Je viens de commencer à étudier C, et en faisant un exemple de passage d'un pointeur à un pointeur en tant que paramètre d'une fonction, j'ai trouvé un problème.
Voici mon exemple de code:
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
int* allocateIntArray(int* ptr, int size){
if (ptr != NULL){
for (int i = 0; i < size; i++){
ptr[i] = i;
}
}
return ptr;
}
void increasePointer(int** ptr){
if (ptr != NULL){
*ptr += 1; /* <----------------------------- This is line 16 */
}
}
int main()
{
int* p1 = (int*)malloc(sizeof(int)* 10);
allocateIntArray(p1, 10);
for (int i = 0; i < 10; i++){
printf("%d\n", p1[i]);
}
increasePointer(&p1);
printf("%d\n", *p1);
p1--;
free(p1);
fgets(string, sizeof(string), stdin);
return 0;
}
Le problème se produit à la ligne 16, lorsque je modifie *ptr+=1
en *ptr++
. Le résultat attendu doit être le tableau entier et le numéro 1, mais lorsque j'utilise *ptr++
le résultat est 0.
Y a-t-il une différence entre +=1
et ++
? Je pensais que les deux étaient identiques.
c
pointers
post-increment
huy nguyen
la source
la source
string
.allocateIntArray
est un mauvais nom car il semble que vous soyezmalloc
le tableau de la fonction, mais vous ne le faites pas. Je suggère à lafillIntArray
place. 2) Vous n'utilisez pas la valeur de retour deallocateIntArray
. Je vous suggère de changer le type de retour envoid
. 3) Laif (ptr != NULL)
fonction ne devrait-elle pas l'increasePointer
êtreif (*ptr != NULL)
? 4) Le castingmalloc
est inutile. Voir le commentaire de Sourav ci-dessus. 5) Ceci:for (int i = 0; i < 10; i++){ printf("%d\n", p1[i]); }
etprintf("%d\n", *p1); p1--;
doit être inclus dansif(p1 != NULL)
. 6)string.h
est inutilisé.p+=1
est comme++p
, pas commep++
Réponses:
La différence est due à la priorité des opérateurs.
L'opérateur de post-incrémentation
++
a une priorité plus élevée que l'opérateur de déréférencement*
. Donc*ptr++
équivaut à*(ptr++)
. En d'autres termes, l'incrément de poste modifie le pointeur, pas ce qu'il pointe.L'opérateur d'affectation
+=
a une priorité inférieure à l'opérateur de déréférencement*
, il*ptr+=1
est donc équivalent à(*ptr)+=1
. En d'autres termes, l'opérateur d'affectation modifie la valeur vers laquelle pointe le pointeur et ne change pas le pointeur lui-même.la source
*p++
et*++p
. La priorité de l'opérateur de ce dernier est claire, celle du premier suit.L'ordre de priorité des 3 opérateurs impliqués dans votre question est le suivant:
post-incrément
++
> déréférencement*
> affectation+=
Vous pouvez consulter cette page pour plus de détails sur le sujet.
En bref, pour exprimer cette affectation
*ptr+=1
à l'aide de l'opérateur de post-incrémentation, vous devez ajouter des parenthèses à l'opérateur de déréférencement pour donner à cette opération la priorité sur++
comme dans ce(*ptr)++
la source
Appliquons des parenthèses pour montrer l' ordre des opérations
Faisons-le encore avec
Et encore avec
*ptr += 1
, nous incrémentons la valeur de la variable vers laquelle pointe le pointeur .*ptr++
, nous incrémentons le pointeur après la fin de notre instruction (ligne de code) et renvoyons une référence à la variable vers laquelle pointe le pointeur .Ce dernier vous permet de faire des choses comme:
Il s'agit d'une méthode courante utilisée pour copier un
src
tableau dans un autredest
tableau.la source
Très bonne question.
Dans K&R "langage de programmation C" "5.1 pointeurs et adresses", nous pouvons obtenir une réponse à cela.
"Les opérateurs unaires * et & se lient plus étroitement que les opérateurs arithmétiques"
"Les opérateurs unaires comme * et ++ s'associent de droite à gauche ."
// Cela fonctionne comme * (ptr ++).
La bonne manière est:
la source
* ptr + = 1: Incrémente les données vers lesquelles pointe ptr. * ptr ++: pointeur d'incrémentation qui pointe vers l'emplacement mémoire suivant au lieu des données vers lesquelles pointe le pointeur.
la source