13 Stimmen

C-Zeiger-Arithmetik

Angesichts dieses Codes:

int *p, *q;

p = (int *) 1000;
q = (int *) 2000;

Was ist q - p und wie?

34voto

paxdiablo Punkte 809679

Nach der Norm ist er eigentlich nicht definiert. Zeigerarithmetik ist nicht garantiert, es sei denn, die Zeiger zeigen beide auf ein Element in oder kurz hinter demselben Array.

Der relevante Abschnitt der Norm ist 6.5.6:9 (n1362-Entwurf von c1x, aber dies hat sich seit c99 nicht geändert), der besagt:

Wenn zwei Zeiger subtrahiert werden, müssen beide auf Elemente desselben Array-Objekts zeigen, oder eines nach dem letzten Element des Array-Objekts zeigen; das Ergebnis ist die Differenz der Subscripts der beiden Array-Elemente.

Sie erhalten höchstwahrscheinlich 250, wenn Ihr int Datentyp ist 4 Byte, aber es gibt keine Garantie. Undefiniertes Verhalten (im Gegensatz zu implementierungsdefiniertem Verhalten) bedeutet genau das: undefiniert. Es kann alles passieren, bis hin zur völligen Zerstörung eines großen Teils der Raumzeit.

Ein Auffrischungskurs:

  • Definiertes Verhalten ist das, was in der Norm vorgeschrieben ist. Implementierungen müssen dies tun, um konform zu sein.
  • Das durch die Implementierung definierte Verhalten bleibt der Implementierung überlassen, muss aber eindeutig dokumentiert werden. Verwenden Sie dies, wenn Sie sich nicht allzu sehr um die Portabilität kümmern.
  • Unbestimmtes Verhalten bedeutet, dass alles passieren kann. Tun Sie das niemals!

8voto

Richard Pennington Punkte 19289

Q - p ist 250.

2000 - 1000 = 1000
1000 / sizeof(int) = 250

Zeigerarithmetik, unter der Annahme, dass sizeof(int) 4 ist.


Bearbeiten: OK, zur Klarstellung. In C, wenn zwei Zeiger vom gleichen Typ sind, dann ist der Unterschied zwischen ihnen die Anzahl der Dinge des Typs, auf den gezeigt wird, zwischen ihnen definiert. Zum Beispiel,

struct foo { int ar[1000]; } big[10];
char small[10];

struct foo *fs, *fe;
char *ss, *se;

fs = &big[0]; fe = &big[9];
ss = &small[0]; se = &small[9];

fe - fs == se - ss;

Das heißt, der Unterschied zwischen den beiden Zeigern ist in diesem Fall die Anzahl der Array-Elemente zwischen ihnen. In diesem Fall sind es 0, 1, ... 8 oder 9 Elemente.

2voto

vava Punkte 23765

q-p soll zurückgeben, wie viele Schritte mit Inkrement Sie machen müssen, um von p a q . Das ist 1000 / sizeof(int) und ist gleich 250. Erinnern Sie sich an q++ geht tatsächlich zum nächsten Element vom Typ int und nicht in dessen Mitte, so dass zum tatsächlichen Wert des Zeigers 4 addiert werden sollte. Daraus ergibt sich das Ergebnis.

2voto

Edan Maor Punkte 9446

Die Antwort : q-p wird 250 sein, vorausgesetzt, Sie arbeiten mit einem Rechner, auf dem ein int beträgt 4 Bytes.

Die Berechnung lautet:

q - p = 1000 1000 / 4 (Größe eines int) = 250

Die Idee dahinter :

Die Idee hinter der Zeigerarithmetik ist, dass man, wenn man eine int Zeiger auf 1000 und ein int Zeiger auf 2000, und fragen Sie nach der Differenz, sind Sie pas fragen, was 2000-1000 ist. Was Sie fragen, ist, wie viele int kann ich zwischen die beiden passen.

Dies ist zum Beispiel für alle Arten von Operationen sehr praktisch:

int *i = 100;
i++; // This is **not** 101, it is 104, cause you actually want the next place an int could fit in memory.

Dies ist besonders nützlich, wenn man mit Arrays arbeitet. Ein Array von Ints (definiert int arr[10] ) wird grundsätzlich wie ein Zeiger behandelt. Wenn Sie schreiben arr[5] übersetzt der Compiler es in *(arr + 5) , d.h., addieren Sie 5 zu der int Zeiger genannt arr und erhalten den Wert an dieser Adresse.

Das funktioniert deshalb, weil arr + 5 tut pas bedeutet "addiere 5 zum Wert von arr", es bedeutet "addiere zum Wert von arr, was immer nötig ist, um um 5 weiterzugehen int s" oder, genauer gesagt, "5 * hinzufügen sizeof(int) auf den Wert von arr"

-7voto

Boolean Punkte 13704

Da p auf einen int und damit auf q zeigt, ist q-p gleich 1000.

CodeJaeger.com

CodeJaeger ist eine Gemeinschaft für Programmierer, die täglich Hilfe erhalten..
Wir haben viele Inhalte, und Sie können auch Ihre eigenen Fragen stellen oder die Fragen anderer Leute lösen.

Powered by:

X