Sagen wir, ich möchte Speicher für 3 ganze Zahlen zuweisen:
%Vor%Nun um ihnen Werte zuzuweisen, mache ich:
%Vor%Um auf den zweiten Wert zuzugreifen, mache ich:
%Vor%Aber der Operator [n] ist nur eine Abkürzung für * (a + n). Dann würde ich auf das erste Byte nach einem Index zugreifen. Aber int ist 4 Bytes lang, also sollte ich nicht
tun %Vor%stattdessen? Wie funktioniert es?
Nein, der Compiler kümmert sich darum. Es gibt spezielle Regeln in der Zeigerarithmetik, und das ist einer von ihnen.
Wenn Sie es wirklich nur um ein Byte inkrementieren wollen, müssen Sie den Zeiger auf einen Zeiger auf einen Typ umwandeln, der ein Byte lang ist (zB char
).
Zum Beispiel können wir den C99-Standard verwenden, um herauszufinden, was vor sich geht. Gemäß C99 Standard:
6.5.2.1 Array-Subskribierung
Einschränkungen
- 1 Einer der Ausdrücke muss den Typ "Zeiger auf den Objekttyp" haben, der andere Ausdruck muss haben Integer-Typ, und das Ergebnis hat Typ "Typ".
Semantik - 2 Ein Postfix-Ausdruck gefolgt von einem Ausdruck in eckigen Klammern [] ist ein subskribierter Ausdruck Bezeichnung eines Elements eines Array-Objekts. Die Definition des tiefgestellten Operators [] ist das E1 [E2] ist identisch mit (* ((E1) + (E2))) . Wegen der Konvertierungsregeln das Wenden Sie sich an den binären + Operator, wenn E1 ein Array-Objekt ist (äquivalent dazu ein Zeiger auf den Anfangselement eines Array-Objekts) und E2 ist eine ganze Zahl, E1 [E2] bezeichnet das E2-te Element von E1 (von Null ausgehend).
Und ab 6.5.5.8 über Konvertierungsregeln für +
operator:
Wenn ein Ausdruck, der einen Integer-Typ hat, zu einem Zeiger hinzugefügt oder davon subtrahiert wird, wird der Ergebnis hat den Typ des Zeigeroperanden. Wenn der Zeigeroperand auf ein Element von zeigt ein Array-Objekt, und das Array ist groß genug, zeigt das Ergebnis auf ein Element Offset von das ursprüngliche Element so, dass die Differenz der Indizes des resultierenden und ursprünglichen Array-Elemente entsprechen dem Ganzzahl-Ausdruck. Mit anderen Worten, wenn der Ausdruck P auf zeigt das i-te Element eines Array-Objekts, die Ausdrücke (P) + N (äquivalent, N + (P)) und (P) -N (wobei N den Wert n hat) zeigt jeweils auf die i + n-ten und i-n-ten Elemente von das Array-Objekt, sofern sie vorhanden sind. Außerdem, wenn der Ausdruck P auf den letzten zeigt Englisch: www.weisang.info/index.php?id=143&t...h=fbcd8d2cf9 Bei einem Element eines Array - Objekts zeigt der Ausdruck (P) +1 auf eins nach dem letzten Element des Array-Objekt, und wenn der Ausdruck Q hinter das letzte Element eines Array-Objekts zeigt, Der Ausdruck (Q) -1 zeigt auf das letzte Element des Array-Objekts. Wenn sowohl der Zeiger Operand und das Ergebnis zeigen auf Elemente desselben Array-Objekts oder eines nach dem letzten Element des Array-Objekts, soll die Auswertung keinen Überlauf erzeugen; ansonsten der Verhalten ist nicht definiert. Wenn das Ergebnis nach dem letzten Element des Array-Objekts liegt, wird es angezeigt darf nicht als Operand eines unären * Operators verwendet werden, der ausgewertet wird.
Somit sind alle diese Notizen über Ihren Fall und es funktioniert genau wie Sie geschrieben haben und Sie brauchen keine speziellen Konstruktionen, Dereferenzierung oder irgendetwas anderes (Zeiger-Arithmetik das für Sie tun):
%Vor%Oder in Bezug auf Byte-Zeiger (um die Beschreibung zu vereinfachen, was passiert), ähnelt diese Operation:
%Vor% Außerdem können Sie auf dieses Element mit 1[pn]
zugreifen und das Ergebnis ist dasselbe.
Das solltest du nicht. Die Regeln, was passiert, wenn Sie einen Zeiger zu einem Zeiger hinzufügen, sind nicht offensichtlich. Verwenden Sie also besser nicht Ihre Intuition, sondern lesen Sie Sprachstandards darüber, was in solchen Fällen passiert. Zum Beispiel lesen Sie mehr über Zeigerarithmetik hier (C) oder hier (C ++).
Kurz - ein nicht void-Zeiger wird in Einheiten der Typlängen "gemessen".