C এর ক্রিয়ায় অ্যারে এবং অ্যারে পয়েন্টারটি পাস করার মধ্যে পার্থক্য


110

সি এর দুটি ফাংশনের মধ্যে পার্থক্য কী?

void f1(double a[]) {
   //...
}

void f2(double *a) {
   //...
}

যদি আমি লম্বা অ্যারেগুলিতে ফাংশনগুলি কল করতে পারি তবে এই দুটি ফাংশন কি আলাদাভাবে আচরণ করবে, তারা স্ট্যাকের উপর আরও জায়গা নেবে?

উত্তর:


114

প্রথমত, কিছু স্ট্যান্ডার্ডিজ :

7.7..5.৩ ফাংশন ডিক্লেয়ারার (প্রোটোটাইপ সহ)
...
'' ' টাইপের অ্যারে' 'হিসাবে একটি পরামিতি ঘোষণাকে ' 'যোগ্য পয়েন্টার টাইপ করতে' 'র সাথে সামঞ্জস্য করা হবে , যেখানে টাইপ কোয়ালিফায়ার (যদি থাকে) নির্দিষ্ট করা হয় মধ্যে [এবং ]অ্যারের টাইপ শিক্ষাদীক্ষা করুন। যদি কীওয়ার্ডটি অ্যারের ধরণের ডাইরিভিউশন এবং এর staticমধ্যেও উপস্থিত হয় , তবে ফাংশনটির প্রতিটি কলের জন্য, সংশ্লিষ্ট প্রকৃত যুক্তির মান কমপক্ষে যতগুলি উপাদান নির্দিষ্ট করে ঠিক তত পরিমাণে একটি অ্যারের প্রথম উপাদানটিতে অ্যাক্সেস সরবরাহ করতে পারে অভিব্যক্তি। []

সুতরাং, সংক্ষেপে, কোন ফাংশন প্যারামিটার হিসেবে ঘোষণা T a[]বা T a[N]চিকিত্সা করা হয় যেন এটা ঘোষণা করেন T *a

সুতরাং, অ্যারে প্যারামিটারগুলি কেন পয়েন্টার হিসাবে ঘোষিত হয়েছে এমনভাবে তাকে চিকিত্সা করা হবে? কারণটা এখানে:

.3.৩.২.১ ল্যাভেলিউস, অ্যারে এবং ফাংশন ডিজাইনার
...
3 ব্যতীত যখন এটি sizeofঅপারেটর বা ইউনিারি &অপারেটরের অপারেন্ড হয় বা কোনও অ্যারে শুরু করতে স্ট্রিং আক্ষরিক হয়, এমন একটি এক্সপ্রেশন যা '' টাইপের অ্যারে ' টাইপ করে 'টাইপ' 'পয়েন্টার টু টাইপ ' দিয়ে একটি এক্সপ্রেশনতে রূপান্তরিত হয় যা অ্যারে অবজেক্টের প্রাথমিক উপাদানকে নির্দেশ করে এবং লভ্যালু নয়। যদি অ্যারে অবজেক্টটিতে স্টোরেজ ক্লাসটি নিবন্ধিত থাকে তবে আচরণটি সংজ্ঞায়িত।

নিম্নলিখিত কোড দেওয়া:

int main(void)
{
  int arr[10];
  foo(arr);
  ...
}

কলটিতে fooঅ্যারে এক্সপ্রেশনটি arrকোনও sizeofবা একটির অপরেন্দ্র নয় &, সুতরাং এর প্রকারটি স্পষ্টভাবে 6.2.3.1/3 অনুযায়ী "10-উপাদান অ্যারে int" থেকে "পয়েন্টারে int" রূপান্তরিত হয়। সুতরাং, fooঅ্যারের মানের পরিবর্তে একটি পয়েন্টার মান পাবেন।

6.7.5.3/7 কারণে আপনি লিখতে পারেন fooযেমন

void foo(int a[]) // or int a[10]
{
  ...
}

তবে এটি ব্যাখ্যা করা হবে

void foo(int *a)
{
  ...
}

সুতরাং, দুটি রূপ অভিন্ন।

6.7.5.3/7 এ শেষ বাক্যটি C99 এর সাথে প্রবর্তিত হয়েছিল এবং মূলত এর অর্থ হল যে আপনার যদি পরামিতি ঘোষণার মতো থাকে

void foo(int a[static 10])
{
  ...
}

সাথে সম্পর্কিত প্রকৃত প্যারামিটারটি aঅবশ্যই কমপক্ষে 10 টি উপাদান সহ একটি অ্যারে হতে হবে ।


1
এমএসভিসি সি ++ সংকলক (কমপক্ষে কিছু পুরানো) ব্যবহার করার সময় একটি পার্থক্য রয়েছে, সংকলক ভুলভাবে ফাংশনটির নাম দুটি ক্ষেত্রে পৃথকভাবে ম্যাংগল করার কারণে (সেগুলি অন্যথায় একইরূপে স্বীকৃতি দেওয়ার সময়) লিঙ্ক সমস্যা তৈরি করে। দেখুন এখানে "ঠিক হবে না" বাগ রিপোর্ট connect.microsoft.com/VisualStudio/feedback/details/326874/...
greggo

29

পার্থক্যটি নিখুঁত বাক্য গঠনমূলক। সি-তে, যখন অ্যারে চিহ্নিতকরণটি কোনও ফাংশন প্যারামিটারের জন্য ব্যবহৃত হয়, এটি স্বয়ংক্রিয়ভাবে পয়েন্টার ঘোষণায় রূপান্তরিত হয়।


1
@ কৌশিক: যদিও এ ক্ষেত্রে তারা একই রকম, তবে মনে রাখবেন যে তারা সাধারণ ক্ষেত্রে এক নয়
ব্লুরাজা - ড্যানি ফ্লুঘুফুট

@ ব্লুরাজা: হ্যাঁ, এটি সি এর অন্যতম অসুবিধা ফাংশন প্যারামিটারের ঘোষণা স্থানীয় ভেরিয়েবলের ঘোষণার সাথে খুব মিল , তবে কয়েকটি সূক্ষ্ম পার্থক্য রয়েছে (যেমন এই অ্যারে-টু-পয়েন্টার স্বয়ংক্রিয় রূপান্তর) যা অযত্নে প্রোগ্রামারকে কামড়ানোর প্রবণতা।
টমাস পর্নিন

0

না, তাদের মধ্যে কোনও পার্থক্য নেই। পরীক্ষা করতে আমি এই সি কোডটি ডেভ সি ++ (মিংডাব্লু) সংকলকটিতে লিখেছি:

#include <stdio.h>

void function(int* array) {
     int a =5;
}

void main() {  
     int array[]={2,4};
     function(array);
     getch();
}

আমি যখন আইডিএতে বাইনারি ফাইলের উভয় কলিং সংস্করণগুলির .exe এ মূল ফাংশনটি বিচ্ছিন্ন করতে পারি তখন আমি নীচের মতো ঠিক একই সমাবেশ কোড পাই:

push    ebp
mov     ebp, esp
sub     esp, 18h
and     esp, 0FFFFFFF0h
mov     eax, 0
add     eax, 0Fh
add     eax, 0Fh
shr     eax, 4
shl     eax, 4
mov     [ebp+var_C], eax
mov     eax, [ebp+var_C]
call    sub_401730
call    sub_4013D0
mov     [ebp+var_8], 2
mov     [ebp+var_4], 4
lea     eax, [ebp+var_8]
mov     [esp+18h+var_18], eax
call    sub_401290
call    _getch
leave
retn

সুতরাং এই কলটির দুটি সংস্করণের মধ্যে কোনও পার্থক্য নেই, কমপক্ষে সংকলক তাদের সমানভাবে হুমকি দেয়।


18
দুঃখিত, তবে এটি কেবল প্রমাণ করে যে জিসিসি-র কিছু সংস্করণ উভয়ের জন্য x86 এ একই সমাবেশ তৈরি করে। সঠিক উত্তর, ভুল ব্যাখ্যা।
ল্যাম্বডাপওয়ার
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.