Recientemente decidí que finalmente tengo que aprender C / C ++, y hay una cosa que realmente no entiendo sobre los punteros o, más precisamente, su definición.
¿Qué tal estos ejemplos?
int* test;
int *test;
int * test;
int* test,test2;
int *test,test2;
int * test,test2;
Ahora, a mi entender, los primeros tres casos están haciendo lo mismo: Test no es un int, sino un puntero a uno.
El segundo conjunto de ejemplos es un poco más complicado. En el caso 4, tanto test como test2 serán punteros a un int, mientras que en el caso 5, solo test es un puntero, mientras que test2 es un int "real". ¿Y el caso 6? ¿Igual que en el caso 5?
c++
c
pointers
declaration
Michael Stum
fuente
fuente
int*test;
?Foo<Bar<char>>
el>>
tenía que estar escrito> >
para no ser tratado como un desplazamiento a la derecha.++
operador de incremento no se puede dividir por un espacio, los identificadores no se pueden dividir por un espacio (y el resultado puede ser legal para el compilador pero con un comportamiento de tiempo de ejecución indefinido). Las situaciones exactas son muy difíciles de definir considerando el desorden de sintaxis que es C / C ++.Respuestas:
4, 5 y 6 son lo mismo, solo la prueba es un puntero. Si quieres dos punteros, debes usar:
O, mejor aún (para dejarlo todo claro):
fuente
Los espacios en blanco alrededor de los asteriscos no tienen importancia. Los tres significan lo mismo:
El "
int *var1, var2
" es una sintaxis maligna que solo pretende confundir a la gente y debe evitarse. Se expande a:fuente
int*test
.int *test
( google-styleguide.googlecode.com/svn/trunk/… ).Muchas pautas de codificación recomiendan que solo declare una variable por línea . Esto evita cualquier confusión del tipo que tenía antes de hacer esta pregunta. La mayoría de los programadores de C ++ con los que he trabajado parecen ceñirse a esto.
Un poco al margen, lo sé, pero algo que encontré útil es leer las declaraciones al revés.
Esto comienza a funcionar muy bien, especialmente cuando comienzas a declarar punteros constantes y se vuelve complicado saber si es el puntero lo que es constante, o si es a lo que apunta el puntero lo que es constante.
fuente
Utilice la "Regla de la espiral en sentido horario" para ayudar a analizar las declaraciones de C / C ++;
Además, las declaraciones deben estar en declaraciones separadas cuando sea posible (lo cual es cierto la gran mayoría de las veces).
fuente
int* x;
estilo en lugar delint *x;
estilo tradicional . Por supuesto, el espaciado no le importa al compilador, pero afecta a los humanos. La negación de la sintaxis real conduce a reglas de estilo que pueden molestar y confundir a los lectores.Como otros mencionaron, 4, 5 y 6 son iguales. A menudo, la gente usa estos ejemplos para argumentar que
*
pertenece a la variable en lugar del tipo. Si bien es una cuestión de estilo, existe cierto debate sobre si debe pensar y escribirlo de esta manera:o de esta manera:
FWIW Estoy en el primer campo, pero la razón por la que otros argumentan a favor de la segunda forma es que (en su mayoría) resuelve este problema en particular:
que es potencialmente engañoso; en su lugar escribirías
o si realmente quieres dos punteros,
Personalmente, digo que lo mantenga en una variable por línea, entonces no importa qué estilo prefiera.
fuente
int *MyFunc(void)
? a*MyFunc
¿una función devuelve unint
? No. Obviamente, deberíamos escribirint* MyFunc(void)
, y decirMyFunc
es una función que devuelve aint*
. Entonces para mí esto está claro, las reglas de análisis gramatical de C y C ++ son simplemente incorrectas para la declaración de variables. deberían haber incluido la calificación de puntero como parte del tipo compartido para toda la secuencia de coma.*MyFunc()
es unint
. El problema con la sintaxis de C es mezclar la sintaxis de prefijo y sufijo ; si solo se usara el prefijo , no habría confusión.int const* x;
, que encuentro tan engañosas comoa * x+b * y
.fuente
#include <windows.h>LPINT test, test2;
En 4, 5 y 6,
test
siempre es un puntero ytest2
no es un puntero. El espacio en blanco (casi) nunca es significativo en C ++.fuente
En mi opinión, la respuesta es AMBAS, dependiendo de la situación. Generalmente, en mi opinión, es mejor poner el asterisco al lado del nombre del puntero, en lugar del tipo. Compare, por ejemplo:
¿Por qué el segundo caso es inconsistente? Porque, por ejemplo,
int x,y;
declara dos variables del mismo tipo pero el tipo se menciona solo una vez en la declaración. Esto crea un precedente y un comportamiento esperado. Yint* pointer1, pointer2;
es inconsistente con eso porque se declarapointer1
como un puntero, peropointer2
es una variable entera. Claramente propenso a errores y, por lo tanto, debe evitarse (colocando el asterisco al lado del nombre del puntero, en lugar del tipo).Sin embargo , existen algunas excepciones en las que es posible que no pueda colocar el asterisco junto al nombre de un objeto (y dónde importa dónde lo ponga) sin obtener un resultado no deseado, por ejemplo:
MyClass *volatile MyObjName
void test (const char *const p) // const value pointed to by a const pointer
Finalmente, en algunos casos, podría decirse que sería más claro poner el asterisco al lado del nombre del tipo , por ejemplo:
void* ClassName::getItemPtr () {return &item;} // Clear at first sight
fuente
El fundamento de C es que declaras las variables de la forma en que las usas. Por ejemplo
dice que
*a[42]
será unchar
. Ya[42]
un puntero de char. Y asía
es una matriz de punteros char.Esto porque los escritores del compilador original querían usar el mismo analizador para expresiones y declaraciones. (No es una razón muy sensata para elegir un diseño de idioma)
fuente
char* a[100];
también deduce que*a[42];
será un puntero de carácterchar
ya[42];
carácter.a[42]
es unchar
puntero y*a[42]
es un carácter.Yo diría que la convención inicial era poner la estrella en el lado del nombre del puntero (lado derecho de la declaración
en el lenguaje de programación c de Dennis M. Ritchie, las estrellas están en el lado derecho de la declaración.
Al mirar el código fuente de Linux en https://github.com/torvalds/linux/blob/master/init/main.c podemos ver que la estrella también está en el lado derecho.
Puede seguir las mismas reglas, pero no es un gran problema si coloca estrellas en el lado de la letra. Recuerda que la consistencia es importante, por eso siempre pero la estrella del mismo lado independientemente del lado que hayas elegido.
fuente
El puntero es un modificador del tipo. Es mejor leerlos de derecha a izquierda para comprender mejor cómo el asterisco modifica el tipo. 'int *' se puede leer como "puntero a int '. En declaraciones múltiples, debe especificar que cada variable es un puntero o se creará como una variable estándar.
1, 2 y 3) La prueba es de tipo (int *). El espacio en blanco no importa.
4, 5 y 6) La prueba es de tipo (int *). Test2 es de tipo int. Nuevamente, el espacio en blanco es intrascendente.
fuente
Como regla general, mucha gente parece comprender estos conceptos de la siguiente manera: En C ++, una gran cantidad de significado semántico se deriva de la unión a la izquierda de palabras clave o identificadores.
Toma por ejemplo:
La constante se aplica a la palabra "int". Lo mismo ocurre con los asteriscos de los punteros, se aplican a la palabra clave que queda a la izquierda de ellos. ¿Y el nombre de la variable real? Sí, eso lo declara lo que queda de él.
fuente