2010-01-02 14 views
5

निम्नलिखित सी प्रोग्राम में मुझे चेतावनी मिलती है:सी फ़ंक्शंस में परिवर्तनीय तर्क सूचियां - तर्क सूची के माध्यम से ठीक से पुन: कैसे करें?

warning #2030: '=' used in a conditional expression.

समस्या वास्तव में क्या है और मैं इससे कैसे बचूं? परिवर्तनीय तर्कों के माध्यम से पुन: प्रयास करने का सही तरीका क्या है?

#include <stdio.h> 
#include <stdarg.h> 

int Sum(int a, int b, ...) 
{ 
    int arg; 
    int Sum = a + b; 

    va_list ap; 
    va_start(ap, b); 

    while(arg = va_arg(ap, int)) 
    { 
     Sum += arg; 
    } 
    va_end(ap); 

    return Sum; 
} 

int main(int argc, char *argv[]) 
{ 
    printf("%d\n", Sum(1, 2, 4, 8)); 

    return 0; 
} 
+0

आपका उदाहरण कोड टूटा हुआ है: लूप समाप्त होता है अगर 'arg == 0', लेकिन आप 'Sum') को' 0' तर्क नहीं देते हैं; यदि सभी वैकल्पिक तर्कों का एक ही प्रकार है, तो varargs का उपयोग करने के बजाय सरणी को पास करना बेहतर होता है और इसे अच्छा दिखने के लिए कुछ मैक्रो जादू करें: http://stackoverflow.com/questions/1375474/variable-arity-in-c/ 1375636 # 1375636 – Christoph

+0

अच्छा बिंदु! लेकिन यह सवाल को प्रभावित नहीं करता है। आपका मैक्रो अच्छा है और एक स्पष्ट बेहतर विकल्प है! –

उत्तर

5

तुम क्या कर रहे हैं, मुहावरेदार है अगर थोड़ा बदसूरत सी

आदेश, संकलक क्या आप जानते हैं कि आप क्या कर रहे हैं समझाने के लिए हालांकि, आप काम का एक अतिरिक्त सेट में लपेट कर सकता है कोष्ठक:

while((arg = va_arg(ap, int))) 

यह चेतावनी का ख्याल रखना चाहिए।

अद्यतन:

काम के आसपास कोष्ठक जोड़ने का उपयोग कर C99 संकलक im में चेतावनी को दबाने के लिए प्रतीत नहीं होता है (PellesC)। - गैरी विलोबी

क्या, ऐसा नहीं हुआ? फिर आपको परीक्षण को थोड़ा और स्पष्ट करने की आवश्यकता है:

while((arg = va_arg(ap, int)) != 0) 

चाल चलाना चाहिए। इसे थोड़ा और पठनीय होने का भी तर्क दिया जा सकता है।


आप मुझसे पूछने जा रहे हैं कि मेरा मतलब "थोड़ा बदसूरत" है।

अन्य भाषाओं के साथ काम करने से, मुझे परीक्षण और संशोधन के बीच स्पष्ट अलगाव होने के लिए उपयोग किया जाता है। आप उस मूल्य के while में एक परीक्षण कर रहे हैं, लेकिन साथ ही एक साइड इफेक्ट (अर्थात् अगले तर्क में पढ़ना) बनाते हैं। जैसा कि मैंने कहा, यह सी में बहुत सामान्य माना जाता है, हाँ "idiomatic" क्योंकि बहुत सी प्रोग्रामर ऐसा करते हैं; मुझे लगता है कि कश्मीर & आर

में इसी तरह के कोड का भी उदाहरण व्यक्तिगत पसंद से कर रहे हैं, मैं शायद के रूप में इस पुनर्लेखन चाहते हैं:

while (1) { 
    arg = va_arg(ap, int); 
    if (!arg) break; 
    ... 
} 

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

+0

आप सही हैं, मैंने परीक्षण के दौरान एक स्नीकी शॉर्टकट का उपयोग किया है। मैं वर्तमान में के एंड आर पढ़ रहा हूं और पूरी किताब इस तरह चालाक छोटे शॉर्टकट से भरा है। पुस्तक पढ़ने के बाद मैं अब इनका उपयोग कर रहा हूं और वास्तव में इसे पसंद करता हूं। लेकिन, और यह एक बड़ा है, लेकिन यह कोड को पढ़ने के लिए थोड़ा कठिन बनाता है। मैं समझता हूं कि लोग दोनों का उपयोग क्यों करते हैं और आपका कोड वास्तव में चीजों को और स्पष्ट करता है। –

+0

पीएस असाइनमेंट के चारों ओर कोष्ठक जोड़ना C99 कंपाइलर आईएम (PellesC) का उपयोग कर चेतावनी को दबाता प्रतीत नहीं होता है। –

+0

ट्रिक्स पाठ्यपुस्तक के लिए अच्छे हैं। मैं कोड लिखना पसंद करूंगा जो दूसरों द्वारा आसानी से समझ में आता है। यहां तक ​​कि अगर मैं थोड़ा रक्षात्मक कोडर देखता हूं .. – Jack

0

while(arg = va_arg(ap, int)) से while((arg = va_arg(ap, int))) बदलें।

चेतावनी इसलिए होती है क्योंकि आप एक कथन में असाइनमेंट के मान को असाइन और चेक कर रहे हैं।

1

चेतावनी के बारे में है:

while(arg = va_arg(ap, int)) 

और कह रहा है "क्या आप वाकई यह मतलब नहीं था रहे हैं:"

while(arg == va_arg(ap, int)) 

इस मामले में, आप तो आप इसे दबाने सकते नहीं था कहकर:

while((arg = va_arg(ap, int))) 

हालांकि, आपका कोड अभी भी काम नहीं करेगा। Elipsis द्वारा प्रतिनिधित्व पैरामीटर की किसी भी तरह की आपूर्ति किए बिना variadic कार्यों का उपयोग करने का कोई तरीका नहीं है। उदाहरण के लिए, printf% sign का उपयोग करके करता है:

printf ("% s% d% p", x, y, z);

का अर्थ है elpisis द्वारा प्रतिनिधित्व तीन पैरामीटर हैं।

अपने मामले में, आप संभवतः पूर्णांक की सूची में टर्मिनिंग मान के रूप में शून्य का उपयोग कर सकते हैं - यही आपके लूप का तात्पर्य है।

+0

उसका कोड पूर्णांक की सूची को समाप्त करने के लिए शून्य का उपयोग करता है, इसलिए उसे इस तरह के फ़ंक्शन को कॉल करने की आवश्यकता है: Sum (1, 2, 4, 8, 0); –

+0

क्या मैंने अपने पिछले पैरा में जो कहा वह नहीं है? –

0

फिर भी एक और तरीका समारोह लिखने के लिए:

int Sum(int a, ...) 
{ 
    int sum = 0; 
    int current = a; 

    va_list args; 
    va_start(args, a); 

    for(; current; current = va_arg(args, int)) 
     sum += current; 

    va_end(args); 

    return sum; 
} 

यह मिलता है (बेकार) दूसरे नामित पैरामीटर से छुटकारा और पाश हालत से बाहर तर्क सूचक की वेतन वृद्धि ले जाता है।

संबंधित मुद्दे