Je travaillais sur une fonction où je voulais transmettre un paramètre en tant que pointeur et affecter sa valeur dans la fonction. Je suis arrivé à une solution avec un pointeur sur un pointeur et utiliser un pointeur seul. Il a fait gratter ma tête quand un pointeur à un pointeur doit être requis si un pointeur peut agir exactement la même chose lors de l'attribution de la valeur d'un pointeur à partir d'un paramètre?
Afficher mon code d'exemple ci-dessous. P>
// pointers.c
void foo(int *f) {
*f = 1;
}
void bar(int **f) {
int y = 2;
int *temp = &y;
(*f) = temp;
}
void baz(int *f) {
int y = 3;
int *temp = &y;
f = temp;
}
int main(int argc, char const *argv[]) {
int j = 0;
int *num = &j;
printf("%d\n", *num);
foo(num);
printf("%d\n", *num);
bar(&num);
printf("%d\n", *num);
baz(num);
printf("%d\n", *num);
return 0;
}
$ gcc pointers.c -o pointers -Wall && ./pointers
0
1
2
3
3 Réponses :
C'est tout ce qui est brisé. Votre programme pas strong> indique que La variable Alors, pourquoi l'impression Vous devez vraiment utiliser un pointeur vers le pointeur pour affecter baz () code> fonctionne comme vous le souhaitez. Il semble seulement à cause d'une autre briseur. P>
y code> dans bar () code> est local à celui-ci. Et son stockage ne sont valables que lors de l'exécution de la barre () code>. Après bar () code> complète, y code> n'est plus valide et n'est pas son stockage. Et pourtant, vous avez fait num code> point sur ce stockage. Cela entraînera un comportement indéfini. Il s'agit simplement de faire des hasard que le stockage n'était pas réutilisé ou écrasé et continue de tenir 2 au moment où vous imprimez sa valeur. P>
BAZ () code> n'affecte pas ce que num code> pointe vers. f code> dans cette fonction est un paramètre et donc local à baz () code>. L'affectation à f code> n'affecte que celle locale. P>
* num code> après avoir appelé baz () code> produire "3"? Parce que num code> indique toujours sur le stockage de y code> à partir de l'appel à bar () code> et l'appel à baz () code > Ouvrez ce stockage avec 3. Encore une fois, c'est le hasard et ne peut pas être invoqué. P>
num code>, comme vous l'avez fait dans bar () code>. Mais vous ne devez pas utiliser les pointeurs vers les locaux après votre retour de leur portée. P>
D'accord, il semble que mon code a beaucoup de défauts dedans. Merci de pointer ceux-ci, mais de retour à la question quand est-ce que j'ai besoin d'un double pointeur? J'ai vu des méthodes telles que Strcpy attribuer la valeur d'un paramètre à l'aide d'un pointeur. Est-ce la bonne façon?
Également basé sur votre réponse, qu'en est-il de la méthode foo? Est-ce que quelque chose ne va pas avec ça? Est-ce que cela attribue en réalité numériquement?
foo () code> attribue via f code> (qui est le même pointeur que num code>) sur j code>. Il ne change pas num code> lui-même. De même, Strcpy () Code> écrit via le pointeur de destination sur le tableau de caractères qu'il pointe, mais ne change pas le pointeur de destination lui-même. Les paramètres de la fonction sont toujours des copies locales de tout ce que l'appelant a passé. La fonction peut modifier leur valeur, mais cela ne change que la copie locale.
Si vous souhaitez que une fonction modifie une variable de l'appelant, vous devez transmettre un pointeur sur cette variable et écrire dans le pointeur. Si la variable de l'appelant est elle-même un pointeur, vous avez besoin d'un pointeur sur un pointeur.
Une fois la recherche dans Stackoverflow, j'ai constaté qu'un pointeur sur un pointeur est requis comme paramètre de fonction lorsque vous souhaitez modifier ce qu'un pointeur pointe dans une fonction. p>
J'ai trouvé les liens suivants Modifier où un pointeur pointe dans une fonction et Adressechanging Adresse contenue par le pointeur à l'aide de la fonction p>
c n'a pas de passe par référence, de sorte qu'il fonctionne comme ci-dessous: em> p>
Un pointeur est simplement une variable normale qui contient l'adresse de quelque chose d'autre comme valeur. Si vous passez un pointeur initialisé sur une fonction, la fonction reçoit une copie du pointeur qui détient l'adresse d'origine comme valeur. Vous pouvez modifier la valeur de l'adresse de la mémoire détenue par le pointeur en le déséroferce et attribuant une nouvelle valeur à cette adresse mémoire. Tout autre pointeur qui pointe sur cette adresse mémoire pointe également sur la nouvelle valeur. Cela fonctionne pour la valeur pointée par le pointeur, mais vous ne pouvez pas modifier l'adresse du pointeur lui-même (rappelez-vous que ce n'est qu'une copie du pointeur d'origine avec son adresse propre et très différente locale à la fonction, tout changement à la fonction. L'adresse du pointeur lui-même sera perdue sur le retour de la fonction) P>
Pour changer le pointeur lui-même dans une fonction (telle que lorsque vous realloc code>, etc.), vous devez transmettre l'adresse de em> le pointeur en tant que paramètre. Par exemple. FOO (& the_Pointer) CODE> Le paramètre de fonction doit être un pointeur à pointeur em> (par exemple un double pointeur). Il suit la même sémantique, mais vous passez maintenant l'adresse de em> le pointeur par valeur. Vous êtes alors libre de modifier l'adresse du pointeur en attribuant la nouvelle adresse de pointeur au pointeur déréférencé dans la fonction. Le changement sera ensuite visible dans la fonction d'appel. p>
Je pourrais avoir certains de mes détails incorrects afin de modifier ou de mettre à jour pour effectuer des corrections.
J'ai modifié le contenu un peu pour être plus concis.
Il y a plusieurs utilisations de Double, Triple, ... Pointeurs dans 'C'. Extrapoler votre exemple, le double pointeur peut être utilisé pour affecter une valeur à un pointeur transmis à une fonction sous forme de paramètre.
Donc, si vous prenez votre fonction dans l'exemple ci-dessus, la fonction Cependant, votre problème est que dans votre exemple, vous l'affectez un pointeur qui n'est valable que dans la fonction. Lorsque la fonction renvoie, Ce comportement peut être utilisé pour renvoyer un pointeur à une mémoire allouée de manière dynamique ou à une variable statique, c'est-à-dire p> Dans cet exemple, TMP sera attribué à un pointeur pour une mémoire allouée de manière dynamique, qui persistera qu'on utilise un bar code>, il y a une partie du Utilisation dedans: p> la barre code> affecterait une valeur au pointeur PTR, qui peut être utilisée ultérieurement dans la principale . P> PTR code> serait attribué une valeur, car elle existait à l'intérieur de la fonction, mais elle pointera une valeur non valide. Le comportement du programme ne sera pas défini à ce stade. P> gratuit code>. Vous pouvez attribuer une valeur de TMP code> à * f code> et l'utiliser ultérieurement int il principal code>. Il existe également des utilisations pour les variables statiques ou globales, qui persistent après le retour de la fonction. p> p>
Votre code provoque un comportement non défini,
Barcode> EnsemblesNuméro CODE> Pour pointer vers un int qui est détruitIl n'y a qu'un seul cas où un pointeur à un pointeur est requis i> et vous l'avez dans votre code.
Char * Argv [] Code> est juste une autre façon d'exprimerChar ** argv code> (lorsqu'il est utilisé comme paramètre), et c'est le seul moyen de prendre des arguments de ligne de commande. (Bien entendu, de nombreux autres cas dans lesquels un pointeur d'un pointeur est utile i>.)