রেফারেন্স দিয়ে পাস করার সাথে বনাম মান দিয়ে যাওয়ার মধ্যে পার্থক্য কী?


562

পার্থক্য কি

  1. একটি পরামিতি রেফারেন্স দ্বারা পাস
  2. একটি পরামিতি মান দ্বারা পাস?

দয়া করে আমাকে কিছু উদাহরণ দিতে পারেন?



1
যদি আপনি কোনও ঠিকানা বা মান কী তা জানেন না তবে এখানে দেখুন
মধু

উত্তর:


1078

প্রথম এবং সর্বাগ্রে, সিএস তত্ত্বে বর্ণিত পার্থক্যটি "রেফারেন্স ভ্যালু রেস। রেফারেন্স দ্বারা পাস" পার্থক্যটি এখন অপ্রচলিত কারণ মূলত "রেফারেন্স দ্বারা পাস" হিসাবে সংজ্ঞায়িত কৌশলটি তখন থেকে অনুকূলে পড়েছে এবং খুব কমই ব্যবহৃত হয়। 1

নতুন ভাষাগুলি 2 একই প্রভাবগুলি অর্জনের জন্য পৃথক (তবে অনুরূপ) কৌশল যুক্ত করতে ব্যবহার করে (নীচে দেখুন) যা বিভ্রান্তির প্রাথমিক উত্স।

বিভ্রান্তির একটি গৌণ উত্স হ'ল "রেফারেন্স দ্বারা পাস" এ, "রেফারেন্স" এর সাধারণ শব্দ "রেফারেন্স" এর চেয়ে সংক্ষিপ্ত অর্থ রয়েছে (কারণ বাক্যাংশটি এর পূর্বাভাস দেয়)।


এখন, খাঁটি সংজ্ঞাটি হ'ল:

  • যখন কোনও পরামিতি রেফারেন্স দিয়ে পাস হয় , কলার এবং কলি প্যারামিটারের জন্য একই ভেরিয়েবল ব্যবহার করে। যদি কলি প্যারামিটার ভেরিয়েবলটি পরিবর্তন করে, তবে প্রভাবটি কলারের পরিবর্তনশীলটির কাছে দৃশ্যমান।

  • যখন কোনও প্যারামিটার মান দ্বারা পাস হয় , কলার এবং কলিটির একই মান সহ দুটি স্বতন্ত্র ভেরিয়েবল থাকে । যদি কলি প্যারামিটার ভেরিয়েবলটি পরিবর্তন করে, তবে প্রভাবটি কলারের কাছে দৃশ্যমান নয়।

এই সংজ্ঞাটিতে নোট করার বিষয়গুলি হ'ল:

  • এখানে "পরিবর্তনশীল" এর অর্থ হ'ল কলারের (স্থানীয় বা গ্লোবাল) ভেরিয়েবলটি নিজেই - অর্থাত যদি আমি একটি স্থানীয় ভেরিয়েবলকে রেফারেন্স দিয়ে পাস করি এবং এটি অর্পণ করি তবে আমি কলারের ভেরিয়েবলটি নিজেই পরিবর্তন করব, উদাহরণস্বরূপ এটি যা পয়েন্টার দিচ্ছে তাতে যা যা ইঙ্গিত করছে তা নয়। ।

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


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

এই জাতীয় রেফারেন্সটি পাস করা হ'ল পাস-বাই-ভ্যালুতে আসে কারণ একটি ভেরিয়েবলের মান প্রযুক্তিগতভাবেই রেফারেন্স হয়, রেফার্ড অবজেক্ট নয়। তবে প্রোগ্রামটিতে নেট এফেক্টটি পাস-বাই-ভ্যালু বা পাস-বাই-রেফারেন্সের মতো হতে পারে:

  • যদি কোনও রেফারেন্স কেবলমাত্র একজন কলারের পরিবর্তনশীল থেকে নেওয়া হয় এবং আর্গুমেন্ট হিসাবে পাস করা হয় তবে পাস-বাই-রেফারেন্সের মতোই এটির প্রভাব রয়েছে: যদি রেফারেন্স করা অবজেক্টটি রূপান্তরিত হয় কলিতে হয় তবে কলার পরিবর্তনটি দেখতে পাবেন।
    • যাইহোক, যদি একটি পরিবর্তনশীল এই রেফারেন্স ধারণ করা হয় reassiged, এটা যে বস্তু প্রতি নির্দেশ, বন্ধ তাই এই পরিবর্তনশীল উপর কোনও অপারেশন পরিবর্তে প্রভাবিত করবে যাই হোক না কেন এটি এখন প্রতি নির্দেশ করা হয় হবে।
  • পাস-বাই-ভ্যালুর মতো একই প্রভাব ফেলতে অবজেক্টের অনুলিপিটি কোনও এক সময় তৈরি করা হয়। বিকল্পগুলির মধ্যে রয়েছে:
    • কলকারী কল করার আগে কেবল একটি ব্যক্তিগত অনুলিপি তৈরি করতে পারবেন এবং কলিকে তার পরিবর্তে একটি রেফারেন্স দিতে পারেন।
    • কিছু ভাষায় কিছু অবজেক্টের ধরণগুলি "অপরিবর্তনীয়": এগুলির উপর যে কোনও ক্রিয়াকলাপ যা মানকে পরিবর্তন করে বলে মনে হয় তা আসলে আসলটিকে প্রভাবিত না করে একটি সম্পূর্ণ নতুন অবজেক্ট তৈরি করে। সুতরাং, এই জাতীয় ধরণের কোনও বস্তুকে আর্গুমেন্ট হিসাবে পাস করার ক্ষেত্রে সর্বদা পাস-বাই-ভ্যালুর প্রভাব থাকে: কলির জন্য একটি অনুলিপি স্বয়ংক্রিয়ভাবে তৈরি করা হবে যদি এবং যখন এটির পরিবর্তনের প্রয়োজন হয় এবং কলারের বস্তু কখনই প্রভাবিত হয় না।
      • ক্রিয়ামূলক ভাষায়, সমস্ত বস্তু অপরিবর্তনীয়।

আপনি দেখতে পারেন, এই যুগলের কৌশলগুলি সংজ্ঞা অনুসারে প্রায় একই রকম, কেবলমাত্র একটি মাত্র নির্দেশনার স্তর সহ: কেবল "রেফারেন্সযুক্ত বস্তু" দিয়ে "পরিবর্তনশীল" প্রতিস্থাপন করে।

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


দ্রষ্টব্য : দীর্ঘদিন ধরে, এই উত্তরটি বলত:

বলুন আমি আপনার সাথে একটি ওয়েব পৃষ্ঠা ভাগ করতে চাই। যদি আমি আপনাকে ইউআরএল বলি, আমি রেফারেন্স দিয়ে যাচ্ছি। আমি দেখতে পাচ্ছি একই ওয়েব পৃষ্ঠা দেখতে আপনি সেই URL টি ব্যবহার করতে পারেন। যদি পৃষ্ঠাটি পরিবর্তন করা হয়, তবে আমরা উভয়ই পরিবর্তনগুলি দেখতে পাই। আপনি যদি ইউআরএল মুছে ফেলেন তবে আপনি যা করছেন তা সেই পৃষ্ঠায় আপনার উল্লেখটি নষ্ট করছে - আপনি আসল পৃষ্ঠাটি নিজেই মুছছেন না।

আমি যদি পৃষ্ঠাটি মুদ্রণ করে প্রিন্ট আউট করি তবে আমি মান দিয়ে যাচ্ছি। আপনার পৃষ্ঠাটি মূলটির সংযোগ বিচ্ছিন্ন অনুলিপি। পরবর্তী কোনও পরিবর্তন আপনি দেখতে পাবেন না এবং আপনি যে কোনও পরিবর্তন (যেমন আপনার মুদ্রণে স্ক্রাবলিং) মূল পৃষ্ঠায় প্রদর্শিত হবে না। আপনি যদি মুদ্রণটি নষ্ট করে দেন তবে আপনি আসলে তার সামগ্রীর অনুলিপিটি নষ্ট করেছেন - তবে মূল ওয়েব পৃষ্ঠাটি অক্ষত রয়েছে।

এটি "রেফারেন্স" এর সংকীর্ণ অর্থ ব্যতীত বেশিরভাগ ক্ষেত্রেই সঠিক - এটি উভয়ই অস্থায়ী এবং অন্তর্নিহিত (এটি করার দরকার নেই, তবে সুস্পষ্ট এবং / অথবা অবিচল থাকা অতিরিক্ত বৈশিষ্ট্যগুলি রয়েছে, পাস-বাই-রেফারেন্সের অংশ নয় , উপরে বর্ণিত হিসাবে)। আরও ঘনিষ্ঠ সাদৃশ্যটি আপনাকে মূল নকলটির জন্য একটি দস্তাবেজের অনুলিপি সরবরাহ করবে be


1 আপনি ফোর্টরান বা ভিজ্যুয়াল বেসিকটিতে প্রোগ্রামিং না করলে এটি ডিফল্ট আচরণ নয় এবং আধুনিক ব্যবহারের বেশিরভাগ ভাষায় সত্য কল-বাই-রেফারেন্সও সম্ভব নয়।

2 যথেষ্ট পরিমাণ বয়স্ক ব্যক্তিরাও এটিকে সমর্থন করে

3 বেশ কয়েকটি আধুনিক ভাষায়, সমস্ত ধরণের রেফারেন্স প্রকার। এই দৃষ্টিভঙ্গিটি সিএলইউ ভাষা দ্বারা 1975 সালে প্রবর্তিত হয়েছিল এবং এর পরে পাইথন এবং রুবি সহ আরও অনেক ভাষা গ্রহণ করেছে। এবং আরও অনেকগুলি ভাষা একটি হাইব্রিড পদ্ধতির ব্যবহার করে, যেখানে কিছু প্রকারগুলি "মান ধরণের" এবং অন্যগুলি "রেফারেন্স টাইপ" হয় - তাদের মধ্যে সি #, জাভা এবং জাভাস্ক্রিপ্ট রয়েছে।

4 প্রতি সেটের জন্য উপযুক্ত পুরানো টার্মটি পুনর্ব্যবহার করার ক্ষেত্রে খারাপ কিছু নেই, তবে একসময় এটি পরিষ্কার করে দেওয়া উচিত যে প্রতিবার কোন অর্থটি ব্যবহৃত হচ্ছে। এটি না করা ঠিক ঠিক যা বিভ্রান্তির সৃষ্টি করে।


আমি ব্যক্তিগতভাবে নতুন কৌশলগুলির জন্য "নতুন" বা "অপ্রত্যক্ষ" পাস-বাই-ভ্যালু / পাস-বাই-রেফারেন্স ব্যবহার করব।
ivan_pozdeev

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

@ ইয়ংগুন ১) দয়া করে "প্রায় প্রতিটি সূচক প্রোগ্রামিং কোর্সে প্রদত্ত সংজ্ঞা" এর একটি লিঙ্ক সরবরাহ করুন। আরও লক্ষ করুন যে এর লক্ষ্য আজকের বাস্তবতাগুলিতে স্পষ্ট হওয়া উচিত, এক দশক বা তিন দশকের আগে যখন কোনও সিএস কোর্স লেখা হয়েছিল তখন নয় real 2) সংজ্ঞা হিসাবে "ঠিকানা" ব্যবহার করা যায় না কারণ এটি ইচ্ছাকৃতভাবে সম্ভব বাস্তবায়ন থেকে বিরত থাকে। যেমন কিছু ভাষার (ফোর্টরান) পয়েন্টার নেই; তারা ব্যবহারকারীদের কাছে কাঁচা ঠিকানা প্রকাশ করে কিনা (ভিবি না করে) তার মধ্যেও পার্থক্য রয়েছে; এটি একটি কাঁচা মেমরি ঠিকানা হতে হবে না, ভেরিয়েবলের সাথে লিঙ্ক করার অনুমতি দেয় এমন কিছু করতে পারে।
ivan_pozdeev

@ivan_podeev কোন লিঙ্ক দুঃখিত। আমি "প্রায় প্রতিটি সূচনা কোর্স" বলি কারণ ব্যক্তিগতভাবে, আমি কলেজে গিয়েছিলাম এবং প্রোগ্রামিং বুটক্যাম্পও নিয়েছিলাম যা আমাকে তা শিখিয়েছিল। এই কোর্সগুলি আধুনিক ছিল (5 বছরেরও কম আগে)। একটি "কাঁচা ঠিকানা" একটি "পয়েন্টার" এর প্রতিশব্দ ... আপনি প্রযুক্তিগতভাবে সঠিক হতে পারেন (কিছু চেরি বাছাই করা লিঙ্ক অনুসারে) তবে আপনি যে ভাষাটি ব্যবহার করছেন সেটি বেশিরভাগ প্রোগ্রামারদের জন্য ব্যবহারিক এবং বিভ্রান্তিকর। : আপনি এটিতে আমার পূর্ণ চিন্তা চান আমি 3500 শব্দ ব্লগ পোস্টে লিখেছি medium.com/@isaaccway228/...
YungGun

@ ইয়ংগুন "অনেক দীর্ঘ, পড়েনি"। এক নজরে উত্তরে বর্ণিত ঠিক বিভ্রান্তি দেখায়। রেফারেন্স দ্বারা পাস বাস্তবায়নের একটি বিমূর্ত কৌশল। হুডের নীচে ঠিক কী পাস হবে তা বিবেচ্য নয়, প্রোগ্রামটির প্রভাব কী তা তা বিবেচনা করে।
ivan_pozdeev

150

ফাংশনগুলিতে আর্গুমেন্টগুলি কীভাবে પસાર করা যায় এটি একটি উপায়। রেফারেন্স দিয়ে পাস করার অর্থ হ'ল ডাকা ফাংশনগুলির পরামিতি কলকারীদের পাস হওয়া যুক্তির মতো হবে (মান নয়, তবে পরিচয়টি - নিজেই ভেরিয়েবল)। মান দ্বারা পাস মানে কলযুক্ত ফাংশনগুলির পরামিতি কলকারীদের পাস হওয়া যুক্তির অনুলিপি হবে। মানটি একই হবে, তবে পরিচয় - পরিবর্তনশীল - আলাদা। সুতরাং একটি ক্ষেত্রে ডাকা ফাংশন দ্বারা সম্পন্ন একটি প্যারামিটারে পরিবর্তিত হয়ে যাওয়া আর্গুমেন্টকে পরিবর্তিত করে এবং অন্য ক্ষেত্রে ডাকা ফাংশনটিতে প্যারামিটারের মান পরিবর্তন করে (যা কেবল একটি অনুলিপি)। দ্রুত তাড়াহুড়োয়:

  • জাভা কেবল মান দ্বারা পাস সমর্থন করে। সর্বদা আর্গুমেন্ট অনুলিপি করে, যদিও কোনও বস্তুর রেফারেন্স অনুলিপি করার সময়, তথাকথিত ফাংশনটির প্যারামিটার একই অবজেক্টের দিকে নির্দেশ করবে এবং সেই বস্তুর পরিবর্তন কলারের মধ্যে দেখা যাবে। যেহেতু এটি বিভ্রান্তিকর হতে পারে, তাই এখানে জোন স্কিটির কী বলা উচিত।
  • সি # মান দ্বারা পাস এবং রেফারেন্স দ্বারা পাস সমর্থন করে (কীওয়ার্ড refকলার এবং ব্যবহৃত ফাংশন হিসাবে ব্যবহৃত হয়)। জন স্কিট এই একটি চমৎকার ব্যাখ্যা রয়েছে এখানে
  • সি ++ মান দ্বারা পাস এবং রেফারেন্স দ্বারা পাস সমর্থন করে (রেফারেন্স প্যারামিটার ধরণের নাম যা ব্যবহৃত হয়)। আপনি নীচে এটির একটি ব্যাখ্যা পাবেন।

কোড

যেহেতু আমার ভাষা সি ++, আমি এটি এখানে ব্যবহার করব

// passes a pointer (called reference in java) to an integer
void call_by_value(int *p) { // :1
    p = NULL;
}

// passes an integer
void call_by_value(int p) { // :2
    p = 42;
}

// passes an integer by reference
void call_by_reference(int & p) { // :3
    p = 42;
}

// this is the java style of passing references. NULL is called "null" there.
void call_by_value_special(int *p) { // :4
    *p = 10; // changes what p points to ("what p references" in java)
    // only changes the value of the parameter, but *not* of 
    // the argument passed by the caller. thus it's pass-by-value:
    p = NULL;
}

int main() {
    int value = 10;
    int * pointer = &value;

    call_by_value(pointer); // :1
    assert(pointer == &value); // pointer was copied

    call_by_value(value); // :2
    assert(value == 10); // value was copied

    call_by_reference(value); // :3
    assert(value == 42); // value was passed by reference

    call_by_value_special(pointer); // :4
    // pointer was copied but what pointer references was changed.
    assert(value == 10 && pointer == &value);
}

এবং জাভাতে একটি উদাহরণ ক্ষতিগ্রস্থ করবে না:

class Example {
    int value = 0;

    // similar to :4 case in the c++ example
    static void accept_reference(Example e) { // :1
        e.value++; // will change the referenced object
        e = null; // will only change the parameter
    }

    // similar to the :2 case in the c++ example
    static void accept_primitive(int v) { // :2
        v++; // will only change the parameter
    }        

    public static void main(String... args) {
        int value = 0;
        Example ref = new Example(); // reference

        // note what we pass is the reference, not the object. we can't 
        // pass objects. The reference is copied (pass-by-value).
        accept_reference(ref); // :1
        assert ref != null && ref.value == 1;

        // the primitive int variable is copied
        accept_primitive(value); // :2
        assert value == 0;
    }
}

উইকিপিডিয়া

http://en.wikipedia.org/wiki/Pass_by_reference#Call_by_value

http://en.wikipedia.org/wiki/Pass_by_reference#Call_by_reference

এই ছেলে এটি বেশ নখ:

http://javadude.com/articles/passbyvalue.htm


9
ডাউনটা কেন? যদি কিছু ভুল হয় বা ভুল বোঝাবুঝির দিকে নিয়ে যায় তবে দয়া করে একটি মন্তব্য করুন।
জোহানেস স্কাউব -

1
আমার ভোট ছিল না, তবে একটি সামান্য বিন্দুতে (আপনি জানেন, রাষ্ট্রপতির বিতর্কের ক্ষেত্রে যে ধরনের পদক্ষেপ নেওয়া হয়েছিল) আমি বলব এটি "কৌশল" এর চেয়ে "কৌশল" বেশি।
হারপো

28
সম্পূর্ণতার জন্য +1। ডাউনভোটগুলি সম্পর্কে চিন্তা করবেন না - লোকেরা অদ্ভুত কারণে এটি করে। ক্যালকুলেটর সম্পর্কে একটি মতামত প্রশ্নে প্রত্যেকে এমন একটি লোক দ্বারা বঞ্চিত হয়েছিল যিনি ভাবেননি যে প্রোগ্রামারদের ক্যালকুলেটর ব্যবহার করা উচিত! যাইহোক, আমি ভেবেছিলাম আপনার উত্তরটি খুব ভাল।
মার্ক ব্রিটিংহাম

1
স্কিটির ব্যাখ্যার লিঙ্কগুলি নষ্ট হয়ে গেছে।
মানি ওরিয়েন্টেড প্রোগ্রামার

স্কিটির ব্যাখ্যার লিঙ্কগুলি এখনও ভাঙা।
রোকিত

85

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

টি এল; ডিআর

সহজ কথায়:

  • মান দ্বারা কল মানে আপনি ফাংশন আর্গুমেন্ট হিসাবে মান পাস
  • রেফারেন্স দ্বারা কল মানে আপনি ফাংশন আর্গুমেন্ট হিসাবে ভেরিয়েবল পাস

রূপক পদে:

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

"মান দ্বারা কল" এবং "রেফারেন্স দ্বারা কল" এর অর্থ এই নয়

নোট করুন যে এই দুটি ধারণাই রেফারেন্স প্রকারের ধারণা (যা জাভাতে সমস্ত ধরণের যা সাব টাইপযুক্ত Object, এবং সি # তে সমস্ত classধরণের), বা সি এর মতো পয়েন্টার ধরণের ধারণা (যা শব্দার্থগতভাবে সমতুল্য ) থেকে সম্পূর্ণ স্বতন্ত্র এবং অরথোগোনাল জাভাটির "রেফারেন্সের ধরণগুলিতে", কেবলমাত্র বিভিন্ন সিনট্যাক্স সহ)

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

নোট সি ++ "রেফারেন্স" (যেমন একটি ধারণা আছে যে int&) যে না মত জাভা এবং C # এর "রেফারেন্স ধরনের", কিন্তু হয় "রেফারেন্স দ্বারা কল" মত। জাভা এবং সি # এর "রেফারেন্সের ধরণগুলি", এবং পাইথনের সমস্ত প্রকারগুলি সি এবং সি ++ "পয়েন্টার ধরণের" (যেমন int*) নামে কল করে।


ঠিক আছে, এখানে দীর্ঘ এবং আরও আনুষ্ঠানিক ব্যাখ্যা।

পরিভাষা

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

শুরু করার জন্য, এখানে কোনও ফাংশন ঘোষণার কয়েকটি সি-জাতীয় ভাষায় একটি উদাহরণ রয়েছে:

void foo(int param) {  // line 1
  param += 1;
}

এবং এখানে এই ফাংশন কল করার একটি উদাহরণ:

void bar() {
  int arg = 1;  // line 2
  foo(arg);     // line 3
}

এই উদাহরণটি ব্যবহার করে, আমি পরিভাষার কয়েকটি গুরুত্বপূর্ণ বিট সংজ্ঞায়িত করতে চাই:

  • fooলাইন 1 এ ঘোষিত একটি ফাংশন (জাভা সমস্ত ফাংশন পদ্ধতি তৈরির জন্য জোর দিয়েছিল, তবে সাধারণতা হারানো ছাড়া ধারণাটি একই রকম; সি এবং সি ++ ঘোষণা এবং সংজ্ঞার মধ্যে একটি পার্থক্য তৈরি করে যা আমি এখানে যাব না)
  • paramএকটি হয় ফর্ম্যাল প্যারামিটার থেকে foo, এছাড়াও লাইন 1 ঘোষণা
  • argএকটি ভেরিয়েবল , বিশেষত ফাংশনের স্থানীয় ভেরিয়েবলbar , ঘোষণা করা হয় এবং লাইন 2 এ আরম্ভ হয়
  • argএছাড়াও একটি হল যুক্তি একটি নির্দিষ্ট করার জন্য আবাহন এর fooলাইন 3

এখানে পৃথক করার জন্য দুটি অত্যন্ত গুরুত্বপূর্ণ ধারণার সেট রয়েছে। প্রথমটি মান বনাম ভেরিয়েবল :

  • একটি মান হয় একটি অভিব্যক্তি মূল্যায়নের ফলাফলের ভাষায়। উদাহরণস্বরূপ, মধ্যে barউপরের ফাংশন, লাইন পর int arg = 1;প্রকাশের argহয়েছে মান 1
  • একটি পরিবর্তনশীল মানগুলির জন্য একটি ধারক । একটি পরিবর্তনশীল পরিবর্তনীয় হতে পারে (এটি বেশিরভাগ সি-জাতীয় ভাষায় ডিফল্ট), কেবল পঠনযোগ্য (যেমন জাভা finalবা সি # এর ব্যবহার হিসাবে ঘোষিত readonly) বা গভীরভাবে অপরিবর্তনীয় (যেমন সি ++ এর ব্যবহার const)।

পার্থক্য যুক্ত করার জন্য ধারণাগুলির অপর গুরুত্বপূর্ণ যুগলটি প্যারামিটার বনাম আর্গুমেন্ট :

  • একটি প্যারামিটার (একে ফরমাল প্যারামিটারও বলা হয়) একটি ভেরিয়েবল যা কোনও ফাংশন কল করার সময় কলার সরবরাহ করতে হবে।
  • একটি আর্গুমেন্ট এমন একটি মান যা ফাংশনটির কলার দ্বারা সেই ফাংশনের একটি নির্দিষ্ট আনুষ্ঠানিক প্যারামিটারটি পূরণ করার জন্য সরবরাহ করা হয়

মান দ্বারা কল করুন

ইন মান কল , ফাংশন এর আনুষ্ঠানিক পরামিতি ভেরিয়েবল সদ্য ফাংশন আবাহন জন্য তৈরি করা হয়, এবং যা দিয়ে সক্রিয়া করা হয় মান তাদের আর্গুমেন্ট।

এটি ঠিক একইভাবে কাজ করে যে কোনও অন্যান্য ধরণের ভেরিয়েবল মান সহ আরম্ভ হয়। উদাহরণ স্বরূপ:

int arg = 1;
int another_variable = arg;

এখানে argএবং another_variableসম্পূর্ণ স্বাধীন ভেরিয়েবল - তাদের মান একে অপরের থেকে স্বতন্ত্রভাবে পরিবর্তিত হতে পারে। যাইহোক, যেখানে এ another_variableঘোষিত হয়, এটি একই মান ধরে রাখার সক্রিয়া করা হয় argযা - ঝুলিতে 1

যেহেতু এগুলি স্বতন্ত্র পরিবর্তনশীল, তাই পরিবর্তনগুলি another_variableপ্রভাবিত করে না arg:

int arg = 1;
int another_variable = arg;
another_variable = 2;

assert arg == 1; // true
assert another_variable == 2; // true

এটি আমাদের উপরের উদাহরণের মধ্যে argএবং সম্পর্কের ঠিক একই রকম param, যা আমি এখানে প্রতিসাম্যের জন্য পুনরাবৃত্তি করব:

void foo(int param) {
  param += 1;
}

void bar() {
  int arg = 1;
  foo(arg);
}

এটি ঠিক যেন আমরা কোডটি এইভাবে লিখেছি:

// entering function "bar" here
int arg = 1;
// entering function "foo" here
int param = arg;
param += 1;
// exiting function "foo" here
// exiting function "bar" here

এটি হ'ল, মান দ্বারা কলটি যার সংজ্ঞাযুক্ত বৈশিষ্ট্যটি হ'ল কলি ( fooএই ক্ষেত্রে) আর্গুমেন্ট হিসাবে মানগুলি গ্রহণ করে তবে তার নিজস্ব পৃথক পৃথক রয়েছে ভেরিয়েবল (আহ্বায়ক ভেরিয়েবল থেকে যারা মানের জন্য barএই ক্ষেত্রে)।

উপরের আমার রূপকের কাছে ফিরে যাচ্ছি, আমি barএবং আপনি যদি আমি থাকি foo, যখন আমি আপনাকে কল করি, তখন আমি আপনাকে একটি কাগজের টুকরো দিয়েছিলাম যার উপরে একটি মূল্য লেখা আছে। আপনি কাগজের টুকরো কল param। সেই মানটি একটি অনুলিপি আমি আমার নোটবুকে (আমার স্থানীয় ভেরিয়েবলগুলি) আমি যে ভেরিয়েবলটিতে লিখেছিarg

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

রেফারেন্স দিয়ে কল করুন

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

উপরে আমাদের উদাহরণে ফিরে যাওয়া, এটি এর সমতুল্য:

// entering function "bar" here
int arg = 1;
// entering function "foo" here
// aha! I note that "param" is just another name for "arg"
arg /* param */ += 1;
// exiting function "foo" here
// exiting function "bar" here

যেহেতু paramকেবল অন্য নাম arg- এটি হ'ল তারা একই ভেরিয়েবল , পরিবর্তনগুলি paramপ্রতিফলিত হয় arg। এটি মৌলিক উপায় যেখানে রেফারেন্স দ্বারা কল মান অনুসারে কল থেকে পৃথক হয়।

খুব অল্প ভাষাই রেফারেন্স অনুসারে কল সমর্থন করে তবে সি ++ এটি এর মতো করতে পারে:

void foo(int& param) {
  param += 1;
}

void bar() {
  int arg = 1;
  foo(arg);
}

এই ক্ষেত্রে, paramঠিক একই নেই মান যেমন arg, এটি একটি প্রকৃত হয় arg (ঠিক একটি ভিন্ন নাম দ্বারা) এবং তাই barপালন করতে পারে argবৃদ্ধি করা হয়েছে।

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

সংযোজন: বস্তু ভাগ করে কল করুন

যদি আপনার কাছে যা থাকে তা মান অনুসারে কল হয় তবে প্রকৃত মানটি একটি রেফারেন্স টাইপ বা পয়েন্টার টাইপ হয় তবে "মান" নিজেই খুব আকর্ষণীয় হয় না (যেমন সি তে এটি প্ল্যাটফর্ম-নির্দিষ্ট আকারের কেবল একটি পূর্ণসংখ্যা) - কী আকর্ষণীয় হয় যে মান নির্দেশ করে

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

আবার ইউআরএলটির উপমাটি ধার করার জন্য, আমি আপনাকে যে ওয়েবসাইটটি ইউআরএলটির একটি অনুলিপি দিয়েছি তা হ'ল আকর্ষণীয় নয় যদি আমরা দুজনের বিষয়ই ওয়েবসাইটের হয় তবে URL নয়। আপনি যে URL টির অনুলিপিটি নিয়ে স্ক্রাবলিং করছেন তা আমার URL টির অনুলিপিটিকে প্রভাবিত করে না (এবং বাস্তবে জাভা এবং পাইথনের মতো ভাষায় "URL", বা রেফারেন্স টাইপের মান, এটি করতে পারে) মোটেও সংশোধন করা হবে না, কেবল এটিই কেবল নির্দেশিত জিনিসটি পারে)।

বারবারা লিসকভ যখন তিনি সিএলইউ প্রোগ্রামিং ল্যাঙ্গুয়েজ আবিষ্কার করেছিলেন (যার মধ্যে এই শব্দার্থবিজ্ঞান ছিল) তখন বুঝতে পেরেছিলেন যে বিদ্যমান শব্দগুলি "মূল্য দ্বারা কল" এবং "রেফারেন্স দ্বারা কল" এই নতুন ভাষার শব্দার্থতত্ত্ব বর্ণনার জন্য বিশেষভাবে কার্যকর ছিল না। সুতরাং তিনি একটি নতুন শব্দ উদ্ভাবন করেছেন: বস্তু ভাগ করে নেওয়ার মাধ্যমে কল করুন

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


উন্নততর ব্যাখ্যা: এখানে পৃথক করার জন্য দুটি অত্যন্ত গুরুত্বপূর্ণ ধারণার সেট রয়েছে। The first is value versus variable. The other important pair of concepts to distinguish is parameter versus argument:
এস কে ভেঙ্কট

2
দুর্দান্ত উত্তর। আমি মনে করি যে আমি যুক্ত করব যে রেফারেন্স অনুসারে কোনও নতুন স্টোরেজ তৈরি করার দরকার নেই। প্যারামিটারের নামটি মূল স্টোরেজ (মেমরি) উল্লেখ করে। ধন্যবাদ
শ্রুতলি

1
সেরা উত্তর আইএমও
রাফায়েল আইং

59

২ টি শর্ত বোঝার আগে আপনাকে নিম্নলিখিতগুলি বুঝতে হবে । প্রতিটি বস্তুর 2 টি জিনিস রয়েছে যা এটি আলাদা করতে পারে।

  • এর মান।
  • এর ঠিকানা।

সুতরাং যদি আপনি বলেন employee.name = "John"

জেনে রাখুন যে সম্পর্কে 2 জিনিস আছে name। এটির মানটি যা "John"মেমরির মধ্যে এটির অবস্থান যা কিছু হেক্সাডেসিমাল সংখ্যা এটির মতো হতে পারে:0x7fd5d258dd00

ভাষার স্থাপত্য বা আপনার অবজেক্টের ধরণের (শ্রেণি, কাঠামো ইত্যাদি) উপর নির্ভর করে আপনি হয় স্থানান্তরিত হবেন "John"বা0x7fd5d258dd00

পাসিং "John"মান দ্বারা পাস হিসাবে পরিচিত। পাসিং 0x7fd5d258dd00রেফারেন্স দ্বারা পাস হিসাবে পরিচিত। যে কেউ এই মেমোরি অবস্থানটির দিকে ইশারা করছে তার মানটির অ্যাক্সেস থাকবে"John"

এ সম্পর্কে আরও তথ্যের জন্য, আমি আপনাকে পয়েন্টারকে ডিফারেন্সিং সম্পর্কে পড়ার পরামর্শ দিই এবং কেন ক্লাসের চেয়ে স্ট্রাক্ট (মানের ধরণ) বেছে নিন (রেফারেন্স টাইপ)


3
যে আমি সন্ধান করছিলাম, আসলে একটি ধারণাটি কেবল ব্যাখ্যা নয়, খোঁজ করা উচিত ব্রোম আপ।
হাইসুম উসমান

জাভা সর্বদা মান দ্বারা পাস হয়। জাভাতে অবজেক্টের রেফারেন্সগুলি পাস করা মান দ্বারা পাস বলে বিবেচিত হয়। এটি আপনার বিবৃতিটির বিরোধিতা করে "পাস করা 0x7fd5d258dd00 রেফারেন্স দ্বারা পাস হিসাবে পরিচিত।"
চেতনা রাইনা

53

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

#include <iostream>

void by_val(int arg) { arg += 2; }
void by_ref(int&arg) { arg += 2; }

int main()
{
    int x = 0;
    by_val(x); std::cout << x << std::endl;  // prints 0
    by_ref(x); std::cout << x << std::endl;  // prints 2

    int y = 0;
    by_ref(y); std::cout << y << std::endl;  // prints 2
    by_val(y); std::cout << y << std::endl;  // prints 2
}

1
আমি মনে করি যে শেষ লাইনে ২ টি পরিবর্তে 0 টি প্রিন্ট করা উচিত কারণ একটি সমস্যা রয়েছে দয়া করে আমাকে বলুন যে আমি কিছু অনুপস্থিত রয়েছি কিনা।
তাইমুর চাঙ্গাইজ

@TaimoorChangaiz; কোন "শেষ লাইন"? যাইহোক, আপনি যদি আইআরসি ব্যবহার করতে পারেন তবে অনুগ্রহ করে ## প্রোগ্রামিং এ ফ্রিণোডে আসুন। সেখানে জিনিসগুলি ব্যাখ্যা করা অনেক সহজ হবে। আমার নিক সেখানে "পাইয়ন" আছে।
পাইয়ন

1
@ এডুয়ার্ডো লেইন বাই_ওয়াল (y); std :: cout << y << স্টাড :: এন্ডল; // প্রিন্ট 2
তৈমুর চাঙ্গাইজ

5
@ তাইমুর চ্যাঙ্গাইজ: এটি 2 টি মুদ্রণ করবে না কেন? yপূর্ববর্তী লাইনে ইতিমধ্যে 2 এ সেট করা হয়েছে। কেন এটি 0 এ ফিরে যাবে?
পাইয়ন

@ এডুয়ার্ডোলাইন আমার খারাপ। হ্যাঁ তুমিই ঠিক. সংশোধনের জন্য ধন্যবাদ
তাইমুর চাঙ্গাইজ

28

এটির সর্বাধিক সহজ উপায় হ'ল একটি এক্সেল ফাইলে। আসুন উদাহরণস্বরূপ বলা যাক যে আপনার দুটি সংখ্যক, কোষ A1 এবং B1 অনুসারে 5 এবং 2 রয়েছে এবং আপনি তৃতীয় কক্ষে তাদের যোগফল পেতে চান, আসুন এ 2 বলে দিন। আপনি এটি দুটি উপায়ে করতে পারেন।

  • হয় এলে সেলে তার মানগুলি 52 2 টাইপ করে কক্ষ এ 2 তে প্রবেশ করে। এই ক্ষেত্রে, কক্ষগুলির A1 বা B1 এর মানগুলি পরিবর্তন হলে, A2 এর যোগফলটি একই থাকে।

  • অথবা কক্ষগুলি A1 এবং B1 এর "রেফারেন্স" পাশ করে A2 এবং A1 + B1 টাইপ করে সেল এ 2 তে প্রবেশ করুন । এই ক্ষেত্রে, কক্ষগুলির A1 বা B1 এর মানগুলি পরিবর্তন হলে, A2 এর যোগফলটিও পরিবর্তিত হয়।


এটি অন্যান্য সমস্ত উত্তরের মধ্যে সবচেয়ে সহজ এবং সর্বোত্তম উদাহরণ।
অমিত রায়

18

রেফ দিয়ে যাওয়ার সময় আপনি মূলত ভেরিয়েবলের দিকে একটি পয়েন্টার দিয়ে যাচ্ছেন। মান দ্বারা পাস আপনি ভেরিয়েবল একটি অনুলিপি পাস হয়। বেসিক ব্যবহারের সাধারণভাবে এর অর্থ পরিবর্তিত পরিবর্তনের মাধ্যমে পরিবর্তনের পরিবর্তনগুলি কলিং পদ্ধতি এবং তাদের মান অনুযায়ী পাস করা হবে।


12

মান দ্বারা পাস আপনার নির্দিষ্ট করা ভেরিয়েবলে সঞ্চিত ডেটার একটি কপি প্রেরণ করে, রেফারেন্স দিয়ে পাস ভেরিয়েবলের সাথে সরাসরি লিঙ্ক প্রেরণ করে। সুতরাং আপনি যদি রেফারেন্সের মাধ্যমে কোনও ভেরিয়েবল পাস করেন এবং তারপরে আপনি যে ব্লকটি দিয়েছিলেন তার ভিতরে ভেরিয়েবলটি পরিবর্তন করেন তবে আসল ভেরিয়েবলটি পরিবর্তিত হবে। আপনি যদি কেবল মূল্য দিয়ে পাস করেন তবে আসল ভেরিয়েবলটি আপনি যে ব্লকটি দিয়েছিলেন তা দ্বারা পরিবর্তন করা যাবে না তবে কল করার সময় যা কিছু রয়েছে তার একটি অনুলিপি পাবেন।


7

মান দ্বারা পাস - ফাংশনটি ভেরিয়েবলটি অনুলিপি করে এবং একটি অনুলিপি সহ কাজ করে (যাতে এটি মূল ভেরিয়েবলের কোনও কিছু পরিবর্তন করে না)

রেফারেন্স দ্বারা পাস - ফাংশনটি আসল ভেরিয়েবল ব্যবহার করে, আপনি যদি অন্য ফাংশনে ভেরিয়েবলটি পরিবর্তন করেন তবে এটি আসল ভেরিয়েবলেও পরিবর্তন করে।

উদাহরণ (অনুলিপি করুন এবং ব্যবহার করুন / নিজে চেষ্টা করুন এবং দেখুন):

#include <iostream>

using namespace std;

void funct1(int a){ //pass-by-value
    a = 6; //now "a" is 6 only in funct1, but not in main or anywhere else
}
void funct2(int &a){ //pass-by-reference
    a = 7; //now "a" is 7 both in funct2, main and everywhere else it'll be used
}

int main()
{
    int a = 5;

    funct1(a);
    cout<<endl<<"A is currently "<<a<<endl<<endl; //will output 5
    funct2(a);
    cout<<endl<<"A is currently "<<a<<endl<<endl; //will output 7

    return 0;
}

এটি সহজ রাখুন, উঁকি দেয়। পাঠ্য দেয়াল একটি খারাপ অভ্যাস হতে পারে।


প্যারামিটারের মান পরিবর্তন করা হয়েছিল কি না তা বুঝতে এটি সত্যই সহায়ক, ধন্যবাদ!
কেভিন ঝাও

5

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

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

সি # আলোচনা এবং উদাহরণ এখানে লিঙ্ক পাঠ্য দেখুন


3

উদাহরণ:

class Dog 
{ 
public:
    barkAt( const std::string& pOtherDog ); // const reference
    barkAt( std::string pOtherDog ); // value
};

const &সাধারণত সেরা। আপনি নির্মাণ এবং ধ্বংসের জরিমানা ব্যয় করবেন না। যদি রেফারেন্সটি কনড না হয় তবে আপনার ইন্টারফেসটি পরামর্শ দিচ্ছে যে এটি ডেটাতে পাস হওয়া পরিবর্তন করবে।


2

সংক্ষেপে, মান দ্বারা উত্তীর্ণ হ'ল এটি যা হয় এবং রেফারেন্সের মাধ্যমে পাস হয় যেখানে হয়।

যদি আপনার মান VAR1 = "শুভ গাই!" হয় তবে আপনি কেবল "শুভ ছেলে!" দেখতে পাবেন। যদি ভিএআর 1 "হ্যাপি গ্যাল!" এ পরিবর্তিত হয় তবে আপনি এটি জানেন না। যদি এটি রেফারেন্স এবং VAR1 পরিবর্তনের মাধ্যমে পাস হয় তবে আপনি পাবেন।


2

আপনি যদি কোনও ফাংশনে পাস করার পরে মূল ভেরিয়েবলের মান পরিবর্তন করতে না চান তবে ফাংশনটি " পাস বাই ভ্যালু " দিয়ে তৈরি করা উচিত " পরামিতি দিয়ে তৈরি করা উচিত।

তারপরে ফাংশনটির কেবল মান হবে তবে ভেরিয়েবলের পাসের ঠিকানা নয় not ভেরিয়েবলের ঠিকানা ব্যতীত ফাংশনের অভ্যন্তরীণ কোডটি ফাংশনের বাইরের দিক থেকে পরিবর্তনশীল মানটি পরিবর্তন করতে পারে না।

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


1

মান দ্বারা পাস মানে আর্গুমেন্ট ব্যবহার করে একটি ফাংশন মান কিভাবে পাস করতে হয়। মান দ্বারা পাস আমরা আমরা উল্লেখ করা চলক মধ্যে সঞ্চিত ডেটা অনুলিপি এবং রেফারেন্স বিসিএসই টি দ্বারা তিনি অনুলিপি করা হয় পাসের চেয়ে ধীর। এর মধ্যে আমরা অনুলিপি করা ডেটাগুলিতে পরিবর্তন করি তবে মূল ডেটা প্রভাবিত হয় না। এনডি পাসের মাধ্যমে রেফারেন্স করুন বা ঠিকানা দ্বারা পাস করুন আমরা ভেরিয়েবলের সরাসরি লিঙ্কটি প্রেরণ করি। বা ভেরিয়েবলের পয়েন্টারটি পাস করা। এটি দ্রুত বিসিএস কম সময় ব্যয় করা হয়


0

এখানে একটি উদাহরণ যা মান - পয়েন্টার মান - রেফারেন্সের মাধ্যমে পাসের মধ্যে পার্থক্যগুলি দেখায় :

void swap_by_value(int a, int b){
    int temp;

    temp = a;
    a = b;
    b = temp;
}   
void swap_by_pointer(int *a, int *b){
    int temp;

    temp = *a;
    *a = *b;
    *b = temp;
}    
void swap_by_reference(int &a, int &b){
    int temp;

    temp = a;
    a = b;
    b = temp;
}

int main(void){
    int arg1 = 1, arg2 = 2;

    swap_by_value(arg1, arg2);
    cout << arg1 << " " << arg2 << endl;    //prints 1 2

    swap_by_pointer(&arg1, &arg2);
    cout << arg1 << " " << arg2 << endl;    //prints 2 1

    arg1 = 1;                               //reset values
    arg2 = 2;
    swap_by_reference(arg1, arg2);
    cout << arg1 << " " << arg2 << endl;    //prints 2 1
}

"রেফারেন্স দ্বারা পাস" পদ্ধতিতে একটি গুরুত্বপূর্ণ সীমাবদ্ধতা রয়েছে । যদি কোনও পরামিতি রেফারেন্স হিসাবে পাস হিসাবে ঘোষিত হয় (সুতরাং এটি & চিহ্ন দ্বারা পূর্বে হয়) এর সাথে সম্পর্কিত প্রকৃত প্যারামিটার অবশ্যই পরিবর্তনশীল হতে হবে

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

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

পিএস: আপনি বর্তমান থ্রেডে ডিলান বিটি উত্তরও পরীক্ষা করতে পারেন যা এটি সরল কথায় ব্যাখ্যা করে।


আপনি উল্লেখ করেছেন "যদি কোনও পরামিতি ঘোষণা করা হয় [রেফারেন্স হিসাবে] এর সাথে সম্পর্কিত প্রকৃত প্যারামিটার অবশ্যই পরিবর্তনশীল", তবে এটি সাধারণভাবে সত্য নয়। যদি কোনও রেফারেন্স কোনও অস্থায়ী (যেমন কোনও ফাংশনের রিটার্ন মান) এর সাথে আবদ্ধ থাকে তবে রেফারেন্সটির সাথে মেলে তার জীবনকাল বাড়ানো হয়। বিশদ জন্য এখানে দেখুন ।
ক্রিস হান্ট
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.