C Arithmétique des pointeurs

Pointeurs en C

. Comme ptr est un pointeur de type char, il se décale de sizeof(char) octets lorsqu'il est incrémenté, c'est-à-dire 1 octet.

Supposons queptrsoit un pointeur d'entier pointant vers l'adresse 1000, et qu'il s'agisse d'un entier de 32 bits. Effectuons l'opération arithmétique suivante sur ce pointeur :

ptr++

Après avoir effectué les opérations ci-dessus,ptrpointera vers l'emplacement 1004, car chaque fois que ptr est incrémenté, il pointera vers l'emplacement entier suivant, c'est-à-dire 4 octets plus loin à partir de la position actuelle. Cette opération déplace le pointeur vers l'emplacement mémoire suivant sans affecter la valeur réelle dans l'emplacement mémoire. SiptrS'il pointe vers un caractère à l'adresse 1000, l'opération ci-dessus fera pointer le pointeur vers l'emplacement 1001, car la position du caractère suivant est 1001.

Résumons :

  • Chaque incrémentation d'un pointeur le fait en réalité pointer vers l'unité de stockage de l'élément suivant.
  • Chaque décrémentation d'un pointeur le fait pointer vers l'unité de stockage de l'élément précédent.
  • Le nombre d'octets dont un pointeur se décale lorsqu'il est incrémenté ou décrémenté dépend de la longueur du type de données de la variable vers laquelle il pointe ; par exemple, int fait 4 octets.

Incrémenter un pointeur

Incrémenter un pointeur signifie faire pointer le pointeur vers l'emplacement mémoire suivant.

L'opération d'incrémentation sur un pointeur effectue un décalage mémoire approprié en fonction du type de données vers lequel le pointeur pointe.

Nous préférons utiliser des pointeurs au lieu de tableaux dans les programmes, car un pointeur variable peut être incrémenté, tandis qu'un tableau ne peut pas être incrémenté ; un tableau peut être considéré comme un pointeur constant. Le programme suivant incrémente le pointeur variable pour accéder séquentiellement à chaque élément du tableau :

Exemple

#include <stdio.h> const int MAX = 3; int main () { // Définir un tableau d'entiers int var[] = {10, 100, 200}; // Définir une variable entière i et un pointeur d'entier ptr int i, *ptr; // Faire pointer ptr vers l'adresse de début du tableau var ptr = var; // Parcourir le tableau for ( i = 0; i < MAX; i++) { // Afficher l'adresse pointée par le pointeur actuel ptr printf("Adresse mémoire : var[%d] = %p\n", i, ptr ); // afficher la valeur à l'adresse pointée par le pointeur actuel ptr printf("Valeur stockée : var[%d] = %d\n", i, *ptr ); // Déplacer le pointeur ptr vers la position de l'élément suivant du tableau ptr++; } return 0; }

Lorsque le code ci-dessus est compilé et exécuté, il produit les résultats suivants :

存储地址:var[0] = e4a298cc
存储值:var[0] = 10
存储地址:var[1] = e4a298d0
存储值:var[1] = 100
存储地址:var[2] = e4a298d4
存储值:var[2] = 200

Incrémentation du pointeur de caractère :

Exemple

#include <stdio.h>

int main() {
    char str[] = "Hello";
    char *ptr = str;  // Le pointeur pointe vers le premier caractère de la chaîne

    printf("Caractère initial : %c\n", *ptr);  // Afficher H

    ptr++;  // Incrémenter le pointeur pour qu'il pointe vers le caractère suivant
    printf("Caractère après incrémentation : %c\n", *ptr);  // Sortie e

    return 0;
}

Dans cet exemple, ptr++ fait se déplacer le pointeur à partir de str

Lorsque le code ci-dessus est compilé et exécuté, il produit les résultats suivants :

初始字符: H
递增后字符: e

Incrémentation d'un pointeur de structure :

Exemple

#include <stdio.h>

struct Point {
    int x;
    int y;
};

int main() {
    struct Point points[] = {{1, 2}, {3, 4}, {5, 6}};
    struct Point *ptr = points;  // Le pointeur pointe vers le premier élément du tableau de structures

    printf("Point initial : (%d, %d)\n", ptr->x, ptr->y);  // Sortie (1, 2)

    ptr++;  // Incrémenter le pointeur pour pointer vers la structure suivante
    printf("Point incrémenté : (%d, %d)\n", ptr->x, ptr->y);  // Sortie (3, 4)

    return 0;
}

. Comme ptr est un pointeur de type struct Point, l'incrémenter le fait avancer de sizeof(struct Point) octets.

Lorsque le code ci-dessus est compilé et exécuté, il produit les résultats suivants :

初始点: (1, 2)
递增后点: (3, 4)

Décrémenter un pointeur

Décrémenter un pointeur signifie faire pointer le pointeur vers l'emplacement mémoire précédent. Comme pour l'incrémentation d'un pointeur, l'opération de décrémentation effectue également un décalage mémoire approprié en fonction du type de données vers lequel le pointeur pointe.

Effectuer une opération de décrémentation sur un pointeur revient à soustraire la taille en octets de son type de données de la valeur, comme indiqué ci-dessous :

Exemple

#include <stdio.h> int main() { int arr[] = {10, 20, 30, 40, 50}; int *ptr = &arr[4]; // Le pointeur pointe vers le dernier élément du tableau printf("Valeur initiale : %d\n", *ptr); // Sortie 50 ptr--; // Décrémenter le pointeur pour qu'il pointe vers l'élément entier précédent printf("Valeur décrémentée : %d\n", *ptr); // Sortie 40 ptr--; // Décrémenter le pointeur à nouveau printf("Valeur décrémentée à nouveau : %d\n", *ptr); // Sortie 30 return 0; }

Lorsque le code ci-dessus est compilé et exécuté, il produit les résultats suivants :

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

Décrémenter un pointeur de caractère :

Exemple

#include <stdio.h>

int main() {
    char str[] = "Hello";
    char *ptr = &str[4];  // Le pointeur pointe vers le dernier caractère 'o' de la chaîne

    printf("Caractère initial : %c\n", *ptr);  // Sortie o

    ptr--;  // Décrémenter le pointeur pour qu'il pointe vers le caractère précédent
    printf("Caractère décrémenté : %c\n", *ptr);  // Sortie l

    ptr--;  // Décrémenter à nouveau le pointeur
    printf("Caractère décrémenté à nouveau : %c\n", *ptr);  // Sortie l

    return 0;
}

Lorsque le code ci-dessus est compilé et exécuté, il produit les résultats suivants :

初始字符: o
递减后字符: l
再次递减后字符: l

Décrémentation d'un pointeur de structure :

Exemple

#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];  // Le pointeur pointe vers le dernier élément du tableau de structures

    printf("Point initial : (%d, %d)\n", ptr->x, ptr->y);  // Sortie (5, 6)

    ptr--;  // Décrémenter le pointeur pour qu'il pointe vers la structure précédente
    printf("Point décrémenté : (%d, %d)\n", ptr->x, ptr->y);  // Sortie (3, 4)

    ptr--;  // Décrémenter à nouveau le pointeur
    printf("Point décrémenté à nouveau : (%d, %d)\n", ptr->x, ptr->y);  // Sortie (1, 2)

    return 0;
}

Lorsque le code ci-dessus est compilé et exécuté, il produit les résultats suivants :

初始点: (5, 6)
递减后点: (3, 4)
再次递减后点: (1, 2)

Comparaison de pointeurs

En C, les pointeurs peuvent être comparés pour déterminer leur relation. La comparaison de pointeurs est principalement utilisée pour déterminer si deux pointeurs pointent vers le même emplacement mémoire, ou pour déterminer si un pointeur se trouve avant ou après un autre pointeur.

Les pointeurs peuvent être comparés à l'aide d'opérateurs relationnels, tels que==、!=、<、>、<=et>=Si p1 et p2 pointent vers deux variables liées, comme des éléments différents d'un même tableau, alors p1 et p2 peuvent être comparés pour déterminer leur ordre.

Voici quelques exemples de code qui montrent comment comparer des pointeurs et afficher les résultats.

Comparaison d'égalité de pointeurs :

Exemple

#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 et ptr2 pointent vers la même adresse mémoire\n"); // Cette ligne sera affichée } else { printf("ptr1 et ptr2 pointent vers des adresses mémoire différentes\n"); } if (ptr1 != ptr3) { printf(""ptr1 et ptr3 pointent vers des adresses mémoire différentes\n"); // Cette ligne sera affichée } else { printf("ptr1 et ptr3 pointent vers la même adresse mémoire\n"); } return 0; }

Lorsque le code ci-dessus est compilé et exécuté, il produit les résultats suivants :

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

Comparaison de la taille des pointeurs :

Exemple

#include <stdio.h>

int main() {
    int arr[] = {10, 20, 30, 40, 50};
    int *ptr1 = &arr[1];  // Pointe vers arr[1], la valeur est 20
    int *ptr2 = &arr[3];  // Pointe vers arr[3], la valeur est 40

    if (ptr1 < ptr2) {
        printf("ptr1 est avant ptr2\n");  // Cette ligne sera affichée
    } else {
        printf("ptr1 est après ptr2 ou à la même position\n");
    }

    if (ptr1 > ptr2) {
        printf("ptr1 est après ptr2\n");
    } else {
        printf("ptr1 est avant ptr2 ou à la même position\n");  // Cette ligne sera affichée
    }

    return 0;
}

Lorsque le code ci-dessus est compilé et exécuté, il produit les résultats suivants :

ptr1 在 ptr2 之前
ptr1 在 ptr2 之前或相同位置

Parcours d'un tableau et comparaison de pointeurs :

Exemple

#include <stdio.h>

int main() {
    int arr[] = {10, 20, 30, 40, 50};
    int *start = arr;           // Pointe vers le premier élément du tableau
    int *end = &arr[4];         // Pointe vers le dernier élément du tableau
    int *ptr;

    for (ptr = start; ptr <= end; ptr++) {
        printf("La valeur pointée par le pointeur actuel : %d\n", *ptr);
    }

    return 0;
}

Lorsque le code ci-dessus est compilé et exécuté, il produit les résultats suivants :

当前指针指向的值: 10
当前指针指向的值: 20
当前指针指向的值: 30
当前指针指向的值: 40
当前指针指向的值: 50

Résumé

  • Comparaison d'égalité (==et!=): Utilisé pour déterminer si deux pointeurs pointent vers le même emplacement mémoire.
  • Comparaison de taille (<, >, <=, >=): Généralement utilisé lorsque des pointeurs parcourent des tableaux ou des blocs mémoire, pour déterminer si un pointeur se trouve avant ou après un autre pointeur.
Notez que la comparaison de pointeurs n'a de sens que lorsque les pointeurs pointent vers le même tableau ou le même bloc mémoire ; sinon, le comportement est indéfini.

Pointeurs en C

autres extensions