2016-08-04 6 views
70

एक C11 पार्सर (शैक्षिक उद्देश्यों के लिए) को लागू करने की कोशिश में, मैंने पाया कि C11 (p. 470) में बल्कि में C99 (p. 412) (धन्यवाद जोहान्स!), प्रत्यक्ष declarator परिभाषित किया गया है के रूप में:सी में "[*]" (स्टार संशोधक) का क्या अर्थ है?

(6.7.6) direct-declarator: 
    direct-declarator [ type-qualifier-list? * ] 

सबसे पहले, मैं सोचा कि यह व्याकरण में एक त्रुटि थी (प्रकार सूची वैकल्पिक नहीं होनी चाहिए)।

int array[*] = { 1, 2, 3 }; 
// error: star modifier used outside of function prototype 

तो जाहिरा तौर पर, (बजना में) इस स्टार संशोधक कहा जाता है: हालांकि, जब मैं यह मेरी संदर्भ संकलक (बजना) में बाहर की कोशिश की, मैं एक नहीं बल्कि अप्रत्याशित त्रुटि मिली।

मैं जल्दी से सीखा है कि वे केवल समारोह हस्ताक्षर में इस्तेमाल किया जा सकता है:

void foobar(int array[*]) 

हालांकि, वे केवल घोषणा में इस्तेमाल किया जा सकता। साथ ही एक त्रुटि में एक समारोह परिभाषा परिणामों में इसका इस्तेमाल करने की कोशिश कर रहा है:

void foobar(int array[*]) { 
    // variable length array must be bound in function definition 
} 

तो जहाँ तक मैं बता सकता हूँ, अभिप्रेत व्यवहार समारोह घोषणा में [*] उपयोग करना और फिर एक निश्चित संख्या का उपयोग करने के लिए है समारोह परिभाषा में।

// public header 
void foobar(int array[*]); 

// private implementation 
void foobar(int array[5]) { 

} 

हालांकि, मैं यह कभी नहीं देखा है और मैं काफी या तो यह करने के उद्देश्य समझ में नहीं आता।

  1. इसका उद्देश्य क्या है, इसे क्यों जोड़ा गया था?
  2. int[] के साथ क्या अंतर है?
  3. int * के साथ क्या अंतर है?
+2

यह सी 99 के बाद से सी में रहा है। मेरा मानना ​​है कि इसका मतलब है "यहां वीएलए नंबर के लिए प्लेसहोल्डर"। 'int [] []' मान्य नहीं है, लेकिन 'int [] [*] 'है (एक गैर-परिभाषित फ़ंक्शन प्रोटोटाइप में)। –

+1

आप सही हैं, मैं इसका उल्लेख करना भूल गया लेकिन मैंने त्रुटियों की खोज की जो मुझे क्लैंग से मिलीं और वे अपने वीएलए यूनिट टेस्ट सूट से मेल खाते थे। फिर भी, मैं उनके उद्देश्य को जानना चाहता हूं। धन्यवाद! – elslooo

+1

22 विचार और यह "सी स्टार संशोधक" के लिए पहले से ही पहला Google परिणाम है। आपने एक अस्पष्ट सुविधा पर मारा है। – ApproachingDarknessFish

उत्तर

14

C99 के लिए सी औचित्य दस्तावेज़ कहते हैं

A function prototype can have parameters that have variable length array types (§6.7.5.2) using a special syntax as in

int minimum(int, int [*][*]); 

This is consistent with other C prototypes where the name of the parameter need not be specified.


What's the difference with int[]

What's the difference with int *.

मुझे लगता है कि यह केवल एक समारोह प्रोटोटाइप में उन प्रकार का मतलब है कि "सूचक" है, जबकि एक [*] एक गैर शीर्ष में स्थिति (int[*] अभी भी int[] के बराबर है, मुझे लगता है कि, फ़ंक्शन प्रोटोटाइप में) वास्तव में मान्य है और का अर्थ है सरणी

// not recommended though: it is now unclear what the parameters 
// mean to human callers! 
void f(int, int [][*]); 

void f(int n, int x[][n]) { 
    x[1][0] = 1; 
} 

int main() { 
    int a[2][1]; 
    f(1, a); 
    printf("%d\n", a[1][0]); 
} 

प्रयोजन के लिए के रूप में, जब समारोह परिभाषा सरणी का अनुक्रमण, संकलक पता है कि कैसे अगले सूचकांक के कई पूर्णांकों जब पहली सूचकांक (x[i] स्किप के ऊपर f में i * n पूर्णांकों) देने को छोड़ने के लिए की जरूरत है। लेकिन गैर-परिभाषित प्रोटोटाइप घोषणा में इस जानकारी की आवश्यकता नहीं है, इसलिए इसे छोड़ा जा सकता है और * द्वारा प्रतिस्थापित किया जा सकता है।

+1

आपका फ़ंक्शन प्रोटोटाइप 'शून्य एफ (int, int x [] [*]) होना चाहिए। जब आप पहला पैरामीटर एक नाम देते हैं, तो '*' की आवश्यकता नहीं होती है। इस सुविधा का पूरा बिंदु यह है कि आप पुराने फ़ैशन फ़ंक्शन प्रोटोटाइप का उपयोग कर सकते हैं जो पैरामीटर का नाम नहीं देते हैं। – user3386109

+0

@ user3386109 हम्म, सी 8 9 में पैरामीटर की अनुमति नहीं दे रहा था? मैंने सोचा कि यह हमेशा अनुमति दी गई थी? नामों को छोड़कर क्यों "पुरानी शैली" हो रही है? लेकिन, सच है, यदि आप –

38

What is its purpose, why was it added?

उद्देश्य तब देखा जाता है जब चर चरम दो आयामी सरणी को फ़ंक्शन पैरामीटर के रूप में उपयोग किया जाता है।समारोह

int foo(int n, int m, int a[n][m]) {...} 

के निम्नलिखित

int foo(int , int, int [][*]); 
int foo(int , int, int a[*][*]); 
int foo(int , int, int (*a)[*]); 
int foo(int n, int, int a[n][*]); 
int foo(int , int m, int a[*][m]); 
int foo(int , int m, int (*a)[m]); 
int foo(int n, int m, int a[n][m]); 

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

What's the difference with int[] ?
What's the difference with int * ?

-1 डी सरणी के मामले में, के लिए समारोह परिभाषा

int bar(int n, int a[n]} {...} 

निम्नलिखित प्रोटोटाइप के किसी भी वैध

int bar (int , int *); 
int bar (int , int [*]); 
Int bar (int , int []); 
int bar (int n, int a[]); 
int bar (int n, int a[n]); 
int bar (int n, int [n]); 

है इस मामले में न तो * है और न ही n संकलक के रूप में आवश्यक है होगा int [*] और int [n] दोनों int * के रूप में व्यवहार करें। तो, एक आयामी सरणी के साथ आप बहुत अंतर नहीं देख सकते हैं।


नोट: फ़ंक्शन पैरामीटर के रूप में परिवर्तनीय लंबाई सरणी का उपयोग करते समय, पैरामीटर का क्रम महत्वपूर्ण है। bar के पहले चार प्रोटोटाइप के पैरामीटर का ऑर्डर स्विच किया जा सकता है, लेकिन बाद में दो पहले पैरामीटर में सरणी नहीं होनी चाहिए।

int bar (int a[n], int n); //Wrong. Compiler has not yet seen 'n'. 
+4

पैरामीटर का नाम देते हैं तो प्रेरणा कम होती है, यह मानक को उद्धृत करने के बजाय सीधे प्रश्न का उत्तर देती है। – alvits

+5

मानक उद्धरण सीधे प्रश्न का उत्तर देता है, और यह आधिकारिक है, क्योंकि यह मानक से है। मानक उद्धरण के साथ कुछ भी गलत नहीं है। (इसके बारे में सोचने के लिए आओ, उद्धरण तर्क दस्तावेज से है, मानक नहीं, हालांकि।) – user2357112

+0

@ user2357112 मेरे द्वारा एक और जवाब नहीं था जो सीधे मानक उद्धृत करता था। मुझे लगता है कि अल्विट्स उस से संबंधित है। मेरा सी मानक को उद्धृत नहीं करता है, क्योंकि आप सही ढंग से –

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