C Zeigerarithmetik
. Da ptr ein Zeiger vom Typ char ist, bewegt er sich beim Inkrementieren um sizeof(char) Bytes, d. h. um 1 Byte.
Angenommen,ptrist ein Integer-Zeiger, der auf die Adresse 1000 zeigt, und es ist eine 32-Bit-Ganzzahl. Führen wir die folgende arithmetische Operation mit diesem Zeiger aus:
ptr++
Nach Ausführung der oben genannten Operationen wirdptrauf die Position 1004 zeigen, da ptr bei jeder Inkrementierung auf die nächste Integer-Position zeigt, d. h. 4 Bytes vorwärts von der aktuellen Position. Diese Operation verschiebt den Zeiger auf die nächste Speicherposition, ohne den tatsächlichen Wert an der Speicherposition zu beeinflussen. WennptrWenn er auf ein Zeichen an Adresse 1000 zeigt, führt die obige Operation dazu, dass der Zeiger auf Position 1001 zeigt, da die nächste Zeichenposition bei 1001 liegt.
Fassen wir zusammen:
- Jede Inkrementierung eines Zeigers bewirkt tatsächlich, dass er auf die Speichereinheit des nächsten Elements zeigt.
- Jede Dekrementierung eines Zeigers bewirkt, dass er auf die Speichereinheit des vorherigen Elements zeigt.
- Die Anzahl der Bytes, um die ein Zeiger beim Inkrementieren oder Dekrementieren springt, hängt von der Länge des Datentyps der Variable ab, auf die er zeigt; zum Beispiel ist int 4 Bytes.
Einen Zeiger inkrementieren
Einen Zeiger zu inkrementieren bedeutet, den Zeiger auf die nächste Speicherposition zeigen zu lassen.
Die Inkrementoperation auf einem Zeiger führt einen entsprechenden Speicher-Offset basierend auf dem Datentyp aus, auf den der Zeiger zeigt.
Wir ziehen es vor, in Programmen Zeiger anstelle von Arrays zu verwenden, weil ein variabler Zeiger inkrementiert werden kann, während ein Array nicht inkrementiert werden kann; ein Array kann als Zeigerkonstante betrachtet werden. Das folgende Programm inkrementiert den variablen Zeiger, um nacheinander auf jedes Element im Array zuzugreifen:
Beispiel
Wenn der obige Code kompiliert und ausgeführt wird, liefert er die folgenden Ergebnisse:
存储地址:var[0] = e4a298cc 存储值:var[0] = 10 存储地址:var[1] = e4a298d0 存储值:var[1] = 100 存储地址:var[2] = e4a298d4 存储值:var[2] = 200
Zeichenzeiger inkrementieren:
Beispiel
int main() {
char str[] = "Hello";
char *ptr = str; // Der Zeiger zeigt auf das erste Zeichen der Zeichenkette
printf("Erstes Zeichen: %c\n", *ptr); // H ausgeben
ptr++; // Den Zeiger inkrementieren, um auf das nächste Zeichen zu zeigen
printf("Zeichen nach Inkrementierung: %c\n", *ptr); // Ausgabe e
return 0;
}
In diesem Beispiel bewegt ptr++ den Zeiger von str weg
Wenn der obige Code kompiliert und ausgeführt wird, liefert er die folgenden Ergebnisse:
初始字符: H 递增后字符: e
Inkrementieren eines Strukturzeigers:
Beispiel
struct Point {
int x;
int y;
};
int main() {
struct Point points[] = {{1, 2}, {3, 4}, {5, 6}};
struct Point *ptr = points; // Zeiger zeigt auf das erste Element des Struktur-Arrays
printf("Anfangspunkt: (%d, %d)\n", ptr->x, ptr->y); // Ausgabe (1, 2)
ptr++; // Inkrementiere den Zeiger, um auf die nächste Struktur zu zeigen
printf("Inkrementierter Punkt: (%d, %d)\n", ptr->x, ptr->y); // Ausgabe (3, 4)
return 0;
}
. Da ptr ein Zeiger vom Typ struct Point ist, bewegt er sich beim Inkrementieren um sizeof(struct Point) Bytes weiter.
Wenn der obige Code kompiliert und ausgeführt wird, liefert er die folgenden Ergebnisse:
初始点: (1, 2) 递增后点: (3, 4)
Einen Zeiger dekrementieren
Einen Zeiger zu dekrementieren bedeutet, den Zeiger auf die vorherige Speicherstelle zeigen zu lassen. Ähnlich wie beim Inkrementieren eines Zeigers führt die Dekrementoperation ebenfalls einen passenden Speicherversatz basierend auf dem Datentyp aus, auf den der Zeiger zeigt.
Eine Dekrementoperation auf einem Zeiger auszuführen bedeutet, die Byte-Größe seines Datentyps vom Wert zu subtrahieren, wie unten gezeigt:
Beispiel
Wenn der obige Code kompiliert und ausgeführt wird, liefert er die folgenden Ergebnisse:
初始值: 50 递减后值: 40 再次递减后值: 30
Zeichenzeiger dekrementieren:
Beispiel
int main() {
char str[] = "Hello";
char *ptr = &str[4]; // Zeiger zeigt auf das letzte Zeichen 'o' der Zeichenkette
printf("Erstes Zeichen: %c\n", *ptr); // Ausgabe o
ptr--; // Den Zeiger dekrementieren, damit er auf das vorherige Zeichen zeigt
printf("Dekrementiertes Zeichen: %c\n", *ptr); // Ausgabe l
ptr--; // Den Zeiger erneut dekrementieren
printf("Erneut dekrementiertes Zeichen: %c\n", *ptr); // Ausgabe l
return 0;
}
Wenn der obige Code kompiliert und ausgeführt wird, liefert er die folgenden Ergebnisse:
初始字符: o 递减后字符: l 再次递减后字符: l
Dekrementieren eines Strukturzeigers:
Beispiel
struct Point {
int x;
int y;
};
int main() {
struct Point points[] = {{1, 2}, {3, 4}, {5, 6}};
struct Point *ptr = &points[2]; // Der Zeiger zeigt auf das letzte Element des Struktur-Arrays
printf("Anfangspunkt: (%d, %d)\n", ptr->x, ptr->y); // Ausgabe (5, 6)
ptr--; // Den Zeiger dekrementieren, damit er auf die vorherige Struktur zeigt
printf("Dekrementierter Punkt: (%d, %d)\n", ptr->x, ptr->y); // Ausgabe (3, 4)
ptr--; // Den Zeiger erneut dekrementieren
printf("Erneut dekrementierter Punkt: (%d, %d)\n", ptr->x, ptr->y); // Ausgabe (1, 2)
return 0;
}
Wenn der obige Code kompiliert und ausgeführt wird, liefert er die folgenden Ergebnisse:
初始点: (5, 6) 递减后点: (3, 4) 再次递减后点: (1, 2)
Zeigervergleich
In C können Zeiger verglichen werden, um ihre Beziehung zueinander zu bestimmen. Der Zeigervergleich wird hauptsächlich verwendet, um festzustellen, ob zwei Zeiger auf dieselbe Speicherstelle zeigen oder ob ein Zeiger vor oder nach einem anderen Zeiger liegt.
Zeiger können mit relationalen Operatoren verglichen werden, wie z. B.==、!=、<、>、<=und>=Wenn p1 und p2 auf zwei zusammengehörige Variablen zeigen, wie z. B. verschiedene Elemente im selben Array, dann können p1 und p2 hinsichtlich ihrer Größe verglichen werden.
Im Folgenden finden sich einige Codebeispiele, die zeigen, wie Zeiger verglichen und die Ergebnisse ausgegeben werden.
Gleichheitsvergleich von Zeigern:
Beispiel
Wenn der obige Code kompiliert und ausgeführt wird, liefert er die folgenden Ergebnisse:
ptr1 和 ptr2 指向相同的内存地址 ptr1 和 ptr3 指向不同的内存地址
Vergleich der Zeigergröße:
Beispiel
int main() {
int arr[] = {10, 20, 30, 40, 50};
int *ptr1 = &arr[1]; // Zeigt auf arr[1], Wert ist 20
int *ptr2 = &arr[3]; // Zeigt auf arr[3], Wert ist 40
if (ptr1 < ptr2) {
printf("ptr1 ist vor ptr2\n"); // Diese Zeile wird ausgegeben
} else {
printf("ptr1 ist nach ptr2 oder an derselben Position\n");
}
if (ptr1 > ptr2) {
printf("ptr1 ist nach ptr2\n");
} else {
printf("ptr1 ist vor ptr2 oder an derselben Position\n"); // Diese Zeile wird ausgegeben
}
return 0;
}
Wenn der obige Code kompiliert und ausgeführt wird, liefert er die folgenden Ergebnisse:
ptr1 在 ptr2 之前 ptr1 在 ptr2 之前或相同位置
Durchlaufen eines Arrays und Vergleichen von Zeigern:
Beispiel
int main() {
int arr[] = {10, 20, 30, 40, 50};
int *start = arr; // Zeigt auf das erste Element des Arrays
int *end = &arr[4]; // Zeigt auf das letzte Element des Arrays
int *ptr;
for (ptr = start; ptr <= end; ptr++) {
printf("Der Wert, auf den der aktuelle Zeiger zeigt: %d\n", *ptr);
}
return 0;
}
Wenn der obige Code kompiliert und ausgeführt wird, liefert er die folgenden Ergebnisse:
当前指针指向的值: 10 当前指针指向的值: 20 当前指针指向的值: 30 当前指针指向的值: 40 当前指针指向的值: 50
Zusammenfassung
- Gleichheitsvergleich (
==und!=): Wird verwendet, um festzustellen, ob zwei Zeiger auf dieselbe Speicherstelle zeigen. - Größenvergleich (
<,>,<=,>=): Wird normalerweise verwendet, wenn Zeiger Arrays oder Speicherblöcke durchlaufen, um festzustellen, ob ein Zeiger vor oder nach einem anderen Zeiger liegt.