সি-তে পয়েন্টারগুলি: কখন এম্পারস্যান্ড এবং নক্ষত্র ব্যবহার করবেন?


298

আমি ঠিক পয়েন্টার দিয়ে শুরু করছি, এবং আমি কিছুটা বিভ্রান্ত হয়েছি। আমি জানি &যে কোনও ভেরিয়েবলের ঠিকানা বলতে বোঝায় এবং *এটি পয়েন্টারটির দ্বারা নির্দেশিত বস্তুর মান পেতে পয়েন্টার ভেরিয়েবলের সামনে ব্যবহার করা যেতে পারে। আপনি যখন অ্যারে, স্ট্রিংগুলির সাথে কাজ করছেন বা যখন আপনি কোনও ভেরিয়েবলের পয়েন্টার কপি সহ ফাংশনগুলি কল করছেন তখন জিনিসগুলি আলাদাভাবে কাজ করে। এই সমস্তটির ভিতরে যুক্তির একটি প্যাটার্ন দেখা মুশকিল।

আমার কখন &এবং ব্যবহার করা উচিত *?


5
আপনি কীভাবে জিনিসকে কখনও কখনও ভিন্নভাবে কাজ করতে দেখেন দয়া করে তা চিত্রিত করুন। অন্যথায়, আমাদের অনুমান করতে হবে এটি কী তা আপনাকে বিভ্রান্ত করছে।
ড্রু ডোরম্যান

1
নীল বাটারওয়ার্থের সাথে একমত সম্ভবত এটি কোনও বই থেকে প্রথম হাত পেতে আরও অনেক তথ্য পাবে এবং কেএন্ডআর ব্যাখ্যাটি বেশ স্পষ্ট।
টম

144
আমি আপনাদের সবার সাথে একমত নই যারা বলে যে এসও তে এই ধরণের প্রশ্ন জিজ্ঞাসা করা ভাল ধারণা নয়। গুগলে অনুসন্ধান করার সময় এসও এক নম্বর সংস্থান হয়ে উঠেছে। আপনি এই উত্তরগুলিতে যথেষ্ট ক্রেডিট দিচ্ছেন না। ড্যান অলসনের প্রতিক্রিয়া পড়ুন। এই উত্তরটি সত্যই অন্তর্দৃষ্টিপূর্ণ এবং newbies জন্য অবিশ্বাস্যরূপে সহায়ক। RTFMঅসহায়, এবং বেশ স্পষ্টভাবে খুব অভদ্র। আপনার যদি উত্তর দেওয়ার সময় না থাকে তবে যারা এই প্রশ্নের উত্তর দিতে সময় নেন তাদের প্রতি শ্রদ্ধা রাখুন। আমি আশা করি আমি এটি "অননকে" করতে পারতাম তবে স্পষ্টতই তার / তার কাছে কোনও অর্থবহ উপায়ে অবদান রাখার সময় নেই।
এসএসএইচ এই

18
কি , SSH এই বলেন একেবারে সত্য। কিছু লোক "জাস্ট গুগল ইট" বলে চিৎকার করে, কিন্তু আজকাল এটি অন্যভাবে: "কেবল স্ট্যাকওভারফ্লোতে দেখুন"। এই প্রশ্নটি অনেক লোকের জন্য দরকারী। (অতএব উন্নতিগুলি এবং কোনও ডাউনভোট নেই))
এমসি সম্রাট

উত্তর:


610

আপনার পয়েন্টার এবং মান আছে:

int* p; // variable p is pointer to integer type
int i; // integer value

আপনি এটির সাথে একটি পয়েন্টারকে একটি মানতে পরিণত করুন *:

int i2 = *p; // integer i2 is assigned with integer value that pointer p is pointing to

আপনি এর সাথে একটি মানকে পয়েন্টারে পরিণত করেন &:

int* p2 = &i; // pointer p2 will point to the address of integer i

সম্পাদনা: অ্যারেগুলির ক্ষেত্রে, তারা পয়েন্টারের মতো খুব বেশি আচরণ করা হয়। আপনি যদি এগুলি পয়েন্টার হিসাবে মনে করেন তবে আপনি *উপরে বর্ণিত অনুসারে সেগুলির মানগুলি পেতে ব্যবহার করবেন, তবে []অপারেটরটি ব্যবহার করার আরও একটি সাধারণ উপায় রয়েছে :

int a[2];  // array of integers
int i = *a; // the value of the first element of a
int i2 = a[0]; // another way to get the first element

দ্বিতীয় উপাদানটি পেতে:

int a[2]; // array
int i = *(a + 1); // the value of the second element
int i2 = a[1]; // the value of the second element

সুতরাং []সূচক অপারেটর অপারেটরের একটি বিশেষ ফর্ম *, এবং এটি এর মতো কাজ করে:

a[i] == *(a + i);  // these two statements are the same thing

2
কিভাবে এই কাজ করে না? int aX[] = {3, 4}; int *bX = &aX;
পিটার

5
অ্যারেগুলি বিশেষ এবং স্বচ্ছভাবে পয়েন্টারে রূপান্তর করা যায়। এটি একটি পয়েন্টার থেকে কোনও মানের দিকে যাওয়ার আরও একটি উপায় হাইলাইট করে, আমি এটি উপরের ব্যাখ্যায় যুক্ত করব।
ড্যান ওলসন

4
যদি আমি এটি সঠিকভাবে বুঝতে পারি ... উদাহরণটি int *bX = &aX;কাজ করে না কারণ aXইতিমধ্যে ইতিমধ্যে aX[0](অর্থাত্ &aX[0]) ঠিকানাটি ফিরে আসে , সুতরাং &aXকোনও ঠিকানার ঠিকানাটি পাওয়া যাবে যা কোনও অর্থহীন নয়। এটা কি সঠিক?
পিটার

6
আপনি সঠিক, যদিও এমন কিছু ক্ষেত্রে রয়েছে যেখানে আপনি আসলে ঠিকানার ঠিকানা চাইতে পারেন। সেক্ষেত্রে আপনি এটিকে ** বিএক্স = এবং এক্স হিসাবে ঘোষণা করবেন তবে এটি আরও উন্নত একটি বিষয় is
ড্যান অলসন

3
@ ড্যান, প্রদত্ত int aX[] = {3,4};, int **bX = &aX;একটি ত্রুটি। &aX"পয়েন্টার টু অ্যারে [2] এর টাইপ int," পয়েন্টার টু পয়েন্টার টু int"নয়। বিশেষত, অ্যারেটির নামটিকে অ্যালারির জন্য প্রথম উপাদানটির পয়েন্টার হিসাবে বিবেচনা করা হয় না &। আপনি এটি করতে পারেন:int (*bX)[2] = &aX;
অলোক সিংহল

28

অ্যারে এবং ফাংশনগুলির সাথে কাজ করার সময় একটি প্যাটার্ন রয়েছে; এটি প্রথমে দেখতে কিছুটা শক্ত।

অ্যারেগুলির সাথে কাজ করার সময়, নিম্নলিখিতগুলি মনে রাখার জন্য এটি দরকারী: যখন একটি অ্যারে এক্সপ্রেশন বেশিরভাগ প্রসঙ্গে উপস্থিত হয়, তখন এক্সপ্রেশনটির প্রকার স্পষ্টভাবে "টি এর এন-এলিমেন্ট অ্যারে" থেকে "পয়েন্টার থেকে টি" তে রূপান্তরিত হয় এবং এর মান সেট করা হয় অ্যারেতে প্রথম উপাদানটি নির্দেশ করতে point এই নিয়মের ব্যতিক্রমগুলি হ'ল যখন অ্যারে এক্সপ্রেশনটি অপারেটরগুলির &বা sizeofঅপারেটরগুলির উপস্থিতি হিসাবে উপস্থিত হয় , বা যখন এটি কোনও স্ট্রিং আক্ষরিক হয় তখন একটি ঘোষণায় প্রারম্ভিক হিসাবে ব্যবহৃত হয়।

সুতরাং, আপনি যখন একটি অ্যারের এক্সপ্রেশন সহ কোনও ফাংশনটিকে আর্গুমেন্ট হিসাবে কল করবেন তখন ফাংশনটি বিন্যাস নয়, অ্যারে নয় একটি পয়েন্টার গ্রহণ করবে:

int arr[10];
...
foo(arr);
...

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

এই কারণেই আপনি "% s" এর সাথে যুক্ত যুক্তিগুলির জন্য অপারেটরটি ব্যবহার করবেন না :&scanf()

char str[STRING_LENGTH];
...
scanf("%s", str);

অন্তর্নিহিত রূপান্তর কারণে, অ্যারের শুরুতে নির্দেশ করে এমন scanf()একটি char *মান গ্রহণ করে str। এটি আর্গুমেন্ট হিসাবে অ্যারে এক্সপ্রেশন সহ যে কোনও ক্রিয়াকলাপের ক্ষেত্রে সত্য (এটি কোনও str*ফাংশন *scanfএবং *printfফাংশন ইত্যাদির সম্পর্কে) সত্য বলে ধরে রাখে ।

অনুশীলনে, আপনি সম্ভবত কখনও কখনও &অপারেটরটি ব্যবহার করে অ্যারে এক্সপ্রেশন সহ কোনও ফাংশন কল করবেন না:

int arr[N];
...
foo(&arr);

void foo(int (*p)[N]) {...}

এই জাতীয় কোড খুব সাধারণ নয়; আপনাকে ফাংশন ঘোষণায় অ্যারেটির আকার জানতে হবে এবং ফাংশনটি নির্দিষ্ট আকারের অ্যারেগুলিতে পয়েন্টার দিয়ে কাজ করে (টি-এর একটি 10-এলিমেন্ট অ্যারের একটি পয়েন্টার 11-এলিমেন্ট অ্যারের পয়েন্টারের চেয়ে আলাদা ধরণের হয় টি এর)।

যখন একটি অ্যারের এক্সপ্রেশন &অপারেটরের কাছে অপরেন্ড হিসাবে উপস্থিত হয় , তখন ফলাফলটির এক্সপ্রেশনটি টাইপ হয় "টি এর এন-এলিমেন্ট অ্যারে থেকে পয়েন্টার", বা T (*)[N], যা পয়েন্টার ( T *[N]) এর অ্যারে থেকে আলাদা এবং বেস টাইপের পয়েন্টার ( T *)।

ফাংশন এবং পয়েন্টারগুলির সাথে কাজ করার সময়, মনে রাখার নিয়মটি হ'ল: আপনি যদি কোনও যুক্তির মান পরিবর্তন করতে চান এবং কলিং কোডটিতে এটি প্রতিবিম্বিত করতে চান তবে আপনাকে যে জিনিসটি সংশোধন করতে চান তার জন্য আপনাকে অবশ্যই একটি পয়েন্টার দিতে হবে। আবার অ্যারেগুলি কিছুটা বানরের রেঞ্চটি কাজে ফেলে দেয় তবে আমরা প্রথমে সাধারণ ক্ষেত্রে মোকাবিলা করব।

মনে রাখবেন যে সি সমস্ত ফাংশন আর্গুমেন্টকে মান দ্বারা পাস করে; আনুষ্ঠানিক প্যারামিটার প্রকৃত প্যারামিটারে মানটির একটি অনুলিপি গ্রহণ করে এবং আনুষ্ঠানিক প্যারামিটারে কোনও পরিবর্তন প্রকৃত প্যারামিটারে প্রতিফলিত হয় না। সাধারণ উদাহরণটি হল অদলবদল কার্য:

void swap(int x, int y) { int tmp = x; x = y; y = tmp; }
...
int a = 1, b = 2;
printf("before swap: a = %d, b = %d\n", a, b);
swap(a, b);
printf("after swap: a = %d, b = %d\n", a, b);

আপনি নিম্নলিখিত আউটপুট পাবেন:

অদলবদলের আগে: a = 1, খ = 2
অদলবদলের পরে: a = 1, খ = 2

আনুষ্ঠানিক প্যারামিটারগুলি xএবং yএর থেকে পৃথক বস্তু aএবং bতাই পরিবর্তিত হয় xএবং এতে yপ্রতিফলিত হয় না aএবং b। যেহেতু আমরা মান পরিবর্তন করতে চান aএবং bআমরা পাস করতে হবে পয়েন্টার swap 'র ফাংশন তাদের:

void swap(int *x, int *y) {int tmp = *x; *x = *y; *y = tmp; }
...
int a = 1, b = 2;
printf("before swap: a = %d, b = %d\n", a, b);
swap(&a, &b);
printf("after swap: a = %d, b = %d\n", a, b);

এখন আপনার আউটপুট হবে

অদলবদলের আগে: a = 1, খ = 2
অদলবদলের পরে: a = 2, খ = 1

উল্লেখ্য, swap 'র ফাংশন, আমরা মান পরিবর্তন করবেন না xএবং y, কিন্তু কি মান xএবং y বিন্দু থেকে । লেখালেখি লেখার *xচেয়ে আলাদা x; আমরা মানটি xনিজের মধ্যে আপডেট করছি না , আমরা সেই অবস্থান থেকে একটি অবস্থান পাই xএবং সেই মানটির আপডেট করি।

এটি সমানভাবে সত্য যদি আমরা কোনও পয়েন্টারের মান পরিবর্তন করতে চাই; যদি আমরা লিখি

int myFopen(FILE *stream) {stream = fopen("myfile.dat", "r"); }
...
FILE *in;
myFopen(in);

তারপরে আমরা ইনপুট প্যারামিটারের মানটি সংশোধন করছি stream, কোনটি stream নির্দেশ করে না তাই পরিবর্তনের streamমানটির উপর কোনও প্রভাব পড়ে না in; এটি কাজ করার জন্য, আমাদের অবশ্যই পয়েন্টারে একটি পয়েন্টারে যেতে হবে:

int myFopen(FILE **stream) {*stream = fopen("myFile.dat", "r"); }
...
FILE *in;
myFopen(&in);

আবার অ্যারেগুলি কিছুটা বানরের রেঞ্চকে কাজগুলিতে ফেলে দেয়। আপনি যখন কোনও ফাংশনে অ্যারে এক্সপ্রেশনটি পাস করেন তখন ফাংশনটি কীটি পায় তা পয়েন্টার। অ্যারে সাবস্ক্রিপশন কীভাবে সংজ্ঞায়িত করা হয়েছে তার কারণে আপনি পয়েন্টারে একইভাবে সাবস্ক্রিপ্ট অপারেটরটি অ্যারেতে ব্যবহার করতে পারেন:

int arr[N];
init(arr, N);
...
void init(int *arr, int N) {size_t i; for (i = 0; i < N; i++) arr[i] = i*i;}

নোট করুন যে অ্যারে অবজেক্টগুলি বরাদ্দ করা যাবে না; অর্থাত্, আপনি এর মতো কিছু করতে পারবেন না

int a[10], b[10];
...
a = b;

সুতরাং আপনি যখন অ্যারেগুলিতে পয়েন্টারগুলি ব্যবহার করছেন তখন সাবধানতা অবলম্বন করতে চান; কিছুটা এইরকম

void (int (*foo)[N])
{
  ...
  *foo = ...;
}

কাজ করবে না


16

সহজভাবে করা

  • &অ্যাড্রেস-এর অর্থ , আপনি দেখতে পাবেন যে সি হিসাবে যেমন প্যারামিটার ভেরিয়েবলটি পরিবর্তন করতে ফাংশনগুলির জন্য স্থানধারকগুলিতে, প্যারামিটার ভেরিয়েবলগুলি রেফারেন্স দিয়ে পাস করার জন্য অ্যাম্পারস্যান্ড অর্থ ব্যবহার করে মান দ্বারা পাস হয়।
  • *পয়েন্টার ভেরিয়েবলের মূল্য বোঝার অর্থ poin পয়েন্টার ভেরিয়েবলের মান পাওয়া যায়।
int foo(int *x){
   *x++;
}

int main(int argc, char **argv){
   int y = 5;
   foo(&y);  // Now y is incremented and in scope here
   printf("value of y = %d\n", y); // output is 6
   /* ... */
}

উপরোক্ত উদাহরণটি ব্যাখ্যা করে যে কীভাবে fooপাস-বাই-রেফারেন্স ব্যবহার করে কোনও ফাংশন কল করা যায়, এর সাথে তুলনা করুন

int foo(int x){
   x++;
}

int main(int argc, char **argv){
   int y = 5;
   foo(y);  // Now y is still 5
   printf("value of y = %d\n", y); // output is 5
   /* ... */
}

এখানে একটি শ্রদ্ধাবোধ ব্যবহার করার উদাহরণ রয়েছে

int main(int argc, char **argv){
   int y = 5;
   int *p = NULL;
   p = &y;
   printf("value of *p = %d\n", *p); // output is 5
}

উপরেরটি চিত্রিত করে যে আমরা কীভাবে ঠিকানাটি পেয়েছি yএবং এটি পয়েন্টার ভেরিয়েবলের জন্য নির্ধারণ করেছি p। তারপর আমরা dereference p যুক্ত করে *এটা সামনে মান প্রাপ্ত করার p, অর্থাত্ *p


10

হ্যাঁ যেটি বেশ জটিল হতে পারে যেহেতু *সি / সি ++ এ বিভিন্ন কারণে ব্যবহৃত হয়।

যদি *ইতিমধ্যে ঘোষিত ভেরিয়েবল / ফাংশনের সামনে উপস্থিত হয় তবে এর অর্থ হয়:

  • ক) *সেই ভেরিয়েবলের মানটিতে অ্যাক্সেস দেয় (যদি সেই ভেরিয়েবলের ধরণটি পয়েন্টার টাইপ হয়, বা *অপারেটরটিকে ওভারলোড করা হয় )।
  • খ) *গুণমান অপারেটরের অর্থ রয়েছে, সেক্ষেত্রে এর বামে আরও একটি পরিবর্তনশীল থাকতে হবে*

যদি *কোনও চলক বা ফাংশন ঘোষণায় উপস্থিত হয় তবে এর অর্থ হ'ল সেই পরিবর্তনশীলটি একটি পয়েন্টার:

int int_value = 1;
int * int_ptr; //can point to another int variable
int   int_array1[10]; //can contain up to 10 int values, basically int_array1 is an pointer as well which points to the first int of the array
//int   int_array2[]; //illegal, without initializer list..
int int_array3[] = {1,2,3,4,5};  // these two
int int_array4[5] = {1,2,3,4,5}; // are identical

void func_takes_int_ptr1(int *int_ptr){} // these two are identical
void func_takes int_ptr2(int int_ptr[]){}// and legal

যদি &কোনও ভেরিয়েবল বা ফাংশন ঘোষণায় উপস্থিত হয় তবে এর সাধারণত অর্থ হল যে ভেরিয়েবলটি সেই ধরণের পরিবর্তকের একটি রেফারেন্স।

যদি &ইতিমধ্যে ঘোষিত ভেরিয়েবলের সামনে উপস্থিত হয় তবে এটি সেই ভেরিয়েবলের ঠিকানা প্রদান করে

অতিরিক্তভাবে আপনার জানা উচিত, যে কোনও ফাংশনে অ্যারে পাস করার সময়, আপনাকে সর্বদা সেই অ্যারের অ্যারের আকারটিও পাস করতে হবে, অ্যারে 0-টার্মিনেটেড সিস্ট্রিং (চর অ্যারে) এর মতো কিছু না করে ব্যতীত।


1
@akmozo s / func_take int_ptr2 / func_take_int_ptr2 / (অবৈধ স্থান)
পিক্সনবিটস

4

আপনি যখন কোনও পয়েন্টার ভেরিয়েবল বা ফাংশন প্যারামিটার ঘোষণা করছেন তখন *:

int *x = NULL;
int *y = malloc(sizeof(int)), *z = NULL;
int* f(int *x) {
    ...
}

এনবি: প্রতিটি ঘোষিত ভেরিয়েবলের নিজস্ব * প্রয়োজন।

আপনি যখন কোনও মানের ঠিকানা নিতে চান, ব্যবহার করুন &। আপনি যখন কোনও পয়েন্টারে মানটি পড়তে বা লিখতে চান, * ব্যবহার করুন।

int a;
int *b;
b = f(&a);
a = *b;

a = *f(&a);

অ্যারেগুলি সাধারণত পয়েন্টারগুলির মতো আচরণ করা হয়। আপনি যখন কোনও ফাংশনে একটি অ্যারে প্যারামিটার ঘোষণা করেন, আপনি ঠিক সহজেই এটিকে একটি পয়েন্টার হিসাবে ঘোষণা করতে পারেন (এর অর্থ একই জিনিস)। যখন আপনি কোনও ফাংশনে অ্যারে পাস করেন, আপনি আসলে প্রথম উপাদানটিতে একটি পয়েন্টারটি পাস করছেন।

ফাংশন পয়েন্টারগুলি হ'ল জিনিস যা নিয়মগুলি পুরোপুরি অনুসরণ করে না। আপনি & ব্যবহার না করে কোনও ফাংশনের ঠিকানা নিতে পারেন এবং আপনি * ব্যবহার না করে কোনও ফাংশন পয়েন্টারটিতে কল করতে পারেন।


4

আমি সমস্ত কথামূলক ব্যাখ্যা দিয়েছিলাম তাই পরিবর্তে উদ্ধার জন্য নিউ সাউথ ওয়েলস বিশ্ববিদ্যালয় থেকে একটি ভিডিওতে পরিণত হয়েছিল e এখানে সহজ ব্যাখ্যা: আমাদের যদি কোনও ঘর থাকে যাতে ঠিকানা xএবং মান থাকে 7তবে মানের ঠিকানা জিজ্ঞাসা করার পরোক্ষ উপায় 7হয় &7প্রত্যক্ষ ও পরোক্ষ ভাবে ঠিকানায় মান জন্য জিজ্ঞাসা করতে xহয় *x.So (cell: x , value: 7) == (cell: &7 , value: *x).Another উপায় এটা দেখব হবে: Johnএ অস্ত 7th seatলোকের *7th seatনির্দেশ করবে Johnএবং &Johnদেব addressএর অবস্থান / 7th seat। এই সাধারণ ব্যাখ্যাটি আমাকে সহায়তা করেছে এবং আশা করি এটি অন্যকেও সহায়তা করবে। চমৎকার ভিডিওটির লিঙ্কটি এখানে : এখানে ক্লিক করুন।

এখানে আরও একটি উদাহরণ:

#include <stdio.h>

int main()
{ 
    int x;            /* A normal integer*/
    int *p;           /* A pointer to an integer ("*p" is an integer, so p
                       must be a pointer to an integer) */

    p = &x;           /* Read it, "assign the address of x to p" */
    scanf( "%d", &x );          /* Put a value in x, we could also use p here */
    printf( "%d\n", *p ); /* Note the use of the * to get the value */
    getchar();
}

অ্যাড-অন: পয়েন্টার ব্যবহারের আগে সর্বদা সূচনা করুন f যদি না হয় তবে পয়েন্টারটি কোনও কিছুর দিকে নির্দেশ করবে, যার ফলে প্রোগ্রামটি ক্র্যাশ হওয়ার কারণ হতে পারে কারণ অপারেটিং সিস্টেম আপনাকে নিজের মেমরির অ্যাক্সেস করা থেকে বিরত রাখবে knows p = &x;, আমরা পয়েন্টারটিকে একটি নির্দিষ্ট অবস্থান নির্ধারণ করছি।


3

প্রকৃতপক্ষে, আপনার এটি বন্ধ আছে, আপনাকে আরও কিছু জানার দরকার নেই :-)

আমি কেবল নিম্নলিখিত বিটগুলি যুক্ত করব:

  • দুটি ক্রিয়াকলাপ বর্ণালীটির বিপরীত প্রান্তে। &একটি পরিবর্তনশীল নেয় এবং আপনাকে ঠিকানা দেয় *, একটি ঠিকানা নেয় এবং আপনাকে পরিবর্তনশীল (বা বিষয়বস্তু) দেয়।
  • আপনি যখন ফাংশনে তাদের পাস করেন তখন পয়েন্টারগুলিতে অ্যারে "অবনমিত" হন।
  • আপনি আসলে (অপ্রত্যক্ষ্যতার একাধিক মাত্রা থাকতে পারে char **pমানে যে pএকটি একটি পয়েন্টার একটি পয়েন্টার char

জিনিসগুলি ভিন্নভাবে কাজ করার ক্ষেত্রে, বাস্তবে নয়:

  • অ্যারে, যেমন ইতিমধ্যে উল্লিখিত হয়েছে, ফাংশনগুলিতে পাস করার সময় পয়েন্টারে (অ্যারের প্রথম উপাদানটিতে) অবনতি হয়; তারা আকারের তথ্য সংরক্ষণ করে না।
  • সি তে কোন স্ট্রিং নেই, কেবল অক্ষর অ্যারে যা কনভেনশন অনুসারে শূন্য ( \0) বর্ণ দ্বারা শেষ হওয়া অক্ষরের একটি স্ট্রিং উপস্থাপন করে ।
  • যখন আপনি কোনও ভেরিয়েবলের ঠিকানাটি কোনও ফাংশনে পাস করেন, আপনি ভেরিয়েবলটি পরিবর্তন করতে পয়েন্টারটিকে ডি-রেফারেন্স করতে পারেন (সাধারণত ভেরিয়েবলগুলি মান দিয়ে যায় (অ্যারেগুলি ব্যতীত))।

3

আমার মনে হয় আপনি কিছুটা বিভ্রান্ত। পয়েন্টারগুলিতে আপনার একটি ভাল টিউটোরিয়াল / বই পড়া উচিত।

এই টিউটোরিয়ালটি শুরু করার জন্য খুব ভাল (পরিষ্কারভাবে কী &এবং কী তা ব্যাখ্যা করে *)। এবং হ্যাঁ কেনেথ রেকের পয়েন্টারস সি বইটি পড়তে ভুলবেন না ।

মধ্যে পার্থক্য &এবং *খুব স্পষ্ট।

উদাহরণ:

#include <stdio.h>

int main(){
  int x, *p;

  p = &x;         /* initialise pointer(take the address of x) */
  *p = 0;         /* set x to zero */
  printf("x is %d\n", x);
  printf("*p is %d\n", *p);

  *p += 1;        /* increment what p points to i.e x */
  printf("x is %d\n", x);

  (*p)++;         /* increment what p points to i.e x */
  printf("x is %d\n", x);

  return 0;
}

1

ঠিক আছে, দেখে মনে হচ্ছে আপনার পোস্টটি সম্পাদিত হয়েছে ...

double foo[4];
double *bar_1 = &foo[0];

&অ্যারে কাঠামোর শুরুর ঠিকানা পেতে আপনি কীভাবে ব্যবহার করতে পারেন তা দেখুন ? অনুসরণ

Foo_1(double *bar, int size){ return bar[size-1]; }
Foo_2(double bar[], int size){ return bar[size-1]; }

একই জিনিস করবে।


প্রশ্নটি সি নয় ++ ট্যাগ করা হয়েছে।
প্রসূন সৌরভ

1
এবং আমি আপত্তিজনক
কাউট
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.