4 Stimmen

Wie funktioniert die unäre Addition bei C-Zeigern?

Ich weiß, dass der unäre Operator ++ zu einer Zahl eine Eins addiert. Wenn ich ihn jedoch auf einen int-Zeiger anwende, erhöht er sich um 4 (die Größe eines int auf meinem System). Warum ist das so? Zum Beispiel der folgende Code:

int main(void)
{
  int *a = malloc(5 * sizeof(int));
  a[0] = 42;
  a[1] = 42;
  a[2] = 42;
  a[3] = 42;
  a[4] = 42;
  printf("%p\n", a);
  printf("%p\n", ++a);
  printf("%p\n", ++a);
  return 0;
}

gibt drei Zahlen mit einer Differenz von 4 zwischen den einzelnen Zahlen zurück.

4 Stimmen

Das ist keine unäre Addition, das ist eine Vorinkrementierung. Die unäre Addition ist ein einzelnes +.

1 Stimmen

Beachten Sie, dass das, was Sie getan haben, ein Speicherleck verursacht hat, weil Sie nicht mehr free(a); da er nicht mehr auf den Anfang des zugewiesenen Speichers zeigt. Der Versuch, ihn zu diesem Zeitpunkt freizugeben, wäre ein undefiniertes Verhalten und kann zu einem Segmentierungsfehler führen (wenn Sie Glück haben).

0 Stimmen

@Bunnit "Unäre Addition ist ein einzelnes +" -- Nein, genauso wenig wie -x eine unäre Subtraktion ist. Addition und Subtraktion sind binäre Operationen. Ein einzelnes - ist eine Negation; ein einzelnes + ist ein No-op.

6voto

Carl Norum Punkte 210051

So ist C nun einmal - die vollständige Erklärung steht in der Spezifikation, Abschnitt 6.5.6 Additive Operatoren , Absatz 8:

Wenn ein Ausdruck vom Typ Ganzzahl zu einem Zeiger addiert oder davon subtrahiert wird, hat das Ergebnis den Typ des Zeigeroperanden. Wenn der Zeigeroperand auf ein Element eines Array-Objekts zeigt und das Array groß genug ist, zeigt das Ergebnis auf ein Element, das gegenüber dem ursprünglichen Element so versetzt ist, dass die Differenz der Indizes des resultierenden und des ursprünglichen Array-Elements gleich dem ganzzahligen Ausdruck ist. Mit anderen Worten: Wenn der Ausdruck P zeigt auf den i -Element eines Array-Objekts, die Ausdrücke (P)+N (äquivalent, N+(P) ) und (P)-N (wobei N hat den Wert n ) zeigen jeweils auf den i + n -th und i n -ten Elemente des Array-Objekts, sofern sie existieren. Außerdem, wenn der Ausdruck P auf das letzte Element eines Array-Objekts zeigt, wird der Ausdruck (P)+1 um eins über das letzte Element des Array-Objekts hinausgeht, und wenn der Ausdruck Q über das letzte Element eines Array-Objekts hinausgeht, wird der Ausdruck (Q)-1 zeigt auf das letzte Element des Array-Objekts. Wenn sowohl der Zeigeroperand als auch das Ergebnis auf Elemente desselben Array-Objekts oder auf ein Element nach dem letzten Element des Array-Objekts zeigen, darf die Auswertung keinen Überlauf erzeugen; andernfalls ist das Verhalten undefiniert. Wenn das Ergebnis auf ein Element hinter dem letzten Element des Array-Objekts zeigt, darf es nicht als Operand eines unären *``** Operator, der ausgewertet wird.

Um das mit Ihrer Verwendung des Präfixes zu verbinden ++ Betreiber, müssen Sie auch lesen Abschnitt 6.5.3.1 Präfix-Inkrement- und Dekrement-Operatoren Absatz 2:

Der Wert des Operanden des Präfixes ++ Operator inkrementiert wird. Das Ergebnis ist der neue Wert des Operanden nach der Inkrementierung. Der Ausdruck ++E ist gleichbedeutend mit (E+=1) .

Und auch Abschnitt 6.5.16.2 Zusammengesetzte Zuordnung Absatz 3:

A Komponentenzuordnung der Form E1 op = E2 unterscheidet sich von dem einfachen Zuweisungsausdruck E1 = E1 op (E2) nur dadurch, dass der l-Wert E1 wird nur einmal ausgewertet.

3voto

Reed Copsey Punkte 536986

Es erhöht die Zeigerposition um die Größe von int den deklarierten Typ des Zeigers.

Denken Sie daran, dass ein int * ist nur ein Zeiger auf eine Stelle im Speicher, an der ein "int" gespeichert ist, wie Sie sagen. Wenn Sie ++ auf den Zeiger, so wird dieser um eine Stelle (um die Größe des Typs) verschoben, in diesem Fall wird der Wert "4" höher, da sizeof(int)==4 .

2voto

Erik Punkte 85308

Der Grund dafür ist, dass die folgende Aussage wahr ist:

*(ptr + n) == ptr[n]

Diese können austauschbar verwendet werden.

1voto

Gavin H Punkte 10060

In der Zeigerarithmetik fügt man einem Zeiger die Größe des Typs hinzu, auf den er zeigt.

so für eine gegebene:

TYPE * p;

Das Addieren zu p erhöht sich tatsächlich um sizeof(TYPE) . In diesem Fall ist die Größe des int 4.

Ver diese verwandte Frage

1voto

andy mango Punkte 1516

Denn in "C" wird die Zeigerarithmetik immer nach der Größe des Objekts skaliert, auf das gezeigt wird. Wenn man ein wenig darüber nachdenkt, stellt sich heraus, dass es "das Richtige" ist.

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