Initialisation pointeur

Résolu/Fermé
trocib Messages postés 6 Date d'inscription mercredi 9 juin 2021 Statut Membre Dernière intervention 19 août 2022 - 30 mars 2022 à 16:10
trocib Messages postés 6 Date d'inscription mercredi 9 juin 2021 Statut Membre Dernière intervention 19 août 2022 - 30 mars 2022 à 20:16
Bonjour,

J'essaie d'apprendre la programmation C à mes heures perdues et j'en arrive tout doucement aux pointeurs.

Le principe est très compréhensible : le pointeur contient l'adresse mémoire de la donnée typée. OK.

Là où je bloque, c'est l'écriture du code et notamment lors de l'initialisation d'un simple pointeur vers un entier.

Si j'écris ceci :


int *p_int;
  • p_int = 5;


Ca ne génère aucun avertissement.

Si j'écris ceci :


int *p_int = 5;


Je reçois cet avertissement : warning: initialization of ‘int *’ from ‘int’ makes pointer from integer without a cast [-Wint-conversion]

J'avoue ne pas comprendre pourquoi. Le code écrit en une seule ligne est pourtant exactement le condensé du code en 2 lignes. Dans le code en 1 ligne j'affecte la valeur 5 à "*p_int" et pas à "p_int".

Avez-vous une explication à cela ?

Merci d'avance pour votre aide.

Cordialement,

trocib

3 réponses

yg_be Messages postés 22753 Date d'inscription lundi 9 juin 2008 Statut Contributeur Dernière intervention 4 mai 2024 1 479
30 mars 2022 à 16:35
bonjour,
ton premier code n'est pas clair, probablement parce que tu n'as pas correctement utilisé les balises de code.
explications: https://codes-sources.commentcamarche.net/faq/11288-les-balises-de-code
ceci:
int *p_int = 5;

est, je pense, équivalent à:
int *p_int;
p_int = 5;

Quelle documentation utilises-tu pour comprendre la syntaxe du langage C? J'ai l'impression que tu as inventé un langage autre que le C.
Ceci fonctionnera:
int *p1, i1;
i1=5;
p1 = &i1;
printf("%d,%d\n",i1,*p1);
0
yg_be Messages postés 22753 Date d'inscription lundi 9 juin 2008 Statut Contributeur Dernière intervention 4 mai 2024 1 479
Modifié le 30 mars 2022 à 16:39
Ta logique ne tient pas la route: comment peux-tu imaginer d'affecter une valeur à "*p_int", alors que "p_int" est indéterminé?
0
trocib Messages postés 6 Date d'inscription mercredi 9 juin 2021 Statut Membre Dernière intervention 19 août 2022
30 mars 2022 à 17:38
Bonjour yg_be et merci pour ta réponse.

C'est noté pour les balises "code", je n'avais pas vu la liste des différents langages.

Alors non je n'invente rien, c'est juste une réflexion qui m'évitera de faire des erreurs plus tard mais à vrai dire ce n'est pas évident d'expliquer le fond de sa pensée sur un forum.

Tout comme on peut écrire :
int age = 30;


Je pensais qu'on pouvait écrire :
int *pointeurage = 30;


Car pour moi *pointeurage c'est l'emplacement mémoire qui est pointé par le pointeur. D'ailleurs si je veux récupérer la valeur 30 j'utilise *pointeurage et non pointeurage seul qui contient en réalité l'adresse de l'entier.

Ou alors je n'ai rien compris... ce qui est fort possible. ;-)
0
[Dal] Messages postés 6175 Date d'inscription mercredi 15 septembre 2004 Statut Contributeur Dernière intervention 30 avril 2024 1 083
Modifié le 30 mars 2022 à 19:38
Lorsque tu écris :

int * pointeurage;


Tu déclares pointeurage comme étant une variable de type pointeur sur int. Dans la déclaration d'un type, l'étoile signifie "pointeur", et tu lis de droite à gauche : pointeurage est un pointeur sur int.

Une telle variable, ne peut stocker qu'une adresse mémoire. Si tu stockes 30 dedans, tu affirmes au compilateur que 30 est une adresse mémoire valide où un contenu de type int est accessible, ce qui est inexact.

L'étoile a une signification différente lorsque tu l'utilises pour déréférencer un pointeur, c'est à dire obtenir la donnée accessible indirectement grâce au pointeur. A ce moment là, l'étoile est un opérateur unaire : c'est l'opérateur d'indirection.

Lorsque tu écris :

int age = 30;
int * pointeurage = &age;
printf("âge = %d\n", *pointeurage);


En lignes 2 et 3, l'étoile a ces deux significations différentes.
1
[Dal] Messages postés 6175 Date d'inscription mercredi 15 septembre 2004 Statut Contributeur Dernière intervention 30 avril 2024 1 083 > [Dal] Messages postés 6175 Date d'inscription mercredi 15 septembre 2004 Statut Contributeur Dernière intervention 30 avril 2024
Modifié le 30 mars 2022 à 19:41
Note que, dans mon code, comme dans mes exemples ci-dessus, j'aime bien mettre un espace avant et après l'étoile lorsque je déclare un type. C'est un parallélisme de forme que je trouve intéressant, car, de la même façon, par exemple, lorsque tu déclares
unsigned int n;
tu mets un espace entre unsigned et int, qui décrivent un type C. Bref, en mettant un espace avant et après, tu traites finalement l'étoile comme un autre mot clef du langage permettant de définir un type.

En revanche, j'accole l'étoile à la variable pointeur lorsque celle-ci est utilisée comme opérateur d'indirection, accolé son opérande unique.

La présence ou absence d'espaces n'a aucune importance syntaxiquement en langage C, ces espaces étant ignorés.

C'est une question de style et d'autres programmeurs feront autrement, mais c'est à mon sens un moyen de distinguer visuellement que l'on fait deux choses différentes.

L'étoile peut aussi être utile en C comme opérateur de multiplication. Du point de vue du style d'écriture, j'aime bien mettre des espaces avant et après les opérateurs infixes (je préfère écrire
2 * 3
et non pas
2*3
). Ainsi, tu pourrais écrire
*i**j
pour multiplier le contenu pointé par les adresses stockées dans i et j. Cela fonctionne en raison des règles de préséance des opérateurs en C, mais ce n'est pas beau et pas très compréhensible.

Ecrire
*i * *j
me paraît plus clair, voire
(*i) * (*j)
bien que les espaces (et parenthèses) ne soient pas nécessaires.
1
trocib Messages postés 6 Date d'inscription mercredi 9 juin 2021 Statut Membre Dernière intervention 19 août 2022
30 mars 2022 à 20:16
Bonsoir Dal,

Ton explication est très claire, je butais sur la signification de l'* et maintenant grâce à toi je comprends mon erreur et l'avertissement généré par le compilateur.

Je suis moi aussi très attaché à un code clair et ton astuce pour ne pas se tromper (* collé ou non suivant l'usage) me convient parfaitement.

Un grand merci ! :-)
0