2011-08-17 15 views
12

बस सी ++ के साथ थोड़ा सा खेल रहा है। मैं वास्तव में क्या करना चाहता हूं वह एक सरणी या सूचक तर्क के लिए परिभाषित डिफ़ॉल्ट मानों के साथ एक फ़ंक्शन सेट करने में सक्षम होना है। चीजों को सरल रखने के लिए, आइए बस एक सरणी का उपयोग करें। इसलिए जैसा:सरणी तर्कों के लिए डिफ़ॉल्ट मान

void experimentA(char a[3] = {'a', 'b', 'c'});

संकलक (LLVM जीसीसी 4.2 GNU99 के साथ) "अपेक्षित अभिव्यक्ति" शिकायत। यह काफी उलझन में है, लेकिन मुझे सहयोगियों ने बताया कि ऐसा इसलिए हो रहा है क्योंकि 'मूल्य' जिसे मैं असाइन करने की कोशिश कर रहा हूं वह स्थिर रूप से आवंटित किया गया है, जबकि वेरिएबल जिसे मैं इसे असाइन करने की कोशिश कर रहा हूं (a[3]) ऑटो है।

लेकिन मैं के बाद से मैं ऐसा करने में समर्थ हूँ, पूरी तरह से यकीन है कि यदि ऐसा है नहीं कर रहा हूँ:

void experimentB(char a[3] = "abc");

और संकलक केवल मुझे उस स्ट्रिंग-शाब्दिक चार करने के लिए * रूपांतरण बहिष्कृत है चेतावनी दी है ।

मुझे समझ में नहीं आता कि इस विसंगति का कारण बनने के लिए "एबीसी" मूल रूप से {'ए', 'बी', 'सी'} से अलग कैसे है। किसी भी अंतर्दृष्टि की बहुत सराहना की है!

+0

मन "abc" रखें वास्तव में { 'एक', 'बी', 'सी', '\ 0'} है जो आकार 4 की एक सरणी में फिट होगा। –

+1

@ डॉउग: जब एक स्ट्रिंग अक्षर का उपयोग चार की सरणी को प्रारंभ करने के लिए किया जाता है, तो शून्य टर्मिनेटर के लिए जगह नहीं होती है। यदि प्रोग्रामर एक स्पष्ट लंबाई निर्दिष्ट कर रहा है, तो उसे पता होना चाहिए कि वह क्या कर रहा है। प्रारंभिक उपयोग के मामलों के वैध उपयोग-व्याख्या करने के लिए –

उत्तर

6

आपके सहयोगी गलत हैं या शायद आप गलत समझाते हैं।

समझने वाला पहला संकेत यह है कि आपके पास सी या सी ++ में फ़ंक्शन पैरामीटर के रूप में कोई सरणी नहीं हो सकती है। कारण ऐतिहासिक हैं। तो जब आप void experimentA(char a[3] ...) लिखते हैं तो संकलक स्वचालित रूप से इसे एक सूचक में परिवर्तित करता है, यानी void experimentA(char* a ...)। तो असली सवाल यह है कि "abc" एक और { 'a', 'b', 'c' } के लिए उपयुक्त डिफ़ॉल्ट मान नहीं है। इसका कारण यह है कि संकलक बताता है, "abc" एक अभिव्यक्ति है और { 'a', 'b', 'c' } नहीं है (यह प्रारंभिक है)। सी ++ में कुछ जगहें हैं जहां आप प्रारंभिककर्ता का उपयोग कर सकते हैं और कुछ जहां आप नहीं कर सकते हैं। पैरामीटर के लिए डिफ़ॉल्ट मान केवल उन स्थानों में से एक होता है जहां आप नहीं कर सकते हैं।

+0

उत्कृष्ट। यह समझ आता है। बहुत बुरा मैं जवाबों में से केवल एक को 'उत्तर' के रूप में चुन सकता हूं। –

1

"abc" एक अभिव्यक्ति है, {'a', 'b', 'c'} एक स्थिर प्रारंभकर्ता है। बाद में केवल परिवर्तनीय घोषणाओं में ही अनुमति दी गई है। मेरे लिए अज्ञात कारणों से डिफ़ॉल्ट मान के साथ तर्क अलग व्याकरण नियम है जो स्थैतिक प्रारंभकर्ताओं को अनुमति नहीं देता है।

सी ++ 0x में स्थैतिक प्रारंभकर्ताओं की अनुमति होने पर कुछ महत्वपूर्ण बदलाव हुए हैं, लेकिन मुझे यकीन नहीं है कि यह प्रश्न के मामले को कैसे प्रभावित करता है।

4

जब आप स्ट्रिंग शाब्दिक "एबीसी" का उपयोग करते हैं, तो इसे स्मृति में कहीं कंपाइलर द्वारा आवंटित किया जाता है, और इसके पहले वर्ण में एक पॉइंटर डिफ़ॉल्ट मान के रूप में उपयोग किया जाता है। तो संकलक के लिए कोड इस तरह है: void experimentA(char a[3] = 0x12345678);

दूसरे मामले के लिए, सरणी शाब्दिक को एक कंपाइलर द्वारा स्ट्रिंग के रूप में आवंटित नहीं किया जाता है (जिसे मैं भाषा में कुछ असंगतता के रूप में देखता हूं)।

2

"abc"अभिव्यक्ति है। यह अन्य सभी अभिव्यक्तियों से विशेष रूप से व्यवहार करता है, जब इसका उपयोग array of char प्रकार के चर को प्रारंभ करने के लिए किया जाता है।

{'a','b','c'} एक अभिव्यक्ति नहीं है लेकिन प्रारंभकर्ता है। यह केवल परिवर्तनीय परिभाषाओं में वाक्य रचनात्मक रूप से अनुमति है। वहां, वाक्यविन्यास या तो अभिव्यक्ति या गैर-अभिव्यक्ति प्रारंभकर्ता की अनुमति देता है, लेकिन यह ऐसा नहीं है कि प्रारंभकर्ताओं को कहीं और अभिव्यक्ति के रूप में उपयोग किया जा सके।

+0

+1। धन्यवाद कि मैंने छोड़े गए कुछ बदमाश संदेहों को मंजूरी दे दी है। –

1

एक डिफ़ॉल्ट पैरामीटर मान्य होना चाहिए।

आप ("abc") कॉल कर सकते हैं

लेकिन कभी

च ({ 'एक', 'बी', 'सी'});

"एबीसी" प्रभावी रूप से स्मृति में एक पता है और {'ए', 'बी', 'सी'} का अर्थ है सरणी या संरचना/कक्षा प्रारंभ करना।

0

ऐसा करने का एक आसान तरीका सादे पुराने फ़ंक्शन ओवरलोडिंग के माध्यम से है। उदाहरण के लिए, नीचे दिए गए जो चार * प्रकार है प्रारूप पैरामीटर के लिए डिफ़ॉल्ट पैरामीटर मान simulates:

static string to_string(time_point<system_clock> time) 
{ 
    return to_string(time, "%Y-%m-%d-%H-%M-%S"); 
} 

static string to_string(time_point<system_clock> time, const char* format) 
{ 
    time_t tt = system_clock::to_time_t(time); 

    char str[1024]; 
    if (std::strftime(str, sizeof(str), format, std::localtime(&tt))) 
     return string(str); 
    else return string(); 
} 
संबंधित मुद्दे