সিতে পরম মান ফাংশন কেন কনস্ট ইনপুট গ্রহণ করে না?


23

সি-তে, পরম মান ফাংশনের প্রোটোটাইপ (এটি একটি ফ্লোটকে গ্রহণ করে)

 float fabsf( float );

এই প্রোটোটাইপ কেন এই ধরণের ধ্রুবক মান গ্রহণ করে না:

 float fabsf( float const );

fabsf ইনপুটটির মান পরিবর্তন করবে না, তাই না?

আমার যদি এমন কোনও ফাংশন থাকে যা কোনও ইনপুট গ্রহণ করে এবং ফেবসকে কল করে, আমি কি কনপুট হিসাবে ইনপুটটি নির্দিষ্ট করা এড়াতে বাধ্য হই?

এই পরিস্থিতিতে দৃ const়তা সংশোধন করার উপযুক্ত উপায় কী?


26
constএখানে কি অপ্রয়োজনীয়, আপনি কী ভাবছেন যে ঘটছে?
এমএম

1
@ এমএম আমি আশা করি যদি আমি ফাংশনের অভ্যন্তরে ইনপুটটির মান পরিবর্তন করার চেষ্টা করি তবে এটি একটি সংকলন সময় ত্রুটি তৈরি করবে। এটা কি ভুল?
ব্যবহারকারী 24205

16
যেহেতু ফাংশনের অভ্যন্তরের প্যারামিটারটি স্থানীয় কপি, যুক্ত constকরা সম্পূর্ণ অর্থহীন।
লন্ডিন

1
" ফেবিএসএফ ইনপুটটির মান পরিবর্তন করবে না, তা হবে? " আপনি কীভাবে বলতে পারেন? পরামিতিটি মান দ্বারা পাস করা হয়।
ডেভিড শোয়ার্টজ

নিম্নলিখিত কোডটি আইনী সি: float const x = -1.0; float y = fabsf(x);সুতরাং এটি আমার কাছে মনে হয় যা কনস্ট ইনপুট গ্রহণ fabsf করে না। "আপনি আমাকে floatমূল্য দিয়ে পাস করতে পারেন তবে আপনি একটি পাস করতে পারবেন না " বলার উপায় নেই const float। (এবং আমরা উত্তরগুলিতে যেমন দেখতে পাই, সি কোনও ফাংশনটির ইনপুট একটি হওয়া প্রয়োজন বলে কোনও উপায় সরবরাহ করে না float const))
ডেভিড কে

উত্তর:


14

সম্পাদন করা

হিসাবে এমএম মন্তব্য, মধ্যে পরামিতি উপর এগুলির নমুনাconst উপেক্ষা করা হয়। মূল উত্তরের সম্পাদিত উত্স (নীচে দেখুন) এটি দেখায়:

float correct(float const value);

float erroneous(float const value);

float changer(float value);

float correct(float value) {
  return -value;
}

float erroneous(float value) {
  value = -value;
  return value;
}

float changer(float value) {
    value = -value;
    return value;
}

কোনও ত্রুটির বার্তা নেই।

যাইহোক, আমি আশা করি এটি সাহায্য করতে পারে আসল জায়গায় রেখে দেব।


মূল

দ্য constএকটি প্যারামিটার এ তোলে প্যারামিটার শুধুমাত্র পাঠযোগ্য ফাংশন ভিতরে।

উদাহরণ স্বরূপ:

float correct(float const value) {
  return -value;
}

float erroneous(float const value) {
  value = -value;
  return value;
}

float changer(float value) {
  value = -value;
  return value;
}

এই উত্সটি ত্রুটি বার্তা ছাড়াই সংকলন করবে না।

কাজ correct() প্রদত্ত মানটি পড়বে, তার চিহ্নটি পরিবর্তন করবে এবং প্রত্যাখ্যাত মানটি ফিরিয়ে দেবে।

কাজ erroneous()প্যারামিটারে একটি অ্যাসাইনমেন্ট ব্যতীত কার্যকরভাবে একই রকম বলে মনে হচ্ছে। তবে প্যারামিটার হওয়ায় এটি constঅনুমোদিত নয়।

পরবর্তী, ফাংশন changer() উভয় হিসাবে আগে কাজ করবে, তবে এটি কোনও ত্রুটি দেয় না।

কল সাইটটি দেখুন:

float f = 3.14159;
float g = correct(f); // or erroneous(f) or changer(f)

fআর্গুমেন্ট হিসাবে প্রদত্ত ভেরিয়েবলটি প্যারামিটারে অনুলিপি করা হবে valuechanger()ডাকা হলেও তা কখনই বদলায় না ।

আপনি প্যারামিটারগুলি কিছু ধরণের স্থানীয় ভেরিয়েবল হিসাবে দেখতে পছন্দ করতে পারেন। আসলে এগুলি বেশিরভাগ উত্পন্ন মেশিন কোডে এ জাতীয়ভাবে পরিচালিত হয়।


তো, আপনি constমাঝে মাঝে দেখেন কেন ? আপনি যদি এটি একটি পয়েন্টার দেখেন প্যারামিটার হিসাবে সংজ্ঞায়িত করা ।

আপনি যখন মানটি নির্দেশিত মান পরিবর্তন করতে চান না , আপনাকে যুক্ত করতে হবে const; তবে এটি সঠিক অবস্থানে করুন!

void effective(int const * pointer);

void futile(int * const pointer);

void possible_but_overly_restricted(int const * const pointer);

প্রশ্নটি প্রোটোটাইপগুলি সম্পর্কে যদিও, float fabsf( float const );ফাংশন বাস্তবায়নের সাথে প্রোটোটাইপের কোনও সম্পর্ক নেই (যা পুনরায় পুনরায় করতে হবে না const), প্রকৃতপক্ষে constপ্রোটোটাইপটিতে পুরোপুরি উপেক্ষা করা হয়েছে
এমএম

2
কনস্ট প্রোটোটাইপে না গিয়ে ফাংশন সংজ্ঞাতে যেতে পারেন?
ব্যবহারকারী 24205

3
@ ব্যবহারকারী 24205 হ্যাঁ এটি করতে পারে
ড্যানিয়েল

33

সি মান দ্বারা পাস ব্যবহার করে। কোনও ফাংশনের প্যারামিটারের মানটি আপনার দেওয়া যুক্তির অনুলিপি।

কনস্ট এবং নন-কনস্ট্যান্ট উভয় ফ্লোটই অনুলিপি করা ঠিক আছে এবং ফলাফলটি একটি অ-কনস্ট্যান্ট ফ্লোট।

এটি অ্যাসাইনমেন্টের অনুরূপ:

const float f = 5.5f;
float g = f;   // OK

প্রকৃতপক্ষে, ভাষাটি উল্লেখ করে যে কোনও অভিব্যক্তির মান কখনই হতে পারে না const, অর্থাত্ যখন কোনও ভেরিয়েবলের কাছ থেকে কোনও মান পড়ানো হয়, তখন মানটি চলক constথাকলেও হয় না ।


8

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

এর অর্থ হ'ল কলারের দৃষ্টিকোণ থেকে float fabsf( float );এবং float fabsf( const float );একইরকম। সুতরাং প্যারামিটার তৈরি করার কোনও মানে নেই const

এটা কোথায় আছে জানার জন্য ব্যবহার constহলে প্যারামিটার আপনি মধ্যে পাস একটি পয়েন্টার, উদাহরণস্বরূপ হল:

void print_string(char *str)

এই ফাংশনটি নামটি যা বলে তা সত্ত্বেও প্রদত্ত পয়েন্টারটিকে অবজ্ঞা করে এবং এটি কী নির্দেশ করে তা সংশোধন করতে পারে, অর্থাত্ str[0] = 'x'কলিং ফাংশনটির দ্বারা পরিবর্তনযোগ্য পরিবর্তনের জন্য। যদি এই ফাংশনটি এভাবে সংজ্ঞায়িত করা হয়:

void print_string(const char *str)

কলকারীকে নিশ্চিত করা হয় যে ফাংশনটি কোন strপয়েন্টগুলিতে কোনও পরিবর্তন করতে পারে না।


"কলকারী নিশ্চিত হয়ে গেছে যে ফাংশন কোনও পরিবর্তন করতে পারে না ..." সত্য নয় not ফাংশনটি ডেটার ঠিকানাটি জানে এবং অতএব, উদাহরণ সহ: এটিকে সংশোধন করতে পারে ((char*)str)[0] = 'f'const ... *আর্গুমেন্ট তালিকায় তাই শুধুমাত্র একটি "অভিপ্রায় ঘোষণা" হয়।
oroililuig

5

কোনও ভাষা আইনজীবীর দৃষ্টিভঙ্গি যুক্ত করতে:

দুটি ফাংশনের প্রকারের সাথে সামঞ্জস্যপূর্ণ হতে, উভয়ই সামঞ্জস্যপূর্ণ রিটার্ন প্রকারগুলি নির্দিষ্ট করবে। তদুপরি, প্যারামিটার ধরণের তালিকাগুলি যদি উভয়ই উপস্থিত থাকে তবে পরামিতির সংখ্যায় এবং উপবৃত্তাকার টার্মিনেটরের ব্যবহারে সম্মত হবে; সংশ্লিষ্ট প্যারামিটারগুলির সাথে সামঞ্জস্যপূর্ণ প্রকারগুলি থাকতে হবে । [..] ধরণের সামঞ্জস্যতা এবং সংমিশ্রিত প্রকারের সংকল্পে, [..] যোগ্য প্রকারের সাথে ঘোষিত প্রতিটি প্যারামিটারটিকে তার ঘোষিত প্রকারের অযোগ্য সংস্করণ হিসাবে ধরা হয়

এন 1570 6.7.6.3/15

এর অর্থ এই দুটি সামঞ্জস্যপূর্ণ:

void foo(int const);
void foo(int);

অতএব আপনি প্রোটোটাইপটি সহ বা ছাড়াই লিখতে পারেন const(যার অর্থ আরও জ্ঞানহীন; টাইপ / পড়া কম) এবং constআপনি যদি ক্রিয়াকলাপের ভিতরে ক্রিয়াকলাপের (অনুলিপি - কলের মাধ্যমে কল করুন) প্যারামিটারটি সংশোধন করা এড়াতে চান তবে ফাংশন সংজ্ঞাতে যুক্ত করতে পারেন শরীর।

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