2009-04-13 14 views
13

मैं structs here पर एक समान प्रश्न पूछा है, लेकिन मैं यह पता लगाने की कैसे सी चर बताए तरह बातें संभालती है और कोशिश कर रहा हूँ यह अगर वे कार्यात्मक ही कर रहे हैं उन्हें eachother करने के लिए आवंटित करने के लिए अनुमति नहीं है क्यों।सी सरणी घोषणा और असाइनमेंट?

int x[10]; 
int y[10]; 

नहीं एक्स = y क्यों संकलन होगा:

कहते हैं कि मैं दो सरणियों है की सुविधा देता है? यदि वे दोनों समान "हस्ताक्षर" हैं, तो क्या आप उन्हें आगे और आगे असाइन नहीं कर पाएंगे?

मैं इन एक तरीका है कि मुझे क्या करना है कि सी में की अनुमति होगी में घोषित कर सकते हैं? यह मुझे समझ में आता है कि आप सक्षम होंगे, लेकिन शायद ऐसा कोई तरीका है कि यह किया जा सकता है? Structs के लिए Typedefs समाधान प्रतीत होता था, क्या यह सरणी घोषणा और असाइनमेंट के लिए समान होगा?

मैं अपने लोगों की मदद की सराहना करते हैं, मैं Stackoverflow करने के लिए नए कर रहा हूँ, लेकिन यह अब तक मेरे लिए एक बहुत अच्छी संसाधन बना रहा है!

उत्तर

23

सीधे शब्दों में कहें, सरणी असाइन करने योग्य नहीं हैं। वे एक "गैर-संशोधित अंतराल" हैं। यह निश्चित रूप से सवाल पूछता है: क्यों? अधिक जानकारी के लिए इस सवाल का संदर्भ लें:

Why does C++ support memberwise assignment of arrays within structs, but not generally?

सरणी संकेत नहीं हैं।x यहाँ , हालांकि कई परिस्थितियों में यह "decays" (परोक्ष बदल जाती है) ने अपने पहले तत्व के लिए सूचक को एक सरणी का उल्लेख करता है। इसी तरह, y भी एक सरणी का नाम है, सूचक नहीं।

आप structs भीतर सरणी काम कर सकते हैं:

struct data { 
    int arr[10]; 
}; 

struct data x = {/* blah */}; 
struct data y; 
y = x; 

लेकिन आप इसे सीधे नहीं कर सकते सरणियों के साथ। memcpy का प्रयोग करें।

+0

वह कोड अभी भी वह नहीं करता है जो वह चाहता था * यह करना चाहता है, है ना? शायद मैं गलत हूं, लेकिन मुझे लगता है कि वह वाई सरणी की सामग्री को x में कॉपी करने की उम्मीद कर रहा था। –

+0

सच है। सौभाग्य से, कई अन्य उत्तरों ने संकेत दिया है कि memcpy() सही विकल्प है। मैं इसे जोड़ दूंगा ... –

+6

"सरणी का नाम वास्तव में उस सरणी के पहले तत्व का पता है। \ उदाहरण कोड जो आप यहां प्रदान करते हैं वह कुछ ऐसा असाइन करने का प्रयास कर रहा है जो एल-वैल्यू नहीं है।" : वंश के लिए मैंने सोचा कि मुझे लगता है कि सबसे अधिक मतदान वाले उत्तरों से ये दोनों वाक्य गलत हैं। सबसे पहले, एक सरणी का नाम सबसे निश्चित रूप से * एक सूचक नहीं है (उदा। आकार का आकार()), यह कई मामलों में एक सूचक के लिए बस क्षय होता है। दूसरा, सरणी नाम * एक लाभा है, बस एक संशोधित अंतराल नहीं है। –

1

आदेश सरणियों आप सरणी के अंदर मान निर्दिष्ट करना होगा आवंटित करने के लिए में।

यानी। एक्स = y

for(int i = 0; i < 10 < ++i) 
{ 
x[i] = y[i]; 
} 
+0

x = y एक कंपाइलर त्रुटि है। – Naveen

+0

यही कारण है कि मैं समकक्ष क्यों दे रहा हूं! –

+0

यह इंप्रेशन देता है कि x = y एक वैध कथन – Naveen

0

के बराबर जब कहा, "int x [10]" कह रहा है, "10 पूर्णांकों के लिए कुछ कमरा बुक और मुझे स्थान के लिए सूचक पारित" है। तो प्रतिलिपि बनाने के लिए आपको 'मेमोरी लोकेशन का नाम' के बजाए, स्मृति की ओर इशारा करते हुए स्मृति पर काम करना होगा।

तो यहाँ कॉपी करने के लिए आप पाश या memcpy के लिए एक का उपयोग करें()।

2

यहां कुछ संदेश कहते हैं कि एक सरणी का नाम अपने पहले तत्व का पता उत्पन्न करता है। यह हमेशा सच नहीं है:

#include <stdio.h> 

int 
main(void) 
{ 
    int array[10]; 

    /* 
    * Print the size of the whole array then the size of a pointer to the 
    * first element. 
    */ 
    printf("%u %u\n", (unsigned int)sizeof array, (unsigned int)sizeof &array[0]); 

    /* 
    * You can take the address of array, which gives you a pointer to the whole 
    * array. The difference between ``pointer to array'' and ``pointer to the 
    * first element of the array'' matters when you're doing pointer arithmetic. 
    */ 
    printf("%p %p\n", (void*)(&array + 1), (void*)(array + 1)); 

    return 0; 
} 

आउटपुट:

40 4 
0xbfbf2ca4 0xbfbf2c80 
0

मैं सी compilers जहां कि ठीक संकलन होगा ... और कोड y के सरणी के लिए एक्स बिंदु होगा जब चलाने का उपयोग किया है।

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

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

हां, इन आधुनिक समयों में यह सरणी के नाम को "सरणी के सामने एक पोंटर" के बजाय "संपूर्ण सरणी" के लिए शॉर्टेंड होने का अधिक अर्थ देगा। हालांकि, सी इन आधुनिक समय में डिजाइन नहीं किया गया था। यदि आप एक ऐसी भाषा चाहते हैं, तो एडा आज़माएं। x: = y वही करता है जो आप उम्मीद करेंगे; यह एक सरणी की सामग्री को दूसरी तरफ कॉपी करता है।

+0

दोस्ताना यादृच्छिक पिंग। :) जैसा कि आप निस्संदेह (अब) जानते हैं, एक सरणी का नाम एक सूचक नहीं है। – GManNickG

1

रिक्त का जवाब पूरक की कोशिश में, मैं निम्नलिखित कार्यक्रम तैयार:

localhost:~ david$ cat test.c 
#include <stdlib.h> 
#include <stdio.h> 
int main (int argc, char * argv []) 
{ 
    struct data { 
    int c [2]; 
    } x, y; 
    x.c[0] = x.c[1] = 0; 
    y.c[0] = y.c[1] = 1; 
    printf("x.c %p %i %i\n", x.c, x.c[0], x.c[1]); 
    printf("y.c %p %i %i\n", y.c, y.c[0], y.c[1]); 
    x = y; 
    printf("x.c %p %i %i\n", x.c, x.c[0], x.c[1]); 
    printf("y.c %p %i %i\n", y.c, y.c[0], y.c[1]); 

    return 0; 
} 

जब मार डाला है, तो निम्न उत्पादन होता है:

x.c 0x7fff5fbff870 0 0 
y.c 0x7fff5fbff860 1 1 
x.c 0x7fff5fbff870 1 1 
y.c 0x7fff5fbff860 1 1 

बिंदु को वर्णन है कि कैसे संरचनाओं की प्रतिलिपि 'मान होता है।

3
int x [sz]; 
int *y = x; 

यह संकलित करता है तथा yx के रूप में ही किया जाएगा।

+2

'y' सरणी-से-पॉइंटर रूपांतरण के कारण' और x [0] 'के बराबर सूचक होगा, लेकिन यह" x "जैसा नहीं होगा क्योंकि 'x' एक सरणी है, सूचक नहीं। – GManNickG

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