2009-04-13 5 views
13

Ich habe eine ähnliche Frage zu Structs here gestellt, aber ich versuche herauszufinden, wie C Dinge wie das Zuweisen von Variablen behandelt und warum es nicht erlaubt ist, sie einander zuzuordnen, wenn sie funktionell gleich sind.C-Array-Deklaration und Zuweisung?

Lets sagen, ich habe zwei Arrays:

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

Warum nicht x = y kompilieren? Wenn sie beide die gleiche "Signatur" sind, dann sollten Sie sie nicht hin und her zuordnen können?

Kann ich diese so deklarieren, dass ich das in C machen kann? Es macht Sinn für mich, dass Sie es könnten, aber vielleicht gibt es einen Weg, wie dies getan werden kann? Typedefs für Strukturen schien die Lösung zu sein, wäre es für Array Deklaration und Zuweisung dasselbe?

Ich schätze Ihre Jungs helfen, ich bin neu zu Stackoverflow, aber es war eine wirklich gute Ressource für mich bisher!

Antwort

23

Einfach gesagt, Arrays sind nicht zuweisbar. Sie sind ein "nicht modifizierbarer Wert". Dies wirft natürlich die Frage auf: Warum? Bitte beziehen Sie sich auf diese Frage für weitere Informationen:

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

Arrays sind keine Zeiger.x Hier bezieht sich auf ein Array, obwohl es in vielen Fällen zu einem Zeiger auf sein erstes Element "zerfällt" (wird implizit konvertiert). Ebenso ist y auch der Name eines Arrays, kein Zeiger.

Sie können innerhalb structs Array Zuordnung tun:

struct data { 
    int arr[10]; 
}; 

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

Aber man kann es nicht direkt mit Arrays tun. Verwenden Sie memcpy.

+0

Dieser Code tut immer noch nicht das, was er * wollte *, es zu tun, oder? Vielleicht irre ich mich, aber ich hatte den Eindruck, dass er hoffte, den Inhalt des y-Arrays in x zu kopieren. –

+0

Wahr. Glücklicherweise haben viele andere Antworten angegeben, dass memcpy() die richtige Wahl ist. Ich werde es hinzufügen in ... –

+6

"Der Name eines Arrays ist eigentlich die Adresse des ersten Elements dieses Arrays. Der Beispielcode, den Sie hier angeben, versucht, etwas zuzuweisen, das kein l-Wert ist." Aus Gründen der Nachwelt dachte ich, ich würde bemerken, dass beide Sätze der am meisten gewählten Antwort falsch sind. Erstens, der Name eines Arrays ist definitiv * kein Zeiger (z. B. think sizeof()), er zerfällt in vielen Fällen einfach zu einem Zeiger. Zweitens, der Name des Arrays * ist * ein L-Wert, nur kein modifizierbarer L-Wert. –

1

Um Arrays zuweisen zu können, müssen Sie die Werte innerhalb des Arrays zuweisen.

dh. x = y entspricht

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

x = y ist ein Compilerfehler. – Naveen

+0

Deshalb gebe ich das Äquivalent! –

+0

es macht den Eindruck, dass x = y ist eine gültige Anweisung – Naveen

0

Wenn sagen „int x [10]“ sagt: „10 ganze Zahlen etwas Platz reservieren und mir einen Zeiger auf den Ort passieren“. Damit die Kopie Sinn ergibt, müssen Sie auf dem Speicher arbeiten, auf den gezeigt wird, und nicht auf dem Namen des Speicherorts.

Also zum Kopieren hier würden Sie eine for-Schleife oder memcpy() verwenden.

2

Einige Nachrichten hier sagen, dass der Name eines Arrays die Adresse seines ersten Elements liefert. Es ist nicht immer wahr:

#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; 
} 

Ausgang:

40 4 
0xbfbf2ca4 0xbfbf2c80 
0

Ich habe C-Compiler verwendet, wo das ganz gut zusammenstellen würde ... und wenn der Code ausgeführt würde x Punkt y der Arrays machen.

Sie sehen, in C ist der Name eines Arrays ein Zeiger, der auf den Anfang des Arrays zeigt. In der Tat sind Arrays und Zeiger im Wesentlichen austauschbar.Sie können beliebige Zeiger und indexieren Sie es wie ein Array.

Als C in den frühen 70ern entwickelt wurde, war es für relativ kleine Programme gedacht, die in der Abstraktion kaum über der Assemblersprache lagen. In dieser Umgebung war es sehr praktisch, einfach zwischen Array-Indexierung und Zeigermathematik hin und her wechseln zu können. Das Kopieren ganzer Datenfelder war dagegen eine sehr teure Sache und kaum etwas, das vom Benutzer gefördert oder abstrahiert werden sollte.

Ja, in diesen modernen Zeiten wäre es sinnvoller, wenn der Name des Arrays für "das ganze Array" abgekürzt wäre, anstatt für "einen Ponter an der Vorderseite des Arrays". C wurde jedoch in diesen modernen Zeiten nicht entworfen. Wenn du eine Sprache willst, die es war, probier Ada. x: = y dort ist genau das, was Sie erwarten würden; Es kopiert den Inhalt eines Arrays in den anderen.

+0

Freundliches zufälliges Ping. :) Wie Sie zweifellos (jetzt) ​​wissen, ist der Name eines Arrays kein Zeiger. – GManNickG

1

In einem Versuch, Blank Antwort zu ergänzen, ich entwickeln das folgende Programm:

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; 
} 

Wenn er ausgeführt wird, ist die folgende Ausgabe:

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

Der Punkt ist, zu zeigen, wie die Kopie von Strukturen 'Werte auftreten.

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

Dies kompiliert und y die gleiche wie x sein.

+2

'y' wird wegen der Konvertierung von Array zu Zeiger ein Zeiger sein, der äquivalent zu' & x [0] 'ist, aber es wird nicht" das selbe "sein, da' x' ein Array und kein Zeiger ist. – GManNickG