आपके द्वारा पाया गया व्यवहार वास्तव में C भाषा में एक बड़ा मस्सा है। जब भी आप एक फ़ंक्शन की घोषणा करते हैं जो एक सरणी पैरामीटर लेता है, तो कंपाइलर आपको अनदेखा करता है और पैरामीटर को पॉइंटर में बदलता है। इसलिए ये घोषणाएं पहले वाले की तरह व्यवहार करती हैं:
void func(int *a)
void func(int a[])
void func(int a
typedef int array_plz[5];
void func(array_plz a)
होगा सभी चार मामलों में int के लिए एक सूचक होगा। यदि आप एक एरेस को फंक करने के लिए पास करते हैं, तो यह तुरंत एक पॉइंटर में अपने पहले तत्व को क्षय करेगा। (64-बिट सिस्टम पर, एक 64-बिट पॉइंटर 32-बिट इंट के रूप में दोगुना है, इसलिए आपका साइज़ोफ़ रिटर्न 2.)
इस नियम का एकमात्र उद्देश्य ऐतिहासिक संकलक के साथ पीछे की संगतता बनाए रखना है जो फ़ंक्शन तर्कों के रूप में समग्र मूल्यों को पारित करने का समर्थन नहीं करता है।
इसका मतलब यह नहीं है कि किसी फ़ंक्शन के लिए एक सरणी पास करना असंभव है। आप इस मस्से को एक संरचना में एम्बेड करके प्राप्त कर सकते हैं (यह मूल रूप से C ++ 11 के std :: array का उद्देश्य है):
struct array_rly {
int a[5];
};
void func(struct array_rly a)
{
printf("%zd\n", sizeof(a.a)/sizeof(a.a[0])); /* prints 5 */
}
या सरणी के लिए एक पॉइंटर पास करके:
void func(const int (*a)[5])
{
printf("%zd\n", sizeof(*a)/sizeof((*a)[0])); /* prints 5 */
}
यदि सरणी आकार एक संकलन-समय स्थिर नहीं है, तो आप पॉइंटर-टू-सरणी तकनीक का उपयोग C99 चर-लम्बाई के साथ कर सकते हैं:
void func(int n, const int (*a)[n])
{
printf("%zd\n", sizeof(*a)/sizeof((*a)[0])); /* prints n */
}