2011-08-27 7 views
11

मैंने एक सी पुस्तक में पढ़ा है कि एक सरणी num[7] शब्द num&num[0] के बराबर है। यह अवधारणा मेरे लिए ठीक काम कर रही थी, लेकिन जब मैंने नीचे दिखाया गया यह कार्यक्रम लिखा था तो मैं फिर से भ्रमित हो गया।दिया गया 'int num [7]', `num`,` और num [0] `,` और num` कैसे भिन्न होते हैं?

#include<stdio.h> 
#include<conio.h> 
int main() 
{ 
    int num[]={21,22,23,24,25,26,27}; 
    int *x,*y,*z; 
    x=&num; 
    y=num; 
    z=&num[0]; 
    printf("%d %d %d\n",sizeof(x),sizeof(y),sizeof(z)); 
    printf("%d %d %d\n",sizeof(&num),sizeof(num),sizeof(&num[0])); 
    printf("%d %d %d",*(&num),*(num),*(&num[0])); 
    getch(); 
    return 0; 
} 

उत्पादन होता है:

 4 4 4 
     4 28 4 
     2293536 21 21 

num तो &num[0] तो क्यों उनके आकार में एक फर्क है के समान है? और यह तीसरा प्रकार का शब्द &num क्या है? मुझे पता है कि यह एक कचरा मूल्य दिखा रहा है लेकिन क्या इस प्रकार की अवधि कोई समझ में आता है? z=&num[0] मैं पहले से ही समझता हूं। संकलक x=&num असाइनमेंट के लिए चेतावनी दिखाता है, लेकिन y=num; के लिए कंपाइलर में कोई समस्या नहीं है। यदि num आकार 28 है तो इसे एक टाइपकास्ट के बिना एक पूर्णांक सूचक y पर क्यों असाइन किया गया?

#include<stdio.h> 
#include<conio.h> 
int main() 
{ 
    int s[4][2]={{1234,56},{1235,57},{1236,58},{1237,59}}; 
    int i 
    printf ("\n%d %d %d %d %d",sizeof(s[i]),sizeof(&s[i]),sizeof(s), 
     sizeof(s[0][0]),sizeof(&s)); 
    getch(); 
    return 0; 
} 

अब उत्पादन

8 4 32 4 4 

यहाँ sizeof(s[i])8 है:

तो मैं 2-डी सरणी पर इस तरह की कोशिश की। क्योंकि s[i] एक 1-डी सरणी है और इसमें दो तत्व हैं इसलिए यह ठीक है। लेकिन मेरे पास कोई संकेत नहीं है कि &s[i] और &s शब्द क्या हैं। और मैं फिर से देख सकता हूं कि ss[0][0] के समान नहीं है। मैंने सभी कार्यक्रम चलाने के लिए देव सी ++ 4.9.9.2 संस्करण का उपयोग किया है। मैं इन तीन प्रकार की शर्तों में स्पष्ट होना चाहता हूं।

+2

पढ़ें सी पूछे जाने वाले प्रश्न एक पूरे इस मुद्दे के लिए समर्पित अनुभाग है कि: शुरुआती के लिए http://c-faq.com/aryptr/index.html – AnT

+0

@good सवाल ! दोस्त – niko

उत्तर

2

वाह, यह एक ही बार में सवालों की एक बहुत कुछ है

4 4 4 
    4 28 4 
    2293536 21 21 

sizeof() ग में एक एकल ऑपरेटर है। कोड को संकलित करते समय इसे पूर्णांक द्वारा प्रतिस्थापित किया जाता है, रनटाइम पर नहीं। तो संकलक सचमुच आपके प्रिंटफिक्स को बदलता है:

printf("%d %d %d\n", 4, 4, 4); 
printf("%d %d %d\n", 4, 28, 4); 
printf("%d %d %d",*(&num),*(num),*(&num[0])); 

संकलन में एक बहुत ही शुरुआती चरण में।

संकलक sizeof(num) लिखते समय आपको संपूर्ण सरणी का आकार देने के लिए बहुत दयालु है। इस प्रकार सरणी को सरणी पर काम करने के लिए परिभाषित किया गया है। अन्य सभी तत्व आपको आकार (& num) को छोड़कर एक (int *) का आकार देते हैं जो आपको एक (int **) का आकार देता है (एक int ** एक int * वैसे भी एक ही आकार है)।

  • & संख्या अपने सरणी
  • संख्या सूचक की स्मृति स्थान है, और & संख्या [0], अपने सरणी

में पहली int की स्मृति स्थान है अपने दूसरे के लिए सवाल;

printf("\n%d %d %d %d %d",sizeof(s[i]),sizeof(&s[i]),sizeof(s),sizeof(s[0][0]),sizeof(&s)); 

 

sizeof(s[i]) - size of an array (int[2]) == 8 
sizeof(&s[i]) - size of a pointer to an int array sizeof(int **) == 4 
sizeof(s) - size of a 2D array containing 8 ints == sizeof(int[8]) == 32 
sizeof(s[0][0]) - size of an int === 4 
sizeof(&s) - size of a pointer to an array == 4 
3

आपके विरोधाभास मान्य हैं। यह नहीं है कि num&num[0] के बराबर है। यह बस झूठा है। Arrays पॉइंटर्स से एक अलग प्रकार हैं, और numint[7] के साथ किसी ऑब्जेक्ट को संदर्भित करता है, int* नहीं। यही कारण है कि आकार अलग है, उदाहरण के लिए, क्योंकि एक सात पूर्णांक का एक संग्रह संग्रह है।

ध्यान दें कि यदि आवश्यकता हो, num को मान के साथ int* में परिवर्तित किया जा सकता है। एक रूपांतरण समानता के समान नहीं है। आपको सरणी और पॉइंटर्स के बीच यह भ्रम अजीब रूप से प्रमुख मिलेगा, क्योंकि लोग झूठी बात को दोहराते रहते हैं कि सरणी पॉइंटर्स हैं। वे नहीं हैं

3

अब मेरे सवाल है, तो संख्या [0] तो क्यों वहाँ आकार में एक अंतर नहीं है & संख्या के समान है है?

num एक सरणी है। sizeof में एरे के लिए कभी-कभी आश्चर्यजनक व्यवहार होता है, जो कि यह आपको पूरे सरणी का भंडारण आकार बताता है यदि आप इसे वास्तविक सरणी पास करते हैं, लेकिन यह केवल आपको सरणी में किसी तत्व के सूचक के आकार के बारे में बताता है यदि आप इसे पास करते हैं इस तरह के तत्व का पता। यह भ्रम पैदा कर सकता है क्योंकि सरणी नाम फंक्शन कॉल में पॉइंटर में गिरावट आती है।

तो, जवाब है कि num&num[0] के समान नहीं है - उत्तरार्द्ध, num के पहले तत्व का पता है सरणी हटाया का कुल आकार के बारे में कोई जानकारी के साथ।ये दो चीजें कई संदर्भों में अंतर-परिवर्तनीय हैं, जैसे वास्तविक कार्यों को कॉल करना, लेकिन sizeof पर कॉल करते समय (जो फ़ंक्शन नहीं है, लेकिन संकलक द्वारा प्रबंधित एक विशेष कीवर्ड)।

6

यहां अच्छे प्रश्न। उम्मीद है कि हम सभी आपके लिए इन मुद्दों को समझा सकते हैं।

को देखते हुए

int num[]={21,22,23,24,25,26,27}; 

फिर

  • numint[] टाइप है, क्योंकि यह पूर्णांकों किसकी याद जगह में आवंटित किया जाता है की एक घोषित सरणी है। ध्यान दें कि यह प्रकार int* है, जो मामला है यदि आपने इसे malloced किया होता।
  • sizeof(num) 28 है क्योंकि num 7 इंच की एक सरणी है, जो आपकी मशीन पर आकार में 4 बाइट्स हैं। मूल्य 56 होगा यदि इन्ट्स 8 बाइट्स या 14 थे, यदि उनके पास 2 बाइट थे, लेकिन 4 बाइट प्रति पूर्णांक सबसे आम है।
  • &num[0] एक सूचक, प्रकार int* की, जिसका मूल्यnum के पहले तत्व का पता है।
  • x और दोस्तों के आकार 4 हैं क्योंकि उन्हें पॉइंटर्स के रूप में घोषित किया जाता है, जो आपकी मशीन पर, आपके सी कंपाइलर के नीचे, पॉइंटर्स को 4 बाइट्स में आवंटित किया जाता है।

ध्यान में रखने की बात यह है कि एक सरणी एक पैरामीटर के रूप पारित किया जा रहा है जैसे, कुछ संदर्भों में प्रयोग किया जाता है जब, यह एक int* में बदल जाती है है। यही कारण है कि आप *num कह सकते हैं और 21 प्राप्त कर सकते हैं। मुश्किल, लेकिन ऐसा ही है। यही कारण है कि कोई आम तौर पर num और &num[0] का आदान-प्रदान कर सकता है लेकिन आपको वास्तव में भेद को ध्यान में रखना चाहिए, क्योंकि आपने देखा है, sizeof मान भिन्न थे।

रूपांतरण यह है कि y = num समझ में आता है। y में int* टाइप किया गया है और सी में आपको int[] से int* से स्वचालित रूपांतरण मिलता है। आप x = &num नहीं कर सकते क्योंकि &num का प्रकार "int सरणी के लिए सूचक" है। आप इसे int* (int में पॉइंटर) असाइन नहीं कर सकते हैं।

के मामले में

पूर्णांक रों [4] [2] = {{1234,56} {1235,57} {1236,58} {1237,59}};

हम (क्योंकि s[i] किसी पूर्णांक सरणी है) int[][] रूप s के प्रकार, pointer to int[][] रूप &s के प्रकार और int[] के सूचक के रूप में &s[i] के प्रकार की है। जिस तरह से सी आपको पॉइंटर्स को एरे को असाइन/पास करने की अनुमति देता है, वैसे ही आप अपने पहले उदाहरण के समान गेम खेल सकते हैं।

आप देखेंगे कि s, &s[0] और &s[0][0] एक ही स्मृति स्थल के लिए सभी बिंदु है, लेकिन, जैसा कि आप देखा, sizeof मूल्यों अलग होगा।मैं तुम्हें करने के लिए इस उत्पादन को समझाने की कोशिश करता हूँ पी

पहले::

+0

@pst, ठीक है, मैंने बहुत सारी धारणाएं की हैं। इसमें 7 चार-बाइट पूर्णांक हैं। हां, ओपी विभिन्न आकार की चींटियों वाली मशीन पर हो सकता है। –

+0

बेहतर, और एक +1: पी –

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