সি তে রেফারেন্স দিয়ে পাস করা


204

সি যদি রেফারেন্স দ্বারা কোনও ভেরিয়েবল পাস করার পক্ষে সমর্থন না করে তবে কেন এই কাজ করে?

#include <stdio.h>

void f(int *j) {
  (*j)++;
}

int main() {
  int i = 20;
  int *p = &i;
  f(p);
  printf("i = %d\n", i);

  return 0;
}

আউটপুট:

$ gcc -std=c99 test.c
$ a.exe
i = 21 

22
এই কোডটিতে আপনি কোথায় রেফারেন্সটি পাস করছেন ?
অতুল

15
এটি লক্ষ করা উচিত যে সি এর রেফারেন্স দ্বারা পাস হয় না, এটি কেবল পয়েন্টার ব্যবহার করে অনুকরণ করা যায়।
কিছু প্রোগ্রামার ডুড

6
সঠিক বিবৃতি "সি সমর্থন করে না হয় পরোক্ষভাবে আপনি স্পষ্টভাবে (সঙ্গে একটি রেফারেন্স তৈরি করা প্রয়োজন - রেফারেন্স দ্বারা একটি পরিবর্তনশীল ক্ষণস্থায়ী" &স্পষ্টভাবে এটি ডি-রেফারেন্স (সঙ্গে এবং ফাংশন কল করার আগে) *ফাংশনে)।
ক্রিস ডড

2
কল করার সময় আপনার কোড আউটপুট হুবহু সমান f(&i);হয় এটি রেফারেন্স দ্বারা পাসের বাস্তবায়ন, যা সি সিতে
নিখরচায় নেই

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

উত্তর:


315

কারণ আপনি পদ্ধতির কাছে পয়েন্টারের মানটি পাস করছেন এবং তারপরে ইঙ্গিত প্রাপ্ত পূর্ণসংখ্যাটি পেতে এটিটিকে ডিফারেন্স করছেন।


4
চ (P); -> এর অর্থ কি মান দিয়ে যাওয়া? তারপরে ইঙ্গিত দেওয়া পূর্ণসংখ্যা পেতে এটিটিকে ডিফারেন্স করে। -> আপনি আরও ব্যাখ্যা দিতে পারেন
বাপি

4
@ বাপি, একটি পয়েন্টারকে ডিফারেন্স করার অর্থ "এই পয়েন্টারটি যে রেফারেন্স দিচ্ছে সেটি পেতে" to
রুনি লিলিমেটস

আমরা ফাংশনটি কল করার পদ্ধতির জন্য কী ডাকি যা পয়েন্টারটি পাস করার পরিবর্তে ভেরিয়েবলের ঠিকানা নেয়। উদাহরণ: ফানক 1 (ইনট্রি এবং এ)। এটি কি রেফারেন্স দ্বারা কল নয়? এই ক্ষেত্রে রেফারেন্সটি সত্যই গ্রহণ করা হয়েছে এবং পয়েন্টারের ক্ষেত্রে আমরা এখনও মান দিয়ে যাচ্ছি কারণ আমরা কেবলমাত্র মান দ্বারা পয়েন্টারটি পার করছি।
জন হুইলক

1
পয়েন্টার ব্যবহার করার সময় মূল ঘটনাটি হ'ল পয়েন্টারের অনুলিপিটি ফাংশনে প্রবেশ করা হয়। ফাংশনটি সেই পয়েন্টারটি ব্যবহার করে, মূলটি নয়। এটি এখনও পাস-বাই-মান, তবে এটি কাজ করে।
দানিজেল

1
@ ডানিজেল একটি পয়েন্টারটি পাস করা সম্ভব যা কোনও ফাংশন কলে কোনও কিছুর অনুলিপি নয়। উদাহরণস্বরূপ, ফাংশনটি কল করা func: func(&A);এটি কোনও কিছু অনুলিপি না করেই ফাংশনে একটি পয়েন্টারটি পাঠিয়ে দেবে। এটি পাস-বাই-ভ্যালু, তবে সেই মানটি একটি রেফারেন্স, সুতরাং আপনি 'রেজিস্ট্রেশন-বাই রেফারেন্স' চলক এ। কোনও অনুলিপি প্রয়োজন নেই। এটি পাস-বাই-রেফারেন্স বলা বৈধ।
ইয়ুংগুন

124

এটি পাস-বাই-রেফারেন্স নয়, এটি অন্যের বক্তব্য অনুসারে পাস-বাই-ভ্যালু।

সি ভাষাটি ব্যতিক্রম ব্যতীত মূল্য দিয়ে যায়। প্যারামিটার হিসাবে পয়েন্টার পাস করার অর্থ পাস-বাই-রেফারেন্স নয়।

নিয়মটি নিম্নলিখিত:

একটি ফাংশন প্রকৃত পরামিতি মান পরিবর্তন করতে সক্ষম নয়।


আসুন কোনও ফাংশনের স্কেলার এবং পয়েন্টার পরামিতিগুলির মধ্যে পার্থক্যগুলি দেখার চেষ্টা করি।

স্কেলার ভেরিয়েবল

এই সংক্ষিপ্ত প্রোগ্রামটি স্কেলার ভেরিয়েবল ব্যবহার করে পাস-বাই-মান দেখায়। paramফর্মাল প্যারামিটার এবং variableফাংশন আমন্ত্রণকে প্রকৃত প্যারামিটার বলা হয়। paramফাংশনে নোট বৃদ্ধি বৃদ্ধি পায় না variable

#include <stdio.h>

void function(int param) {
    printf("I've received value %d\n", param);
    param++;
}

int main(void) {
    int variable = 111;

    function(variable);
    printf("variable %d\m", variable);
    return 0;
}

ফলাফল হলো

I've received value 111
variable=111

পাস-রেফারেন্সের বিভ্রম

আমরা কোডের টুকরোটি কিছুটা পরিবর্তন করি। paramএখন পয়েন্টার।

#include <stdio.h>

void function2(int *param) {
    printf("I've received value %d\n", *param);
    (*param)++;
}

int main(void) {
    int variable = 111;

    function2(&variable);
    printf("variable %d\n", variable);
    return 0;
}

ফলাফল হলো

I've received value 111
variable=112

এটি আপনাকে বিশ্বাস করে যে প্যারামিটারটি রেফারেন্স দ্বারা পাস হয়েছিল। এটা ছিল না. এটি মান দ্বারা পাস করা হয়েছিল, পরম মান একটি ঠিকানা। ইন্ট টাইপের মান বাড়ানো হয়েছিল এবং এটি সেই পার্শ্ব প্রতিক্রিয়া যা আমাদের মনে করে যে এটি কোনও পাস-রেফারেন্স ফাংশন কল ছিল।

পয়েন্টার - মান দ্বারা উত্তীর্ণ

কীভাবে আমরা সেই সত্যটি প্রদর্শন / প্রমাণ করতে পারি? ওয়েল, সম্ভবত আমরা স্কেলার ভেরিয়েবলগুলির প্রথম উদাহরণ চেষ্টা করতে পারি, তবে স্কেলারের পরিবর্তে আমরা ঠিকানাগুলি (পয়েন্টার) ব্যবহার করি। দেখা যাক এটি সাহায্য করতে পারে কিনা।

#include <stdio.h>

void function2(int *param) {
    printf("param's address %d\n", param);
    param = NULL;
}

int main(void) {
    int variable = 111;
    int *ptr = &variable;

    function2(ptr);
    printf("ptr's address %d\n", ptr);
    return 0;
}

ফলাফলটি হবে যে দুটি ঠিকানা সমান (সঠিক মান সম্পর্কে চিন্তা করবেন না)।

উদাহরণ ফলাফল:

param's address -1846583468
ptr's address -1846583468

আমার মতে এটি স্পষ্টভাবে প্রমাণ করে যে পয়েন্টারগুলি হ'ল মান দ্বারা পাস। অন্যথায় ফাংশন প্রার্থনার পরে ptrহবে NULL


69

সি-তে, পাস-বাই-রেফারেন্সটি একটি ভেরিয়েবলের ঠিকানা (পয়েন্টার) পাস করে এবং প্রকৃত ভেরিয়েবলটি পড়তে বা লিখতে ফাংশনের মধ্যে সেই ঠিকানাটিকে ডিফারেন্স করে সিমুলেটেড হয়। এটি "সি স্টাইল পাস বাই রেফারেন্স" হিসাবে উল্লেখ করা হবে।

সূত্র: www-cs-students.stanford.edu


50

কারণ উপরের কোডটিতে কোনও পাস-বাই-রেফারেন্স নেই। পয়েন্টার ব্যবহার (যেমন void func(int* p)) পাস-বাই-ঠিকানা। এটি সি ++ এ পাস-বাই-রেফারেন্স (সি তে কাজ করবে না):

void func(int& ref) {ref = 4;}

...
int a;
func(a);
// a is 4 now

1
আমি পাশের ঠিকানার উত্তরটি পছন্দ করি। আরও বোধগম্য করে তোলে।
আফজাল আহমদ জিশান

ঠিকানা এবং রেফারেন্স এই প্রসঙ্গে সমার্থক। তবে আপনি দুটি শব্দকে আলাদা করতে এই পদগুলি ব্যবহার করতে পারেন, এটি কেবল তাদের আসল অর্থের প্রতি সৎ নয়।
ইয়ংগুন

27

আপনার উদাহরণটি কাজ করে কারণ আপনি আপনার ভেরিয়েবলের ঠিকানাটি এমন একটি ফাংশনে পাঠাচ্ছেন যা এর মানটি ডিপ্রেশন অপারেটরের সাথে হেরফের করে

সি রেফারেন্স ডেটা ধরণের সমর্থন করে না , আপনি এখনও উদাহরণস্বরূপ পয়েন্টার মানগুলি স্পষ্টভাবে পাস করে বাই-রেফারেন্স অনুকরণ করতে পারেন।

সি ++ রেফারেন্স ডেটা টাইপটি সি থেকে উত্তরাধিকারসূত্রে প্রাপ্ত পয়েন্টার ধরণের চেয়ে কম শক্তিশালী তবে নিরাপদ হিসাবে বিবেচিত এটি আপনার উদাহরণ হতে পারে, সি ++ রেফারেন্স ব্যবহারের জন্য অভিযোজিত :

void f(int &j) {
  j++;
}

int main() {
  int i = 20;
  f(i);
  printf("i = %d\n", i);

  return 0;
}

3
উইকিপিডিয়া নিবন্ধটি সি ++ সম্পর্কিত, সি সংক্রান্ত নয় + রেফারেন্স সি ++ এর আগে বিদ্যমান ছিল এবং বিদ্যমান সি ++ এর সিনট্যাক্সের উপর নির্ভর করে না।

1
@ রোজার: ভাল কথা ... আমি আমার উত্তর থেকে সি ++ এর স্পষ্ট উল্লেখটি সরিয়েছি।
ড্যানিয়েল ভ্যাসালো

1
এবং এই নতুন নিবন্ধটিতে "একটি রেফারেন্স প্রায়শই পয়েন্টার বলা হয়" যা আপনার উত্তর বলে ঠিক তাই নয়।

12

আপনি মান অনুসারে একটি পয়েন্টার (ঠিকানার অবস্থান) দিয়ে যাচ্ছেন ।

এটি "আপনি যে তথ্যটি আপডেট করতে চান তা দিয়ে এখানে জায়গা রয়েছে" বলার মতো like


6

p একটি পয়েন্টার ভেরিয়েবল। এর মান i এর ঠিকানা। আপনি যখন এফ কল করবেন তখন আপনি পি এর মানটি পাস করবেন যা i এর ঠিকানা।



5

সি তে সমস্ত কিছুই হ'ল পাস-বাই-ভ্যালু। পয়েন্টার-এর ব্যবহার আমাদের বিভ্রম যে আমরা রেফারেন্স দ্বারা ক্ষণস্থায়ী কারণ দেয় মান ভেরিয়েবলের পরিবর্তন। তবে, আপনি যদি পয়েন্টার ভেরিয়েবলের ঠিকানা মুদ্রণ করেন তবে আপনি দেখতে পাবেন যে এটি প্রভাবিত হয় না। একটি কপি এর মান ঠিকানার পাস-ইন ফাংশন হয়। নীচে এটি চিত্রিত একটি স্নিপেট রয়েছে।

void add_number(int *a) {
    *a = *a + 2;
}

int main(int argc, char *argv[]) {
   int a = 2;

   printf("before pass by reference, a == %i\n", a);
   add_number(&a);
   printf("after  pass by reference, a == %i\n", a);

   printf("before pass by reference, a == %p\n", &a);
   add_number(&a);
   printf("after  pass by reference, a == %p\n", &a);

}

before pass by reference, a == 2
after  pass by reference, a == 4
before pass by reference, a == 0x7fff5cf417ec
after  pass by reference, a == 0x7fff5cf417ec

4

কারণ আপনি ভেরিয়েবল পি-তে একটি পয়েন্টার (মেমরি ঠিকানা) দিয়ে যাচ্ছেন ফ। অন্য কথায় আপনি একটি পয়েন্টারটি পাস করছেন যা রেফারেন্স নয়।


4

সংক্ষিপ্ত উত্তর: হ্যাঁ, সি পয়েন্টার ব্যবহার করে রেফারেন্স দ্বারা প্যারামিটার পাসিং বাস্তবায়ন করে।

প্যারামিটার পাসিং বাস্তবায়নের সময়, প্রোগ্রামিং ভাষার ডিজাইনাররা তিনটি পৃথক কৌশল (বা শব্দার্থক মডেল) ব্যবহার করেন: সাবপ্রগ্রামে ডেটা স্থানান্তর করুন, সাবপ্রগ্রাম থেকে ডেটা গ্রহণ করুন বা উভয়ই করুন। এই মডেলগুলি সাধারণত মোড, আউট মোড এবং ইনআউট মোড হিসাবে একইভাবে পরিচিত।

এই তিনটি প্রাথমিক পরামিতি উত্তীর্ণ কৌশলগুলি বাস্তবায়নের জন্য ভাষা ডিজাইনারদের দ্বারা বেশ কয়েকটি মডেল তৈরি করা হয়েছে:

পাস-বাই-মান (মোড শব্দার্থবিজ্ঞানে) পাস-বাই-রেজাল্ট (আউট মোড শব্দার্থবিজ্ঞান) পাস-বাই-ভ্যালু-রেজাল্ট (ইনআউট মোড শব্দার্থবিজ্ঞান) পাস-বাই-রেফারেন্স (ইনআউট মোড শব্দার্থবিজ্ঞান) পাস-বাই-নাম (ইনআউট মোড) শব্দার্থবিদ্যা)

ইন-আউট-মোড প্যারামিটার পাস করার জন্য পাস-বাই-রেফারেন্স দ্বিতীয় কৌশল। মূল রুটিন এবং সাবপ্রোগ্রামের মধ্যে পিছনে পিছনে ডেটা অনুলিপি করার পরিবর্তে রানটাইম সিস্টেম উপপ্রগ্রামের জন্য ডেটাতে সরাসরি অ্যাক্সেসের পথ প্রেরণ করে। এই কৌশলটিতে উপ-প্রোগ্রামটির মূল রুটিনের সাথে কার্যকরভাবে ডেটা ভাগ করে নেওয়ার উপাত্তগুলিতে সরাসরি অ্যাক্সেস থাকে। এই কৌশলটির সাথে প্রধান সুবিধাটি হ'ল সময় এবং স্থানের জন্য এটি একেবারে দক্ষ কারণ কোনও জায়গার সদৃশ করার দরকার নেই এবং ডেটা অনুলিপি করার কোনও ব্যবস্থা নেই।

সি তে প্যারামিটার পাসিং বাস্তবায়ন: সি প্যারামিটার হিসাবে পয়েন্টার ব্যবহার করে পাস বাই বাই মান এবং পাস-বাই-রেফারেন্স (ইনআউট মোড) শব্দার্থক প্রয়োগ করে। পয়েন্টারটি সাবপ্রোগ্রামে প্রেরণ করা হয় এবং কোনও আসল তথ্য একেবারেই অনুলিপি করা হয় না। তবে, যেহেতু একটি পয়েন্টার মূল রুটিনের ডেটাতে অ্যাক্সেসের পথ, তাই সাব-প্রোগ্রাম মূল রুটিনে ডেটা পরিবর্তন করতে পারে। সি ALGOL68 থেকে এই পদ্ধতিটি গ্রহণ করেছে।

সি ++ এ প্যারামিটার পাসিং বাস্তবায়ন: সি ++ পয়েন্টারগুলি ব্যবহার করে পাসও-বাই-রেফারেন্স (ইনআউট মোড) শব্দার্থবিজ্ঞানও প্রয়োগ করে এবং একটি বিশেষ ধরণের পয়েন্টার ব্যবহার করে, যা রেফারেন্স টাইপ বলে। রেফারেন্স টাইপ পয়েন্টারগুলি সাবপ্রগ্রামের অভ্যন্তরে অন্তর্নিহিত হয় তবে তাদের শব্দার্থবিজ্ঞানগুলিও পাস-বাই-রেফারেন্স হয়।

সুতরাং এখানে মূল ধারণাটি হ'ল পাস-বাই-রেফারেন্স উপ-প্রোগ্রামে ডেটা অনুলিপি করার পরিবর্তে ডেটাতে অ্যাক্সেস পাথ প্রয়োগ করে। ডেটা অ্যাক্সেসের পাথগুলি স্পষ্টতই পয়েন্টারগুলি বা স্বতঃ-নিরঙ্কিত পয়েন্টারগুলি (রেফারেন্সের ধরণ) ডেরারফারেন্স করা যায়।

আরও তথ্যের জন্য দয়া করে রবার্ট সেবেস্তার, দশম এড।, অধ্যায় 9 এর কনসেপ্টস অফ প্রোগ্রামিং ল্যাঙ্গুয়েজ বইটি দেখুন refer


3

আপনি রেফারেন্স দ্বারা কোনও int পাস করছেন না, আপনি মান দ্বারা একটি পয়েন্টার-টু-ইন-ইন্ট পাশ করছেন। বিভিন্ন বাক্য গঠন, একই অর্থ।


1
+1 "বিভিন্ন বাক্য গঠন, একই অর্থ।" .. সুতরাং একই জিনিসটির অর্থ সিনট্যাক্সের চেয়ে বেশি গুরুত্বপূর্ণ।

সত্য না. সাথে কল void func(int* ptr){ *ptr=111; int newValue=500; ptr = &newvalue }করে int main(){ int value=0; func(&value); printf("%i\n",value); return 0; }এটি 500 এর পরিবর্তে 111 প্রিন্ট করে you
কনফলে ডোলেক্স

@ কনফ্লে, যদি আপনি সিন্টেক্সিকভাবে রেফারেন্সটি দিয়ে যাচ্ছেন ptr = &newvalueতবে তা অনুমোদিত নয়। পার্থক্য নির্বিশেষে, আমি মনে করি আপনি নির্দেশ করছেন যে "একই অর্থ" হুবহু সঠিক নয় কারণ আপনার সি-তে অতিরিক্ত কার্যকারিতাও রয়েছে ("রেফারেন্স" নিজেই পুনরায় স্বাক্ষর করার ক্ষমতা)।
xan

আমরা কখনই এমন কিছু লিখি না ptr=&newvalueযদি এটি রেফারেন্স দিয়ে পাস করা হয়। পরিবর্তে, আমরা লিখি ptr=newvalueএখানে সি ++ তে একটি উদাহরণ রয়েছে: void func(int& ptr){ ptr=111; int newValue=500; ptr = newValue; }ফানক () এ দেওয়া প্যারামিটারটির মান হয়ে যাবে 500
কনফ্লে ডোলেক্স

উপরের আমার মন্তব্যের ক্ষেত্রে, রেফারেন্স দিয়ে পারম পাস করা অর্থহীন। তবে, যদি প্যারামের পরিবর্তে প্যারাম কোনও বস্তু হয় তবে এটি একটি তাত্পর্যপূর্ণ তাত্পর্য তৈরি করবে কারণ কোনও param = new Class()ফাংশনের অভ্যন্তরের পরে যে কোনও পরিবর্তন হয়েছে তা যদি কলকের দ্বারা মান (পয়েন্টার) দ্বারা পাস করা হয় তবে কলারের পক্ষে কোনও প্রভাব ফেলবে না। যদি paramরেফারেন্স দিয়ে পাস করা হয়, পরিবর্তনগুলি কলারের জন্য দৃশ্যমান হবে।
কনফলে ডোলেক্স

3

সিতে, রেফারেন্স দিয়ে পাস করার জন্য আপনি অ্যাড্রেস-অফ অপারেটরটি ব্যবহার করেন &যা কোনও ভেরিয়েবলের বিপরীতে ব্যবহার করা উচিত, তবে আপনার ক্ষেত্রে, যেহেতু আপনি পয়েন্টার ভেরিয়েবলটি ব্যবহার করেছেন p, আপনাকে এটিকে অ্যাড্রেস-অফ অপারেটরের সাথে প্রিফিক্স করার দরকার নেই। আপনি যদি &iপ্যারামিটার হিসাবে ব্যবহার করেন তবে এটি সত্য হত f(&i)

আপনি এটিকে যুক্তিযুক্ত করতে pএবং এটির মানটি কীভাবে মেলে তা দেখতে পারেন i:

printf("p=%d \n",*p);

কেন তাকে প্রিন্টএফ যুক্ত করা উচিত তা বলার জন্য কেন আপনি সমস্ত কোডের (সেই মন্তব্য ব্লক সহ ..) পুনরাবৃত্তি করার প্রয়োজনীয়তা অনুভব করলেন?

@ নীল: সেই ত্রুটিটি @ উইলিয়ামের সম্পাদনা দ্বারা প্রবর্তিত হয়েছিল, আমি এখন এটিকে বিপরীত করব। এবং এখন এটি স্পষ্ট যে টমিমিব কেবল বেশিরভাগ ক্ষেত্রেই সঠিক: আপনি কেবলমাত্র ভেরিয়েবলগুলি নয়, কোনও বস্তুর জন্য প্রয়োগ করতে পারেন।

2

পয়েন্টার এবং রেফারেন্স দুটি পৃথক থিগঞ্জস।

আমি দু'টি জিনিস উল্লেখ করে দেখিনি।

পয়েন্টার হ'ল কোনও কিছুর ঠিকানা। একটি পয়েন্টার অন্যান্য ভেরিয়েবলের মতো সংরক্ষণ এবং অনুলিপি করা যায়। এটি একটি আকার আছে।

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

রেফারেন্স সহ আপনার পয়েন্টারগুলির সাথে সমস্যা নেই, যেমন মালিকানা পরিচালনা, নাল চেক করা, ব্যবহারে ডি-রেফারেন্সিং।


1

'রেফারেন্স দ্বারা পাস' (পয়েন্টার ব্যবহার করে) প্রথম থেকেই সিতে ছিল। আপনি কেন মনে করেন না?


7
কারণ এটি প্রযুক্তিগতভাবে রেফারেন্স দ্বারা পাস হয় না।
মেহরদাদ আফশারি

7
পয়েন্টারের মানটি পাস করা বাই-রেফারেন্সের সমান নয়। এর মান আপডেট করা হচ্ছে j( না *j ) এ f()কোন প্রভাব রয়েছে imain()
জন বোদে

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

4
@ জিম: আমাদের আপনি জানানোর জন্য ধন্যবাদ যে আপনি জনর মন্তব্যকে সমর্থন করেছিলেন telling

1

আমি মনে করি সি আসলে রেফারেন্স দ্বারা পাস সমর্থন করে।

বেশিরভাগ ভাষায় মানের পরিবর্তে সিনট্যাকটিক চিনি পাস করতে হয়। (উদাহরণস্বরূপ সি ++ এর প্রয়োজন হয় এবং প্যারামিটারের ঘোষণায়)।

সি এর জন্য সিনট্যাকটিক চিনিও প্রয়োজন। এটি * প্যারামিটার ধরণের ঘোষণায় এবং যুক্তিতে argument সুতরাং * এবং & হয় রেফারেন্স দ্বারা পাস জন্য C সিনট্যাক্স।

এখন কেউ যুক্তি দিতে পারে যে রেফারেন্স দ্বারা বাস্তব পাসের জন্য কেবলমাত্র প্যারামিটারের ঘোষণায় বাক্য গঠন হওয়া দরকার, আর্গুমেন্টের পাশে নয়।

কিন্তু এখন C # এর যা আসে না রেফারেন্স পাসিং দ্বারা সমর্থন এবং উপর অন্বিত চিনি প্রয়োজন উভয় প্যারামিটার এবং যুক্তি পক্ষের।

সি এর কোন বাই-রেফ পাস করার যুক্তিটি সিনট্যাকটিক উপাদানগুলি অন্তর্নিহিত প্রযুক্তিগত বাস্তবায়নকে প্রকাশ করার কারণ হিসাবে প্রকাশ করার কারণ হিসাবে এটি মোটেই যুক্তি নয়, কারণ এটি সমস্ত বাস্তবায়নের ক্ষেত্রে কমবেশি প্রয়োগ হয়।

কেবলমাত্র যুক্তিটি হ'ল সি-এ রেফ দিয়ে পাস করা একক বৈশিষ্ট নয় তবে দুটি বিদ্যমান বৈশিষ্ট্যকে একত্রিত করে। (& এর মাধ্যমে যুক্তির প্রত্যাখ্যান করুন, * দ্বারা টাইপ করতে প্রত্যাশা করুন)) সি # উদাহরণস্বরূপ দুটি সিনট্যাকটিক উপাদান প্রয়োজন, তবে সেগুলি একে অপরকে ছাড়া ব্যবহার করা যায় না।

এটি স্পষ্টতই একটি বিপজ্জনক যুক্তি, কারণ ভাষাতে প্রচুর অন্যান্য বৈশিষ্ট্য অন্যান্য বৈশিষ্ট্যগুলির সমন্বয়ে গঠিত। (সি ++ এ স্ট্রিং সমর্থন মত)


1

আপনি যা করছেন তা হল রেফারেন্স দ্বারা পাস না করে মান দ্বারা পাস। কারণ আপনি একটি ভেরিয়েবলের মান 'ফ' ফাংশন 'এফ' তে প্রেরণ করছেন (মূলত f (p);)

রেফারেন্স দিয়ে পাসের সাথে সি তে একই প্রোগ্রামটি দেখতে পাবেন, (!!! এই প্রোগ্রামটি 2 টি ত্রুটি দেয় যেমন পাস দিয়ে রেফারেন্স সমর্থিত নয়)

#include <stdio.h>

void f(int &j) {    //j is reference variable to i same as int &j = i
  j++;
}

int main() {
  int i = 20;
  f(i);
  printf("i = %d\n", i);

  return 0;
}

আউটপুট: -

3:12: ত্রুটি: প্রত্যাশিত ';', ',' বা ')' এর আগে '&' টোকেন
             অকার্যকর চ (অন্তর্ & জে);
                        ^
9: 3: সতর্কতা: ফাংশন 'চ' এর অন্তর্নিহিত ঘোষণা
               চ (ক);
               ^
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.