Array-Pointer vertauschen
-
Hallo Leute,
ich habe zwei Arrays gleichen Typs)
und möchte ansich diese Arrays vertauschen bzw. die Pointer verbiegen.
Das heißt ich habe in etwa folgenden Code:MyTyp a[100] = {1,2,3,4,5,6,//...}; MyTyp b[100] = {7,8,9,10,11,12,//...}; void swap (MyTyp **a, MyTyp **b) { MyTyp *c = *a; *a=*b; *b=c; } //Aufruf dann so: :D swap(&a, &b);
Die Deklaration von array a kann ich nicht verändern der code ist so eingefroren.
Ist das prinzipiell möglich?Der Effekt bei diesem Code hier bei mir im Debugger ist das das erste Long Word(32Bit, ist auch der Compiler) vertauscht wird, der Rest bleibt aber leider "gleich" bzw. wird nicht vertauscht.
Ja ich weiß ist vielleicht auch nicht ganz sauber was ich da versuche aber es geht um Testcode für Code der wie gesagt fix ist und das wäre geil wenn das irgendwie gehen würde.Danke und Gruß
-
Nein.
Das geht nicht.
Arrays sind keine PointerDer Arrayname steht schon für die Adresse des ersten Elements.
Darum ist der Adressoperator auf Arraynamen auch sinnfrei.Möglich:
MyTyp a_[100] = {1,2,3,4,5,6,//...}; MyTyp b_[100] = {7,8,9,10,11,12,//...}; MyTyp a = a_; MyTyp b = b_; void swap (MyTyp **a, MyTyp **b) { MyTyp *c = *a; *a=*b; *b=c; }
aber dann bekommst du bei sizeof(a) Probleme.
-
Ein Array ist ein unmodifiable lvalue.
Deshalb kannst du das Array nicht verändern.
Du kannst in C überhaupt niemals die Adresse einer Variablen ändern. Das geht nicht. Niemals.
Um gleich vorzubeugen: Nein, ein Array ist kein Zeiger. Ein Zeiger ist kein Array.
Dir bleibt nur, den Inhalt des Array auszutauschen. Das geht aber nicht direkt mit '=', aber z.B. mit memcpy.
-
DirkB schrieb:
Nein.
Darum ist der Adressoperator auf Arraynamen auch sinnfrei.
}[/code]aber dann bekommst du bei sizeof(a) Probleme.
Nein Sinnfrei ist es nicht weil es ja darum geht diese Adresse als CallbyRef zu übergeben.
Ein Array ist kein Pointer aber der "array"-name ist quasi der Pointer. Ein implizites const dort wird wohl das Problem sein.
Aber warum funktioniert das dann partiell?
-
Die Adresse eines Arrays bekommst du mit dem Namen alleine oder als Adresse vom ersten Element.
MyTyp a[100]; MyTyp *p; p = a; oder p = &[0];
p = &a; ist sinnfrei
Der Compiler gibt eine Warnung und macht bei dir darausp = a;
An swap werden demnach die Adressen vom jeweils ersten Element übergeben.
Und die werden dann ja auch vertauscht.Ein Pointer ist eine Variable, in der eine Adresse gespeichert wird.
Sowas gibt es beim Array nicht. Also kannst du es auch nicht ändern.void swap (MyTyp *a, MyTyp *b,size_t len) { for(size_t i = 0; i< len; i++, a++, b++) { MyTyp *c = *a; *a=*b; *b=c; } }
-
DirkB schrieb:
Die Adresse eines Arrays bekommst du mit dem Namen alleine oder als Adresse vom ersten Element.
Das mag zwar der gleiche Wert sein, aber der Typ ist anders, was durchaus mal relevant sein kann:
#include <stdio.h> int main(void) { int i[5]; printf("%p %p %p\n", i, i + 1, &i+1); printf("%i %i %i\n", sizeof(*i), sizeof(*(i+1)), sizeof(*(&i+1))); return 0; }
Typische Ausgabe:
0xbfc6907c 0xbfc69080 0xbfc69090 4 4 20
-
DerMonsun schrieb:
Hallo Leute,
ich habe zwei Arrays gleichen Typs)
und möchte ansich diese Arrays vertauschen bzw. die Pointer verbiegen.arbeite doch einfach mit zeigern, die adressen lassen sich einfach tauschen und es muss nicht das komplette array umkopiert werden.
-
DirkB schrieb:
p = &a; ist sinnfrei
Der Compiler gibt eine Warnung und macht bei dir darausp = a;
Das ist nicht sinnfrei, sondern UB.
Der Compiler erkennt keine "Sinnfreiheit", er erkennt nur formale Fehler und kann hinweisen, muss es aber nicht.
Und er macht auch nicht definierte Zuweisungen bei einem UB, sondern eben irgendwas.
Und was soll er machen, wenn Bitrepräsentation und/oder Alignment der Typen typ* und typ(*)[100] nicht übereinstimmen? Genau, er macht irgendwas. Das knallt dann (wenn man Glück hat) erst bei dem Gebrauch der Zeiger, also der Dereferenzierung.