Déclarer et initialiser le pointeur de manière concise (c’est-à-dire pointeur vers int)

Compte tenu des pointeurs à char, on peut faire ce qui suit:

char *s = "data"; 

Pour autant que je sache, une variable de pointeur est déclarée ici, de la mémoire est allouée à la fois pour la variable et les données, ces dernières sont remplies de data\0 et la variable en question est définie pour pointer vers le premier octet (la variable contient un adresse pouvant être référencée). C’est court et compact.

Donnons des pointeurs à int, par exemple, on peut faire ceci:

 int *i; *i = 42; 

ou ça:

 int i = 42; foo(&i); // prefix every time to get a pointer bar(&i); baz(&i); 

ou ça:

 int i = 42; int *p = &i; 

C’est un peu tautologique. C’est petit et tolérable avec une utilisation d’une seule variable. Ce n’est pas avec des utilisations multiples de plusieurs variables, cependant, produisant du fouillis de code.

Existe-t-il un moyen d’écrire la même chose de manière concise et à sec? Que sont-ils? Existe-t-il des approches plus larges en matière de programmation permettant d’éviter complètement le problème? Peut-être que je ne devrais pas utiliser de pointeurs du tout (blague) ou quelque chose?

Les littéraux de chaîne constituent un cas d’école: ils déclenchent la création du littéral en mémoire statique et son access sous forme de tableau de caractères. Notez que ce qui suit ne comstack pas, bien que 42 soit un littéral int , car il n’est pas implicitement alloué:

 int *p = &42; 

Dans tous les autres cas, vous êtes responsable de l’affectation de l’object pointé, que ce soit en mémoire automatique ou dynamic.

 int i = 42; int *p = &i; 

Ici, i une variable automatique, et p pointe vers elle.

 int * i; *i = 42; 

Vous venez d’appeler le comportement indéfini. i n’ai pas été initialisé, et pointe donc quelque part au hasard dans la mémoire. Ensuite, vous avez affecté 42 à cet emplacement aléatoire, avec des conséquences imprévisibles. Mal.

 int *i = malloc(sizeof *i); 

Ici, i initialisé pour pointer sur un bloc de mémoire alloué dynamicment. N’oubliez pas de free(i) une fois que vous avez terminé.

 int i = 42, *p = &i; 

Et voici comment vous créez une variable automatique et un pointeur sur celle-ci sous la forme d’une ligne. i est la variable, p pointe vers elle.

Edit: vous semblez vraiment vouloir que cette variable soit allouée de manière implicite et anonyme. Eh bien, voici comment vous pouvez le faire:

 int *p = &(int){42}; 

Ce truc est un littéral composé. Ce sont des instances anonymes avec une durée de stockage automatique (ou statique au niveau du fichier), et n’existent que dans C90 et les versions ultérieures (mais pas C ++!). Contrairement aux littéraux de chaîne, les littéraux composés sont modifiables, ce qui signifie que vous pouvez modifier *p .

Edit 2: Ajout de cette solution inspirée d’ une autre réponse (qui a malheureusement fourni une explication erronée) pour compléter:

 int i[] = {42}; 

Cela allouera un tableau mutable à un élément avec une durée de stockage automatique. Le nom du tableau, bien qu’il ne s’agisse pas d’un pointeur , se décomposera en un pointeur si nécessaire.

Notez cependant que sizeof i renverra le résultat “incorrect”, à savoir la taille réelle du tableau ( 1 * sizeof(int) ) au lieu de la taille d’un pointeur ( sizeof(int*) ). Cela devrait cependant rarement être un problème.

vous pouvez aussi le penser comme un tableau, int i[1]={42} où i est un pointeur sur int

 int * i; *i = 42; 

invoquera un comportement indéfini. Vous modifiez un emplacement de mémoire inconnu. Vous devez d’abord initialiser le pointeur i .

 int i = 42; int *p = &i; 

est la bonne façon. Maintenant, p pointe vers i et vous pouvez modifier la variable pointée par p .

Existe-t-il un moyen d’écrire la même chose de manière concise et à sec?

Comme il n’ya pas de passage par référence en C, vous devez utiliser des pointeurs lorsque vous souhaitez modifier la variable transmise dans une fonction.

Existe-t-il des approches plus larges en matière de programmation permettant d’éviter complètement le problème? Peut-être que je ne devrais pas utiliser de pointeurs du tout (blague) ou quelque chose?

Si vous apprenez le C, vous ne pouvez pas éviter les pointeurs et vous devez apprendre à l’utiliser correctement.

 int i=42; int *ptr = &i; 

cela équivaut à écrire

 int i=42; int *ptr; ptr=&i; 

C’est difficile, c’est vraiment déroutant, mais lors d’appels de fonction, c’est très utile comme:

 void function1() { int i=42; function2(&i); } function2(int *ptr) { printf("%d",*ptr); //outputs 42 } 

ici, nous pouvons facilement utiliser cette notation déroutante pour déclarer et initialiser le pointeur pendant les appels de fonction. Nous n’avons pas besoin de déclarer le pointeur globalement, et l’initialiser lors d’appels de fonction. Nous avons une notation pour faire les deux en même temps.

 int *ptr; //declares the pointer but does not initialize it //so, ptr points to some random memory location *ptr=42; //you gave a value to this random memory location 

Bien que cela comstack, il invoque un comportement non défini car vous n’avez jamais initialisé le pointeur.

Également,

 char *ptr; char str[6]="hello"; ptr=str; 

EDIT: comme indiqué dans les commentaires, ces deux cas ne sont pas équivalents. Mais le pointeur pointe sur “bonjour” dans les deux cas. Cet exemple est écrit uniquement pour montrer que nous pouvons initialiser les pointeurs de ces deux manières (pour pointer vers hello), mais que les deux sont clairement différents à bien des égards.

 char *ptr; ptr="hello"; 

As, nom de chaîne, str est en fait un pointeur sur le 0ème élément de chaîne, c’est-à-dire ‘h’. Il en va de même pour tout tableau arr [], où arr contient l’adresse du 0ème élément.