C में पूर्ण मान फ़ंक्शंस कांस्ट इनपुट स्वीकार क्यों नहीं करते?


23

सी में, निरपेक्ष मान फ़ंक्शन के लिए प्रोटोटाइप (जो एक फ्लोट को स्वीकार करता है) है

 float fabsf( float );

यह प्रोटोटाइप इस तरह एक स्थिर मान क्यों स्वीकार नहीं करता है:

 float fabsf( float const );

fabsf इनपुट का मूल्य नहीं बदलेगा, क्या यह?

अगर मेरे पास एक फ़ंक्शन है जो इनपुट को स्वीकार करता है और फ़ैब्स को कॉल करता है, तो क्या मुझे इनपुट को कास्ट के रूप में निर्दिष्ट करने से बचने के लिए मजबूर किया जाता है?

इस स्थिति में कब्ज की शुद्धता को संभालने का उपयुक्त तरीका क्या है?


26
constयहाँ बेमानी है, आप क्या कल्पना करते हैं?
MM

1
@MM मुझे उम्मीद है कि अगर मैं फ़ंक्शन के अंदर इनपुट के मूल्य को बदलने की कोशिश करता हूं तो यह एक संकलन समय त्रुटि पैदा करेगा। क्या यह गलत है?
user24205

16
चूंकि फ़ंक्शन के अंदर पैरामीटर एक स्थानीय प्रतिलिपि है, इसलिए जोड़ना constपूरी तरह से अर्थहीन है।
लुंडिन

1
" fabsf इनपुट के मूल्य को नहीं बदलेगा, है ना? " आप कैसे बता सकते हैं? पैरामीटर मान द्वारा पारित किया गया है।
डेविड श्वार्ट्ज

निम्नलिखित कोड कानूनी C है: 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में प्रोटोटाइप में पूरी तरह से अनदेखा किया गया है
MM

2
क्या प्रोटोटाइप में जाने के बिना फंक्शन परिभाषा में जा सकते हैं?
user24205

3
@ user24205 हाँ यह कर सकते हैं
डैनियल

33

C मान से पास का उपयोग करता है। किसी फ़ंक्शन के पैरामीटर का मान आपके द्वारा दिए गए तर्क की एक प्रति है।

कॉन्स्ट और नॉन-कॉन्स्टल दोनों फ्लोट्स को कॉपी करना ठीक है, और रिजल्ट एक नॉन-कॉस्ट फ्लोट है।

यह असाइनमेंट के समान है:

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

वास्तव में, भाषा निर्दिष्ट करती है कि एक अभिव्यक्ति का मूल्य कभी नहीं हो सकता है const, अर्थात जब एक चर से मूल्य पढ़ा जाता है, तो वह मान भी नहीं होता है constयदि चर था।


8

चूँकि C भाषा पास शब्दार्थ शब्दार्थ से प्रयोग करती है, इसलिए आप इसे पास करते समय कोई भी तर्क, जबकि इसे आंतरिक रूप से संशोधित किया जा सकता है, आपके द्वारा पास किए जाने वाले मूल्य को सीधे प्रभावित नहीं करता है।

इसका मतलब है कि कॉलर के दृष्टिकोण से, float fabsf( float );और float fabsf( const float );समान हैं। इसलिए पैरामीटर बनाने का कोई मतलब नहीं है const

यह कहां करता है मेकअप भावना उपयोग करने के लिए constहै अगर पैरामीटर में पारित एक सूचक, उदाहरण के लिए है:

void print_string(char *str)

यह फ़ंक्शन, जो नाम का सुझाव देता है, के बावजूद दिए गए पॉइंटर को निष्क्रिय कर str[0] = 'x'सकता है और कॉलिंग फ़ंक्शन द्वारा देखे जा सकने वाले परिवर्तन को परिणामित करने के लिए इसे इंगित करता है। यदि यह फ़ंक्शन इस तरह परिभाषित किया गया था:

void print_string(const char *str)

कॉल करने वाले को यह सुनिश्चित किया जाता है कि फ़ंक्शन किस strबिंदु पर कोई संशोधन नहीं कर सकता है।


"फोन करने वाले को यह सुनिश्चित किया जाता है कि फ़ंक्शन कोई भी संशोधन नहीं कर सकता है ..." यह सच नहीं है। फ़ंक्शन डेटा का पता जानता है और इसलिए इसे संशोधित कर सकता है, जैसे ((char*)str)[0] = 'f':। const ... *तर्क सूची में इसलिए केवल एक "आशय का घोषणा" है।
oromoiluig

5

भाषा वकील परिप्रेक्ष्य जोड़ने के लिए:

दो फ़ंक्शन प्रकार संगत होने के लिए, दोनों संगत रिटर्न प्रकार निर्दिष्ट करेंगे। इसके अलावा, पैरामीटर प्रकार की सूची, यदि दोनों मौजूद हैं, तो मापदंडों की संख्या और दीर्घवृत्त टर्मिनेटर के उपयोग में सहमत होंगे; संगत मापदंडों में संगत प्रकार होंगे । [..] प्रकार की संगतता और एक समग्र प्रकार के निर्धारण में, [..] योग्य प्रकार के साथ घोषित प्रत्येक पैरामीटर को इसके घोषित प्रकार के अयोग्य संस्करण के रूप में लिया जाता है

N1570 6.7.6.3/15

इसका मतलब है कि ये दोनों संगत हैं:

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

इसलिए आप प्रोटोटाइप के साथ या उसके बिना लिख ​​सकते हैं const(जिसका अर्थ है बिना अधिक अर्थ के; टाइप / रीड करने के लिए कम) और constफ़ंक्शन परिभाषा में जोड़ सकते हैं यदि आप गलती से संशोधित करने से बचना चाहते हैं (कॉपी - वैल्यू बाय कॉल!) पैरामीटर फ़ंक्शन के अंदर। तन।

हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.