C Zeigerarithmetik

C Zeiger

. 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

#include <stdio.h> const int MAX = 3; int main () { // Definiere ein Integer-Array int var[] = {10, 100, 200}; // Definiere eine Integer-Variable i und einen Integer-Zeiger ptr int i, *ptr; // Zeiger ptr auf die Startadresse des Arrays var zeigen ptr = var; // Das Array durchlaufen for ( i = 0; i < MAX; i++) { // Die Adresse ausgeben, auf die der aktuelle Zeiger ptr zeigt printf("Speicheradresse: var[%d] = %p\n", i, ptr ); // den Wert an der Adresse ausgeben, auf die der aktuelle Zeiger ptr zeigt printf("Gespeicherter Wert: var[%d] = %d\n", i, *ptr ); // Zeiger ptr auf die Position des nächsten Array-Elements verschieben ptr++; } return 0; }

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

#include <stdio.h>

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

#include <stdio.h>

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

#include <stdio.h> int main() { int arr[] = {10, 20, 30, 40, 50}; int *ptr = &arr[4]; // Zeiger zeigt auf das letzte Element des Arrays printf("Anfangswert: %d\n", *ptr); // Ausgabe 50 ptr--; // Den Zeiger dekrementieren, damit er auf das vorherige Integer-Element zeigt printf("Dekrementierter Wert: %d\n", *ptr); // Ausgabe 40 ptr--; // Den Zeiger erneut dekrementieren printf("Erneut dekrementierter Wert: %d\n", *ptr); // Ausgabe 30 return 0; }

Wenn der obige Code kompiliert und ausgeführt wird, liefert er die folgenden Ergebnisse:

初始值: 50
递减后值: 40
再次递减后值: 30

Zeichenzeiger dekrementieren:

Beispiel

#include <stdio.h>

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

#include <stdio.h>

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

#include <stdio.h> int main() { int a = 5; int b = 10; int *ptr1 = &a; int *ptr2 = &a; int *ptr3 = &b; if (ptr1 == ptr2) { printf("ptr1 und ptr2 zeigen auf dieselbe Speicheradresse\n"); // Diese Zeile wird ausgegeben } else { printf("ptr1 und ptr2 zeigen auf unterschiedliche Speicheradressen\n"); } if (ptr1 != ptr3) { printf(""ptr1 und ptr3 zeigen auf unterschiedliche Speicheradressen\n"); // Diese Zeile wird ausgegeben } else { printf("ptr1 und ptr3 zeigen auf dieselbe Speicheradresse\n"); } return 0; }

Wenn der obige Code kompiliert und ausgeführt wird, liefert er die folgenden Ergebnisse:

ptr1 和 ptr2 指向相同的内存地址
ptr1 和 ptr3 指向不同的内存地址

Vergleich der Zeigergröße:

Beispiel

#include <stdio.h>

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

#include <stdio.h>

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.
Beachten Sie, dass ein Zeigervergleich nur sinnvoll ist, wenn die Zeiger auf dasselbe Array oder denselben Speicherblock zeigen; andernfalls ist das Verhalten undefiniert.

C Zeiger

Weitere Erweiterungen