web-dev-qa-db-fra.com

C Incrémentation de l'adresse du pointeur transmis à un opérateur de fonction ++

J'ai une question qui est soulevée à partir de cette discussion: C - Modifier l'adresse d'un pointeur transmis à une fonction

Disons que j'ai le code suivant:

#include <stdio.h>
foo(char **ptr){
    *ptr++;
}

int main()
{

    char *ptr = malloc(64);
    char arr[] = "Hello World!";
    memcpy(ptr, arr, sizeof(arr)); 
    foo(&ptr);
    foo(&ptr);
    printf("%s",ptr);
    return 0;
}

Je me demandais quelle serait la production de ce programme et je pensais que cela devrait être llo World!.

Après une enquête, j'ai trouvé la question liée ci-dessus et j'ai réalisé que, dans C, les paramètres aux fonctions sont toujours passés par la valeur . Jusqu'à présent, il n'y avait pas de problème. Quand il s'agit de changer *ptr++; expression à -> *ptr = *ptr +1; La sortie devient: llo World!.

À ce stade, je peux dire que je suis un peu confus. Afin de modifier l'adresse du pointeur, nous avons besoin d'un double pointeur. C'est bon, mais pourquoi les opérations de post-incréments diffèrent-elles? Est-ce à cause de la préséance de l'opérateur?

ICI J'ai essayé l'exemple dans un compilateur C en ligne.

6
asevindik

Les opérateurs postfix ont une priorité plus élevée que les opérateurs unaires. Donc cette expression

*ptr++

est équivalent à

*( ptr++ )

La valeur de la sous-expression ptr++ est la valeur du pointeur avant son incrémentation.

Donc, en fait, vous incrémentez le paramètre ptr ayant le type char **. Donc, cet incrémentation ne change pas le pointeur d'origine et n'a pas de sens.

Au lieu de cela, vous pourriez écrire

( *ptr )++

Mais ce sera plus clair et moins déroutant d'utiliser l'opérateur d'incrément unaire comme

++*ptr

si vous voulez incrémenter le pointeur d'origine lui-même.

3
Vlad from Moscow