C ++ এবং C এর ফাংশন প্যারামিটার হিসাবে 'কনট ইন্ট' বনাম 'ইন্ট কনট'


116

বিবেচনা:

int testfunc1 (const int a)
{
  return a;
}

int testfunc2 (int const a)
{
  return a;
}

এই দুটি ফাংশন প্রতিটি দিকেই এক বা একটি পার্থক্য আছে?

আমি সি ভাষার জন্য একটি উত্তরে আগ্রহী, তবে যদি সি ++ ভাষায় আকর্ষণীয় কিছু থাকে তবে আমিও তা জানতে চাই।


সি তে এখন কোন কনস্ট কিওয়ার্ড আছে? সেখানে ব্যবহৃত হত না তবে আমি সি 99 স্ট্যান্ডার্ডের সাথে এতটা পরিচিত নই।
ওনোরিও ক্যাটানাচি

8
আপনার দরকার নেই। সি 90 যথেষ্ট। যদিও এটি মূল কেএন্ডআর সি তে ছিল না।
মার্ক বাকের 14

3
এটি সি 98 এবং এএনএসআই-এর একটি কীওয়ার্ড। কার্নিংহাম এবং রিচির দিনগুলিতে এটি কোনও কীওয়ার্ড ছিল কিনা তা আমি জানি না।
নিলস পিপেনব্রিংক

7
এই সাইটটি ইংরেজিতে "সি অর্থহীন" অনুবাদ cdecl.org
Motti

5
আমি "ইংরাজী গিবারি থেকে সি গিবারিশ" বলতে পারি, তবে এখনও দুর্দান্ত :)
কোস

উত্তর:


175

const Tএবং T constঅভিন্ন। পয়েন্টার ধরণের সাথে এটি আরও জটিল হয়ে ওঠে:

  1. const char* একটি ধ্রুবক একটি পয়েন্টার char
  2. char const* একটি ধ্রুবক একটি পয়েন্টার char
  3. char* const একটি (পরিবর্তনীয়) এর একটি ধ্রুবক পয়েন্টার char

অন্য কথায়, (1) এবং (2) অভিন্ন। পয়েন্টারটি তৈরি করার একমাত্র উপায় ( constপয়েন্টটির চেয়ে বরং) প্রত্যয় ব্যবহার করা const

এ কারণেই অনেক লোক সর্বদা constটাইপের ডান দিকে ("পূর্ব কনস্ট" স্টাইল) পছন্দ করতে পছন্দ করে : এটি তার অবস্থানটিকে ধরণের এবং সামঞ্জস্যপূর্ণ মনে রাখার জন্য সহজ করে তোলে (এটি উপাখ্যানিকভাবে মনে হয় এটি নতুনদের শেখানো সহজ করে তোলে )।


2
সি এর কনস্ট রয়েছে, প্রদত্ত: স্ট্যাটিক কনস্ট চর চারু [] = "ফু"; আপনি ভাল foo পরিবর্তন না।
জেমস অ্যান্টিল

4
কে অ্যান্ড আর সি এর কনস্ট ছিল না; সি 90 (এবং সি 99) করে। এটি সি ++ এর তুলনায় কিছুটা সীমাবদ্ধ তবে এটি দরকারী।
মার্ক বাকের 14

এটি কি রেফারেন্সের জন্য সত্য?
কেন

1
@ কেন হ্যাঁ, এটি একই রকম।
কনরাড রুডল্ফ

1
@ ইটাল-কোহমোলজি ভাল পয়েন্ট যুক্ত হয়েছে। সব পাশাপাশি থাকা উচিত ছিল।
কনরাড রুডলফ

339

কৌশলটি হ'ল ঘোষণাটি পিছনের দিকে পড়তে হবে (ডান থেকে বামে):

const int a = 1; // read as "a is an integer which is constant"
int const a = 1; // read as "a is a constant integer"

দুটোই একই জিনিস। অতএব:

a = 2; // Can't do because a is constant

আপনি যখন আরও জটিল ঘোষণাগুলি যেমন:

const char *s;      // read as "s is a pointer to a char that is constant"
char c;
char *const t = &c; // read as "t is a constant pointer to a char"

*s = 'A'; // Can't do because the char is constant
s++;      // Can do because the pointer isn't constant
*t = 'A'; // Can do because the char isn't constant
t++;      // Can't do because the pointer is constant

5
"চর কনস্ট * ইউ" সম্পর্কে কী? এটি কি "ধ্রুবক চরিত্রের জন্য একটি নির্দেশক" বা "একটি চরিত্রের কাছে ধ্রুবক একটি পয়েন্টার" পড়ে? অস্পষ্ট মনে হচ্ছে। স্ট্যান্ডার্ডটি প্রাক্তন বলেছেন, তবে এটি সন্ধান করার জন্য আপনাকে অগ্রাধিকার এবং সাহচর্যমূলক বিধিগুলি বিবেচনায় নিতে হবে।
পানায়িওটিস কারাবাসিস

5
@ পানায়িওটিসকারাবাসিস সকলকে কোনও স্থানের অদলবদল না করে বিশেষণের শৃঙ্খলা হিসাবে বিবেচনা করা উচিত। char const *, বাম থেকে ডানে পড়ুন: "পয়েন্টার, কনস্ট, চর"। এটি কনট চরের পয়েন্টার। আপনি যখন "একটি পয়েন্টার যা ধ্রুবক" বলেন, "ধ্রুবক" বিশেষণটি পয়েন্টারে থাকে। সুতরাং, সেই ক্ষেত্রে, আপনার বিশেষণগুলির তালিকাটি সত্যই হওয়া উচিত ছিল: "কনস্ট, পয়েন্টার, চর"। তবে আপনি ঠিক বলেছেন, এই কৌতূহলের দ্বিধা আছে। এটি সত্যই একটি "কৌশল", একটি নির্দিষ্ট "বিধি" এর চেয়ে বেশি।
এটস গোলাল

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

@ মার্টিন জেএইচ: তাদের কি টাইপডেফের মাধ্যমে ভেঙে ফেলা যায় না? এবং / অথবা নির্দেশাবলী অপসারণের জন্য ব্যবহার করে?
পিটার মর্টেনসেন

14

এখানে কোন পার্থক্য নেই. তারা উভয়ই "একটি" পূর্ণসংখ্যা হিসাবে ঘোষণা করে যা পরিবর্তন করা যায় না।

আপনি পয়েন্টার ব্যবহার করার সময় জায়গাটি যেখানে পার্থক্য দেখা শুরু হয়।

দুটোই:

const int *a
int const *a

পরিবর্তিত হয় না এমন একটি পূর্ণসংখ্যার পয়েন্টার হিসাবে "একটি" ঘোষণা করুন। "a" কে বরাদ্দ করা যেতে পারে, তবে "* a" দিতে পারে না।

int * const a

একটি পূর্ণসংখ্যার একটি ধ্রুবক পয়েন্টার হিসাবে "ক" ঘোষণা করে। "* a" কে বরাদ্দ করা যেতে পারে, তবে "এ" পারবেন না।

const int * const a

"a" কে ধ্রুবক পূর্ণসংখ্যার জন্য একটি ধ্রুবক পয়েন্টার হিসাবে ঘোষণা করে। "A" বা "* a" কেও বরাদ্দ করা যাবে না।

static int one = 1;

int testfunc3 (const int *a)
{
  *a = 1; /* Error */
  a = &one;
  return *a;
}

int testfunc4 (int * const a)
{
  *a = 1;
  a = &one; /* Error */
  return *a;
}

int testfunc5 (const int * const a)
{
  *a = 1;   /* Error */
  a = &one; /* Error */
  return *a;
}

শেষ উদাহরণটি সবচেয়ে সাধারণ ব্যাখ্যা, দুর্দান্ত!
exru

7

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

"কনট ইনট * পি" হ'ল ইন্টির একটি পয়েন্টার যা সেই পয়েন্টারের মাধ্যমে ইন্ট পরিবর্তন করতে দেয় না। "ইনট * কনস্ট পি" হ'ল একটি ইন্টির পয়েন্টার যা অন্য কোন ইনটকে নির্দেশ করে পরিবর্তন করা যায় না।

Https://isocpp.org/wiki/faq/const-cor درست ness# const- ptr- vs- ptr- const দেখুন ।


নোঙ্গর ( "। প্রায়শই জিজ্ঞাসিত প্রশ্নাবলী-18.5) নষ্ট হয়ে গেছে কোনটি এটা পড়ুন উচিত (সেখানে সঙ্গে বিভিন্ন আছে।" Const "এবং" * ")?
পিটার মর্টেনসেন

@ পিটারমোরটেনসেন: হ্যাঁ, লিঙ্ক পচা। ধন্যবাদ। আমি লিঙ্কটি আপডেট করেছি।
ফ্রেড লারসন 21

5

const intint constসি এর মতো সমস্ত স্কেলার প্রকারের সাথে একই , সাধারণভাবে, স্কেলার ফাংশন প্যারামিটারটি যেমন constপ্রয়োজন হয় না হিসাবে ঘোষণা করা , যেহেতু সি এর কল-বাই-ভ্যালু শব্দার্থবিজ্ঞানের অর্থ হল ভেরিয়েবলের কোনও পরিবর্তনগুলি তার বদ্ধ ফাংশনের স্থানীয় are


4

এটি সরাসরি উত্তর নয় তবে সম্পর্কিত টিপ। জিনিস সোজা রাখার জন্য, আমি সর্বদা " constবাইরের উপর লাগানো" কনভেকশনটি ব্যবহার করি , যেখানে "বাইরের" দ্বারা আমি বোঝাতে চাইছি বাম বা ডানদিকে। এইভাবে কোনও বিভ্রান্তি নেই - কনস্টটি নিকটতম জিনিসটির জন্য প্রযোজ্য (হয় প্রকার বা এটি *)। যেমন,



int * const foo = ...; // Pointer cannot change, pointed to value can change
const int * bar = ...; // Pointer can change, pointed to value cannot change
int * baz = ...; // Pointer can change, pointed to value can change
const int * const qux = ...; // Pointer cannot change, pointed to value cannot change

6
"কন্সট এটির যা কিছু বাকী থাকবে তা" কনট তৈরি করে আপনি সম্ভবত আরও ভাল। উদাহরণস্বরূপ "ইন্টি * কনস্ট ফু" পয়েন্টারটিকে "কনস্ট" করে তোলে, কারণ পয়েন্টারটি এটিতে রেখে যায়। যাইহোক, আপনি দ্বিতীয় লাইন "ইন্ট কনস্ট * বার" লিখবেন, ইন্টি কনট তৈরি করে, কারণ এটি এটি রেখে গেছে। "ইন্ট কনস্ট * কনস্ট * কোউক্স", উভয়, ইনট এবং পয়েন্টার কনস্টকে তৈরি করে, কারণ উভয়ই একবার এটিতে রেখে যায়।
মেকি

4

এগুলি একই, তবে সি ++ এ সর্বদা ডানদিকে কনস্ট ব্যবহার করার ভাল কারণ রয়েছে। আপনি সর্বত্র সামঞ্জস্য বজায় থাকবেন কারণ কনস্টের সদস্য কার্যাদি এইভাবে ঘোষণা করতে হবে:

int getInt() const;

তবে পরিবর্তনটি thisথেকে ফাংশনে পয়েন্টার Foo * constথেকে Foo const * constএখানে দেখো.


3
এটি সম্পূর্ণ ভিন্ন ধরণের কনস্ট।
জাস্টিন মাইনার্স

1
কেন এটি সম্পূর্ণ আলাদা? ডাউনভোট উপার্জনের জন্য যথেষ্ট আলাদা।
নিক ওয়েস্টগেট

1
হ্যাঁ, প্রশ্ন "কনস্ট ইনট" এবং "ইনট কনস্ট" এর মধ্যে পার্থক্য সম্পর্কে আপনার উত্তরটির কোনও যোগসূত্র নেই।
জাস্টিন মেইনার্স

1
আমি বললাম ওরা একই রকম। এবং তবুও গৃহীত এবং শীর্ষে পোষ্ট করা উত্তরগুলি পয়েন্টারের ধরণের উপরে অতিরিক্ত তথ্য দেয়। আপনি কি তাদেরকে হ্রাস করেছেন?
নিক ওয়েস্টগেট

3

হ্যাঁ, তারা ন্যায়বিচারের জন্য একই int

এবং ভিন্ন int*


5
(কনট ইনট *) এবং (ইনট কনস্ট *) একই, তারা (ইনট * কনস্ট) থেকে একেবারে পৃথক।
জেমস অ্যান্টিল

3

আমি মনে করি এ ক্ষেত্রে এগুলি একই, তবে এখানে উদাহরণ রয়েছে যেখানে আদেশের বিষয়টি গুরুত্বপূর্ণ:

const int* cantChangeTheData;
int* const cantChangeTheAddress;

2
প্রকৃতপক্ষে, তবে ইন্ট কনট * প্রথমটির মতো একই, সুতরাং ইনট এবং কনস্টের ক্রম কোনও ব্যাপার নয়, এটি কেবল * এবং ক্র্যাডের ক্রম।
মার্ক বেকার 14
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.