Ich arbeite mit einem Zeiger auf eine Struktur. Ich möchte wissen, ob es möglich ist, direkt an eine bestimmte Position zu gelangen, ohne den Operator ++
zu verwenden.
#include <stdio.h>
#include <stdlib.h>
#define ARRAY_SIZE 10
struct dummy{
int id;
char buffer[10];
};
typedef struct dummy dummy_struct;
int main()
{
int i=0;
dummy_struct *ds = malloc(sizeof(dummy_struct)*ARRAY_SIZE);
dummy_struct *iterator = ds;
for(i=0;i<ARRAY_SIZE;i++)
{
iterator->id = i;
sprintf(iterator->buffer,"%d",i);
iterator++;
}
iterator = ds;
for(i=0;i<ARRAY_SIZE;i++)
{
printf("%d:%s:%p\n",iterator->id,iterator->buffer,iterator);
iterator++;
}
// I want to access directly to 5th position
iterator = ds + (sizeof(dummy_struct)*5);
printf("5th position %d:%s:%p\n",iterator->id,iterator->buffer,iterator);
return 0;
}
Diese Aussage
iterator = ds + (sizeof(dummy_struct)*5);
funktioniert nicht. Ich werde jeden Vorschlag zu schätzen wissen.
Nun, Zeigerarithmetik würdigt den Datentyp !!
iterator = ds + 5;
wird die Arbeit erledigen.
Um dies zu erläutern, wird der obige Ausdruck einen Zeiger erzeugen, indem er in Bytes fünfmal mit der Größe des Typs für ds
multipliziert wird. Das ist dasselbe wie &(ds[5])
.
Um der Vollständigkeit halber zu erklären, warum iterator = ds + (sizeof(dummy_struct)*5);
falsch ist, versuchen Sie hier im Wesentlichen, den Zeiger auf ein Element mit Index als (sizeof(dummy_struct)*5
zu verschieben, der sich außerhalb der Grenzen befindet. Bitte beachten Sie, dass dies undefiniertes Verhalten !! hinweis unten
Zitieren C11
, Kapitel §6.5.6/P8
Wenn ein Ausdruck, der einen Integer-Typ hat, zu einem Zeiger hinzugefügt oder von diesem abgezogen wird, hat das Ergebnis Den Typ des Zeigeroperanden. Wenn der Zeigeroperand auf ein Element von Eines Arrayobjekts zeigt und das Array groß genug ist, zeigt das Ergebnis auf einen Elementversatz von Des ursprünglichen Elements, so dass die Differenz der Subskripte des Die resultierenden und ursprünglichen Array-Elemente entsprechen dem ganzzahligen Ausdruck. Wenn der Ausdruck
P
auf Dasi
- te Element eines Array-Objekts zeigt, zeigen die Ausdrücke(P)+N
(äquivalentN+(P)
) und(P)-N
(wobeiN
den Wertn
hat) diei+n
- undi−n
_-ten Elemente des Array-Objekts , sofern sie vorhanden sind. [....]
und dann in Bezug auf das oben erwähnte undefinierte Verhalten,
[....] Wenn sowohl der Zeiger-Operand Als auch das Ergebnis auf Elemente desselben Arrayobjekts oder auf ein Element hinter dem letzten Element des Arrayobjekts zeigen, darf die Auswertung kein Überlauf; Andernfalls ist das Verhalten undefiniert. Wenn das Ergebnis einen Punkt hinter das letzte Element des Array-Objekts zeigt, darf es Nicht als Operand eines unären
*
-Operators verwendet werden, der ausgewertet wird.
Davon abgesehen ist auch die printf()
-Anweisung fehlerhaft. Sie haben zwei Konvertierungsspezifizierer, aber drei Argumente angegeben. Es ist nicht schädlich , aber nutzlos/sinnlos.
Verwandte, aus Kapitel §7.21.6.1/P2,
[...] Wenn das Format erschöpft ist, während Argumente bestehen bleiben, werden die überzähligen Argumente Ausgewertet (wie immer), werden aber ansonsten ignoriert. [...]
Anhand dieses Falls können Sie direkt verwenden
printf("5th position %d:%s:\n",ds[5].id,ds[5].buffer);
Das Verhalten von
iterator = ds + (sizeof(dummy_struct) * 5);
ist undefined wenn Sie einen Zeiger hinter dem letzten Element des Arrays setzen. Sie setzen iterator
tatsächlich auf weitere Elemente im Array, als Sie denken, um den Faktor sizeof(dummy_struct)
! Tu das nicht.
Die Sprache ermöglicht die Verwendung der Notation iterator = ds + 5;
. Diese idiomatische Zeigerarithmetik fügt 5
Lose sizeof(dummy_struct)
zur Adresse iterator
hinzu. Der Compiler nimmt also die sizeof
-Einstellung für Sie vor. Das ist ein Grund, warum die Zeigerarithmetik so mächtig ist.
Beachten Sie schließlich, dass *(ds + 5)
äquivalent zu ds[5]
ist. Ich finde, letzteres bietet mehr Klarheit bei der Arbeit mit Arrays.
Anscheinend versuchen Sie, den Zeiger iterator
auf das 5th
-Element des Arrays ds
zu richten. Diese Aussage wird jedoch zu einem falschen Ergebnis führen:
iterator = ds + (sizeof(dummy_struct)*5);
Das Ergebnis von sizeof(dummy_struct)*5
ergibt die Gesamtgröße aller Elemente der Struktur dummy_struct
, multipliziert mit 5, die zu der mit ds
referenzierten Adresse addiert und iterator
zugewiesen wird. So kann iterator
auf einen Speicherplatz verweisen, den Ihr Programm nicht besitzt. Sie müssen tun:
iterator = ds + 5;
Oder Sie können auch:
iterator = &ds[5];