Zugriff auf Variablen im zugewiesenen Speicher

8

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?

    
Michał Tabor 26.11.2013, 14:11
quelle

4 Antworten

13

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 ).

    
Juri Robl 26.11.2013 14:13
quelle
8

Gute Frage, aber C wird den Offset automatisch mit der Größe des spitzen Typs multiplizieren. Mit anderen Worten, wenn Sie auf

zugreifen %Vor%

für einen als

deklarierten Zeiger %Vor%

Sie werden implizit auf die Adresse p + (sizeof(T) * n) zugreifen.

    
creichen 26.11.2013 14:13
quelle
1

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.

    
Michael 26.11.2013 14:40
quelle
0

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".

    
klm123 26.11.2013 14:44
quelle

Tags und Links