J'ai récemment décidé que je devais enfin apprendre le C / C ++, et il y a une chose que je ne comprends pas vraiment à propos des pointeurs ou plus précisément de leur définition.
Que diriez-vous de ces exemples:
int* test;
int *test;
int * test;
int* test,test2;
int *test,test2;
int * test,test2;
Maintenant, à ma connaissance, les trois premiers cas font tous la même chose: Test n'est pas un int, mais un pointeur vers un.
Le deuxième ensemble d'exemples est un peu plus délicat. Dans le cas 4, test et test2 seront tous deux des pointeurs vers un int, tandis que dans le cas 5, seul test est un pointeur, tandis que test2 est un int "réel". Et le cas 6? Identique au cas 5?
c++
c
pointers
declaration
Michael Stum
la source
la source
int*test;
?Foo<Bar<char>>
le>>
devait être écrit> >
pour ne pas être traité comme un décalage à droite.++
opérateur d' incrémentation ne peut pas être divisé par un espace, les identificateurs ne peuvent pas être divisés par un espace (et le résultat peut être encore légal pour le compilateur mais avec un comportement d'exécution non défini). Les situations exactes sont très difficiles à définir compte tenu du désordre de syntaxe qu'est C / C ++.Réponses:
4, 5 et 6 sont la même chose, seul le test est un pointeur. Si vous voulez deux pointeurs, vous devez utiliser:
Ou, encore mieux (pour que tout soit clair):
la source
Les espaces blancs autour des astérisques n'ont aucune signification. Les trois signifient la même chose:
Le "
int *var1, var2
" est une mauvaise syntaxe qui est juste destinée à semer la confusion et doit être évitée. Il s'étend à:la source
int*test
.int *test
( google-styleguide.googlecode.com/svn/trunk/… ). Soyez cohérentDe nombreuses directives de codage recommandent de ne déclarer qu'une seule variable par ligne . Cela évite toute confusion comme celle que vous aviez avant de poser cette question. La plupart des programmeurs C ++ avec lesquels j'ai travaillé semblent s'en tenir à cela.
Un petit aparté, je sais, mais quelque chose que j'ai trouvé utile est de lire les déclarations à l'envers.
Cela commence à très bien fonctionner, en particulier lorsque vous commencez à déclarer des pointeurs const et qu'il devient difficile de savoir si c'est le pointeur qui est const, ou si c'est la chose sur laquelle le pointeur pointe est const.
la source
Utilisez la «règle de la spirale dans le sens des aiguilles d'une montre» pour aider à analyser les déclarations C / C ++;
En outre, les déclarations doivent être dans des déclarations séparées lorsque cela est possible (ce qui est vrai la grande majorité des fois).
la source
int* x;
style plutôt qu'auint *x;
style traditionnel . Bien sûr, l'espacement n'a pas d'importance pour le compilateur, mais il affecte les humains. Le refus de la syntaxe réelle conduit à des règles de style qui peuvent ennuyer et dérouter les lecteurs.Comme d'autres l'ont mentionné, 4, 5 et 6 sont identiques. Souvent, les gens utilisent ces exemples pour faire valoir que le
*
appartient à la variable au lieu du type. Bien que ce soit une question de style, il y a un débat pour savoir si vous devriez penser et l'écrire de cette façon:ou de cette façon:
FWIW Je suis dans le premier camp, mais la raison pour laquelle d'autres font valoir la deuxième forme est qu'elle résout (principalement) ce problème particulier:
ce qui est potentiellement trompeur; à la place vous écririez soit
ou si vous voulez vraiment deux pointeurs,
Personnellement, je dis de le garder à une variable par ligne, alors peu importe le style que vous préférez.
la source
int *MyFunc(void)
? une*MyFunc
fonction renvoie-int
t-elle un ? non. Évidemment, nous devrions écrireint* MyFunc(void)
, et direMyFunc
est une fonction retournant unint*
. Donc, pour moi, c'est clair, les règles d'analyse grammaticale C et C ++ sont tout simplement fausses pour la déclaration de variable. ils auraient dû inclure la qualification de pointeur dans le cadre du type partagé pour toute la séquence de virgules.*MyFunc()
c'est unint
. Le problème avec la syntaxe C est de mélanger la syntaxe de préfixe et de suffixe - si seulement postfix était utilisé, il n'y aurait pas de confusion.int const* x;
, que je trouve aussi trompeusesa * x+b * y
.la source
#include <windows.h>LPINT test, test2;
En 4, 5 et 6,
test
est toujours un pointeur ettest2
non un pointeur. L'espace blanc n'est (presque) jamais significatif en C ++.la source
À mon avis, la réponse est LES DEUX, selon la situation. Généralement, l'OMI, il est préférable de mettre l'astérisque à côté du nom du pointeur, plutôt que le type. Comparez par exemple:
Pourquoi le deuxième cas est-il incohérent? Parce que par exemple
int x,y;
déclare deux variables du même type mais le type n'est mentionné qu'une seule fois dans la déclaration. Cela crée un précédent et un comportement attendu. Etint* pointer1, pointer2;
est incompatible avec cela car il se déclarepointer1
comme un pointeur, maispointer2
est une variable entière. Clairement sujet aux erreurs et, par conséquent, doit être évité (en plaçant l'astérisque à côté du nom du pointeur, plutôt que du type).Cependant , il existe certaines exceptions où vous ne pourrez peut-être pas placer l'astérisque à côté d'un nom d'objet (et où cela importe où vous le mettez) sans obtenir un résultat indésirable - par exemple:
MyClass *volatile MyObjName
void test (const char *const p) // const value pointed to by a const pointer
Enfin, dans certains cas, il peut être plus clair de placer l'astérisque à côté du nom du type , par exemple:
void* ClassName::getItemPtr () {return &item;} // Clear at first sight
la source
La logique en C est que vous déclarez les variables comme vous les utilisez. Par exemple
dit que ce
*a[42]
sera unchar
. Eta[42]
un pointeur char. Et ainsia
est un tableau de pointeurs char.Ceci parce que les auteurs du compilateur d'origine voulaient utiliser le même analyseur pour les expressions et les déclarations. (Ce n'est pas une raison très raisonnable pour un choix de conception de langage)
la source
char* a[100];
également que ce*a[42];
sera un pointeurchar
eta[42];
un caractère.a[42]
s'agit d'unchar
pointeur et d'*a[42]
un caractère.Je dirais que la convention initiale était de mettre l'étoile du côté du nom du pointeur (côté droit de la déclaration
dans le langage de programmation c par Dennis M. Ritchie, les étoiles sont sur le côté droit de la déclaration.
en regardant le code source de Linux sur https://github.com/torvalds/linux/blob/master/init/main.c, nous pouvons voir que l'étoile est également sur le côté droit.
Vous pouvez suivre les mêmes règles, mais ce n'est pas grave si vous mettez des étoiles du côté du type. N'oubliez pas que la cohérence est importante, donc toujours mais l'étoile du même côté quel que soit le côté que vous avez choisi.
la source
Le pointeur est un modificateur du type. Il est préférable de les lire de droite à gauche afin de mieux comprendre comment l'astérisque modifie le type. «int *» peut être lu comme un «pointeur vers int». Dans plusieurs déclarations, vous devez spécifier que chaque variable est un pointeur ou elle sera créée comme une variable standard.
1,2 et 3) Le test est de type (int *). L'espace n'a pas d'importance.
4,5 et 6) Le test est de type (int *). Test2 est de type int. Encore une fois, les espaces sont sans importance.
la source
En règle générale, beaucoup de gens semblent saisir ces concepts par: En C ++, une grande partie de la signification sémantique est dérivée par la liaison à gauche de mots-clés ou d'identificateurs.
Prends pour exemple:
Le const s'applique au mot "int". La même chose est avec les astérisques des pointeurs, ils s'appliquent au mot-clé à gauche d'eux. Et le nom réel de la variable? Oui, c'est déclaré par ce qu'il en reste.
la source