Je vous préviens tout de suite, ce qui suit est de la grosse question de newbie.
Alors voilà. J'arrive à faire quelques trucs en C, utiliser libcurl par exemple, mais j'ai toujours cette sale impression de ne pas bien saisir la notion de pointeur. Vos explications seront les bienvenues.
Considérant le code suivant :
#include <stdio.h>
void add (int a, int b, int *c)
{
*c=a+b;
}
int main()
{
int a = 4;
int b = 2;
int c = 0;
add (a, b, &c);
printf ("c = %i\n", c);
return (0);
}
La sortie standard me sort « c = 6 »
Est-ce que la bonne manière d'interpréter :
*c=a+b
est de dire c
pointera sur l'entier résultat de a+b
J'ai honte…
# Nop
Posté par phoenix (site web personnel) . Évalué à 0.
Non la traduction plus juste serait de dire que le la valeur associée au pointeur
c
contient la valeura+b
.Soit
c
un pointeur,*c
représente la valeur pointée par le pointeur.Alors que
&variable
représente la case mémoire (le pointeur) qui contient la valeur.Donc
&(*c) == c
.Est-ce plus clair ?
Dire
c
pointera sur l'entier résultat dea+b
ressemblerai plus à :Mais sans avoir tester la syntaxe, le problème est que la valeur résultat risque d'être déférencer et donc
c
pointera une case non valide en mémoire.[^] # Re: Nop
Posté par max22 . Évalué à 1.
Avec la dernière syntaxe c=&(a+b) ça ne peut pas marcher car cela n'aura aucun effet sur le contenu de c dans la fonction main.
et on ne peut pas obtenir l'adresse de (a+b). on ne peut obtenir l'adresse que des variables et des fonctions.
[^] # Re: Nop
Posté par phoenix (site web personnel) . Évalué à 2.
Oui merci, je m'en doutais un peu (je n'avais pas tester la syntaxe). J'avais mis cette phrase plus pour indiquer à quoi ressemblerai " est de dire
c
pointera sur l'entier résultat dea+b
"# Adresse mémoire
Posté par Obsidian . Évalué à 4.
Bonjour,
Pas tout-à-fait : l'expression en question doit plutôt être lue « ce qui est pointé par c va recevoir le résultat de a+b. ».
Un pointeur est une variable qui contient une adresse en mémoire. Le format de celle-ci est donc dépendant de l'architecture sur laquelle tu travaille mais, a contrario, sera complètement indépendant de la donnée qui se trouve à cette adresse.
Quand tu passes des arguments à une fonction, ceux-ci se retrouvent dans la pile et sont gérés comme s'il s'agissait de variables locales. Ainsi, mais si elles portent le même nom, les variables « a », « b » et « c » de ta fonction add sont complètement indépendantes de celle de ta fonction main et, par conséquent, les arguments en langage C sont toujours transmis par COPIE.
Mais dans le cas présent, ce que tu passes en troisième paramètre est littéralement « l'adresse de la variable c ». Puisque « c » est un entier, l'information en question est donc forcément un « pointeur sur un entier », d'où la manière de rédiger le prototype de add.
Passer à une fonction l'adresse d'une variable extérieure à cette fonction lui permet donc d'écrire dedans, entre autres.
# Merci
Posté par Marotte ⛧ . Évalué à 2.
Merci pour vos explications.
J'ai effectivement utilisé a, b et c comme noms de variables en ayant bien conscience que le a de main() n'est pas le a de add()…
Je crois que j'ai compris.
Sauf :
Bon, c'est « testé » et « déréférencé » ? Mais pourquoi c pointerait sur une « case non valide » ?
[^] # Re: Merci
Posté par Zylabon . Évalué à 3.
Please do not feed the trolls
[^] # Re: Merci
Posté par Renault (site web personnel) . Évalué à 2.
Encore plus con.
Prend un pointeur non initialisé et fait des opération avec.
En C, les variables non initialisées peuvent avoir n'importe qu'elle valeur suivant l'état de la RAM à ce moment là. Si ton pointeur non initialisé contient une adresse ou une valeur qui rend l'opération non valide, c'est le crash garantie.
[^] # Re: Merci
Posté par max22 . Évalué à 1.
Dans l'exemple que tu as donné il n'y a pas de souci de "case non valide".
[^] # Re: Merci
Posté par Marotte ⛧ . Évalué à 2.
Oui c'est bien ce que je pensais, tu confirmes et je t'en remercie. Je pense que j'ai bien compris avec l'exemple de Zylabon.
# un petit dessin
Posté par Zylabon . Évalué à 5. Dernière modification le 23 octobre 2013 à 18:58.
Ça c'est de la mémoire, avec une valeur c quelque part
À l'adresse 3, je vais mettre un pointeur sur c :
Si j'appelle la fonction add avec
add(2,4,6);
, add va calculer 2 + 4 et écrire le résultat à l'adresse désignée par son dernier argument, à savoir 6.Voir le code assembleur aide à comprendre :
En assembleur x86, les opération binaire sont toutes de la forme a+=b, en assembleur addl b,a
Et ce qu'on écrit f[45] en c s'écrit 45(f) en assembleur (f) est équivalent à *f
Please do not feed the trolls
# référence
Posté par max22 . Évalué à 1.
Sinon, pour chipoter sur le titre, il n'y a pas de références en C. Il n'y a que des pointeurs. Les références c'est en C++.
[^] # Re: référence
Posté par Krunch (site web personnel) . Évalué à 2.
Un pointeur étant une référence, si. On peut même faire des référence qui ne sont pas des pointeurs en C (genre un offset de struct ou un index de tableau).
http://en.wikipedia.org/wiki/Reference_(computer_science)
pertinent adj. Approprié : qui se rapporte exactement à ce dont il est question.
Suivre le flux des commentaires
Note : les commentaires appartiennent à celles et ceux qui les ont postés. Nous n’en sommes pas responsables.