2009-02-17 20 views
24

Duplicar posible:
In C, why is the asterisk before the variable name, rather than after the type?¿Qué tiene más sentido: char * string o char * string?

estoy aprendiendo C++ en este momento, y yo estoy viniendo a través de una gran cantidad de cadenas terminadas en cero. Esto me tiene pensando, lo que tiene más sentido cuando se declara punteros:

char* string 

o

char *string 

? Para mí, el formato char * tiene más sentido, porque el tipo de "cadena" es un puntero a un char, en lugar de un char. Sin embargo, generalmente veo el último formato. Esto también se aplica a las referencias, obviamente.

¿Podría alguien decirme si hay una razón lógica para este último formato?

+0

@quant_dev: Sí, esa fue mi idea también. – Shog9

+0

std :: wstring, por supuesto. –

+0

El primer formato tiene más sentido. Estás declarando una variable llamada 'cadena' que tiene un tipo de 'char *', no una variable llamada '* cadena' que tiene un tipo de 'char'. Las personas analizan intuitivamente el código a lo largo de los límites del espacio en blanco, por lo que es razonable formatear el código para que se lea de manera significativa cuando se analiza de esa manera. Por supuesto, las respuestas a continuación explican por qué a veces se usa la convención contraintuitiva. – aroth

Respuesta

51

En la siguiente declaración:

char* string1, string2; 

string1 es un puntero carácter, pero string2 es sólo un único carácter. Por esta razón, la declaración es por lo general el mismo formato que:

char *string1, string2; 

que hace que sea un poco más claro que el * se aplica a string1 pero no string2. Una buena práctica es evitar declarar múltiples variables en una declaración, especialmente si algunas de ellas son punteros.

+3

En mi humilde opinión esto no debe considerarse como LA buena respuesta. Teniendo en cuenta que: - Estamos hablando de C++ - El tipo es char * - La variable que pasará es "cadena", y rara vez "* cadena". - Una variable debe declararse lo más tarde posible, por lo que, por definición, no está en la misma línea que otra. - Bjarne dice: "Un programador típico de C++ escribe int * p ... claramente prefiero ese énfasis y lo veo como importante para usar bien las partes más avanzadas de C++. - const char * const string Luego, las cadenas * char hace definitivamente más sentido. Prefiero char * string, para mayor claridad – Jem

+2

No me parece en ninguna ocasión sensato declarar variables de diferente tipo en la misma línea. – Chiel

+4

Esto es una tontería. ¿Por qué todos se obsesionan con esto? borde de la caja ?! Hay factores mucho más importantes a considerar al decidir cómo alinear sus asteriscos. –

2

dado que puede hacer varias declaraciones en una sola línea, tiene más sentido para mí que pertenezca a la variable en lugar del tipo, p. Ej.

char *pString, arrString[20]; 
+2

No lo creo, es una buena cosa que hacer ... no muy legible – Tim

+0

menos propenso a errores ya que el tipo corresponde a la variable, independientemente de su legibilidad – Simon

2

Yo también creo que el char * foo tiene más sentido cuando se declara una sola variable.

La única vez que uso el otro formato es al declarar múltiples variables en una sola línea, tales como:

char * foo, bar;

33

Bjarne Stroustrup tiene something to say about this:

La confusión fundamental viene (sólo) cuando la gente trata de declarar varios punteros con una sola declaración:

int* p, p1; // probable error: p1 is not an int* 
+0

Brillante! Stroustrup está de acuerdo conmigo! Gracias. – Skilldrick

+0

Esto es cómo me he sentido siempre al respecto. –

+2

Si se desplaza por las preguntas frecuentes de Stroustup, es interesante ver qué estilo de puntero utiliza en realidad en su propio código. – otto

4

En C++ que tiene sentido para poner el * en el identificador de tipo como char *, ya que es parte del tipo en sí.

Pero si define múltiples variables en la misma declaración, esto se vuelve ambiguo y engañoso.

char* foo, bar; 

Mientras foo tiene el tipo char * now, bar tiene el tipo char.Por lo tanto, muchas personas prefieren

char *foo, bar; 

para dejar esto en claro.

2

Personalmente, nunca declaro múltiples variables en una línea.

Debido a eso y el hecho de que yo realmente encontrar patrones agradable, creo que este modelo simple abrogación:

type varname 

Esto significa que casi siempre digo int [] iArray o int * piArray (o cualquiera que sea el húngaro la notación sería, no he usado C++ en una década).

Esto también significa que nunca uso int iArray [], ya que el hecho de que sea una matriz es parte del tipo, no del nombre de la variable.

Pensar de esta manera también me ha ayudado a simplificar las definiciones.

Sólo ofreciendo otra POV

+1

"_No he usado C++ en una década_" ¿Has estado usando Java por casualidad? 'int [] iArray' es la sintaxis de Java. – curiousguy

3

En la mayoría de los casos, std::string str es mucho más preferible a una char *.

Dicho esto, generalmente hago algo como DataType * ptr, para hacer que el * se destaque mejor. O, con mucha más frecuencia, std::tr1::smart_ptr<DataType> ptr, o quizás un auto_ptr.

De manera simple, los punteros crudos son peligrosos de usar de varias maneras, y si voy a usar uno, quiero que se destaque.

3

Me gusta mucho el modismo "char* foo", porque pone toda la información sobre el tipo de variable en un solo lugar. "char *foo" puede ser bastante confuso si la parte "*foo" está tabulada en la mitad de la pantalla.

Por otro lado, estoy de acuerdo con otros carteles que es confuso cuando se declaran múltiples variables en una línea. Intento no mezclar tipos cuando declaro múltiples variables en una línea, y char y char* son tipos separados en mi mente, por lo que esa situación particular no es la que probablemente ocurriría en mi código.

+1

El problema es que el sistema de tipo C no funciona de esa manera, sino que coloca la variable o tipo declarado en el medio. Solo intenta declarar una matriz o un puntero a una función. – starblue

+0

Sí, es verdad: mi filosofía no es aplicable en todas partes en C/C++, desafortunadamente. Pero me gusta declarar punteros y referencias de esa manera, para mayor claridad. – MattK

3

Mi respuesta: no, se debe utilizar:

char * string; 

considerar, si Dennis Ritchie (diseñador del lenguaje C) en lugar de utilizar el carácter '*' había usado un 'PTR' palabra clave, lo haría todos tienen que estar diciendo:

char ptr string; 

y no tener estas discusiones.

También es, en mi humilde opinión, más legible.

+5

No me gusta porque se parece más al operador de multiplicación ... – Skilldrick

6

(std :: string es mejor que char * para la mayoría de usos.)

siempre pongo el * con el tipo, al igual que en char * porque, as Stroustrup noted, esto enfatiza el tipo.

Y nunca declaro variables juntas en una línea para evitar el gotcha común discutido en las respuestas aquí;

char* p, q; // oops, probably not what was meant 
// this is mandated by our style guide: 
char* p; 
char* q; 
7

Lo que hasta ahora nadie ha mencionado es que el siguiente

char *string 

también se puede leer como la que se declara el tipo de la expresión *string (es decir: el operador de indirección aplica al puntero string) como char. Desde este punto de vista, la notación es perfectamente razonable.

Dicho esto, yo uso

char * string 

mí mismo;)

+1

"Dicho esto, uso char * string" - Yo también comencé a converger en este formato después de considerar tanto el 'char *' como 'char *' formatos y no estaba contento con ninguno de ellos ... – stefanB

+0

+1, interpretación útil de sintaxis confusa! – shambulator

0

La primera sugerencia (de char * var) estaría bien, siempre y cuando, además de manifestar una sola variable por línea, pero personalmente , Prefiero el "char * var"; y una sola variable por línea: puede alargar la función en el recuento de líneas, pero es muy clara.

Finalmente, C++ debe usar "var cadena", pero siempre terminamos heredando código con "char *" o teniendo que conectarnos a bibliotecas que no son de C++.

12

Técnicamente, tiene sentido para escribir

char *f 

Debido *f es el declarador en que, mientras que el char es el especificador declaración que especifica un tipo básico de todos los declaradores. Los declaradores contienen operadores como (), [] y & que pueden pensarse en modificar el tipo de base y el identificador real.

utilizo el formulario de arriba de poner * al identificador, ya que hace hincapié en que en realidad es el *f declarador, mientras char es el tipo básico.

Hasta cierto punto, se puede pensar en los modificadores en un declarador para hacer el tipo en el especificador de declaración cuando los operadores se aplican al identificador. Pero no siempre funciona:

int a, *b, &c = a, d(), e[1], C::*f; 

Nota cómo todos a, *b, d() y e[1] resolver estáticamente a un int - aparte de &c y C::* que declaran una referencia (por lo tanto, tiene que ser inicializado) y una puntero a un miembro de la clase, respectivamente.

+0

+1 Muy bien establecido. –

+0

Este comentario puede ser controvertido. Pace Stroustrup, pero no Ritchie, quien escribió las líneas principales de la gramática que amplió, si uno coloca un operador declarador como * justo después de una secuencia de especificación de declaración como const foo como en const foo * bar es fácil leerlo mal como una constante (puntero a un foo) en lugar de un puntero a a (foo constante).Para aclarar las complejidades de la sintaxis de declaración, es útil leer el apéndice de la gramática de K & R o el lenguaje de programación C++ de Stroustrup. – egyik

Cuestiones relacionadas