Por que

char *names [] = {"hello", "Jordan"};

Trabaja bien

Pero esto no

char names [] = {"hello", "Jordan"};

Agradecería si alguien me pudiera explicar esto, gracias :).

2
Jordan Dixon 17 sep. 2018 a las 18:10

4 respuestas

La mejor respuesta

Aquí

char *names [] = {"hello", "Jordan"};

names es matriz de punteros de caracteres , es decir, puede contener punteros, es decir, names cada elemento en sí es una matriz de caracteres. Pero aquí

char names [] = {"hello", "Jordan"};

names es solo una matriz de caracteres , es decir, puede contener solo una matriz de caracteres como "hello" no múltiples.

En segundo caso como

int main(void) {
        char names[] = {"hello", "Jordan"};
        return 0;
}

Cuando compila (le sugerimos que compile con las banderas -Wall -pedantic -Wstrict-prototypes -Werror), el compilador dice claramente

error: exceso de elementos en el inicializador de matriz de caracteres

Lo que significa que no puede tener más de una matriz de caracteres en este caso. La correcta es

char names[] = {'h','e','l','l','o','\0'}; /* here names is array of characters */

Editar: - También hay más posibilidades si la sintaxis de names se ve a continuación

char names[] = { "hello" "Jordan" }; /* its a valid one */

Entonces aquí tanto hello y Jordan se unen y se convierte en una matriz de un solo carácter helloJordan.

char names[] = { "helloJordan" }; 
3
Achal 17 sep. 2018 a las 15:59

char name[] es un conjunto de caracteres para que pueda almacenar una palabra en él:

char name[] = "Muzol";

Esto es lo mismo de:

char name[] = {'M', 'u', 'z', 'o', 'l', '\0'}; /* '\0' is NULL, it means end of the array */

Y char* names[] es una matriz de matrices donde cada elemento de la primera matriz apunta al comienzo de los elementos de la segunda matriz.

char* name[] = {"name1", "name2"};

Es lo mismo de:

char name1[] = {'n', 'a', 'm', 'e', '1', '\0'}; /* or char name1[] = "name1"; */
char name2[] = {'n', 'a', 'm', 'e', '2', '\0'}; /* or char name2[] = "name2"; */
char* names[] = { name1, name2 };

Básicamente, names[0] apunta a &name1[0], donde puede leer la memoria hasta name1[5], aquí es donde encuentra el carácter '\0' (NULL) y se detiene. Lo mismo sucede para name2[];

0
Muzol 18 sep. 2018 a las 12:31

Un literal de cadena, como "hello", se almacena en la memoria estática como una matriz de char s. De hecho, un literal de cadena tiene el tipo char [N], donde N es el número de caracteres en la matriz (incluido el terminador \0). En la mayoría de los casos, un identificador de matriz se desintegra en un puntero al primer elemento de la matriz, por lo que en la mayoría de las expresiones un literal de cadena como "hello" se descompondrá en un puntero al elemento char {{X7} }.

char *names[] = { "hello", "Jordan" };

Aquí los dos literales de cadena decaen a punteros a char que apuntan a 'h' y 'J', respectivamente. Es decir, aquí los literales de cadena tienen el tipo char * después de la conversión. Estos tipos están de acuerdo con la declaración de la izquierda, y la matriz names[] (que no es una matriz de tipo de caracteres, sino una matriz de char *) se inicializa utilizando estos dos valores de puntero.

char names[] = "hello";

O similarmente:

char names[] = { "hello" };

Aquí nos encontramos con un caso especial. Los identificadores de matriz no se convierten en punteros a sus primeros elementos cuando son operandos del operador sizeof o el operador unario &, o cuando son literales de cadena utilizados para inicializar una matriz de tipo de caracteres . Entonces, en este caso, el literal de cadena "hello" no decae a un puntero; en cambio, los caracteres contenidos en el literal de cadena se usan para inicializar la matriz names[].

char names[] = {"hello", "Jordan"};

Nuevamente, los literales de cadena se usarían para inicializar la matriz names[], pero hay exceso de inicializadores en la lista de inicializadores. Esta es una violación de restricción de acuerdo con el Estándar. De § 6.7.9 ¶2 del borrador C11 Estándar:

Ningún inicializador intentará proporcionar un valor para un objeto no contenido dentro de la entidad que se está inicializando.

Una implementación conforme debe emitir un diagnóstico en caso de una violación de restricción, que puede tomar la forma de una advertencia o un error. En la versión de gcc que estoy usando en este momento (gcc 6.3.0) este diagnóstico es un error:

error: excess elements in char array initializer

Sin embargo, para las matrices de char que se inicializan mediante una lista inicializadora de valores char en lugar de mediante literales de cadena, el mismo diagnóstico es una advertencia en lugar de un error.

Para inicializar una matriz de char que no es una matriz de punteros, necesitaría una matriz 2D de char s aquí. Tenga en cuenta que la segunda dimensión es necesaria y debe ser lo suficientemente grande como para contener la cadena más grande en la lista de inicializadores:

char names[][100] = { "hello", "Jordan" };

Aquí, cada literal de cadena se usa para inicializar una matriz de 100 char s contenida dentro de la matriz 2d más grande de char s. O, dicho de otro modo, names[][] es una matriz de matrices de 100 char s, cada una de las cuales se inicializa con un literal de cadena de la lista de inicializadores.

0
ex nihilo 17 sep. 2018 a las 16:46

El primero es una serie de punteros a char. El segundo es un conjunto de caracteres y debería verse como char names[] = {'a', 'b', 'c'}

2
edtheprogrammerguy 17 sep. 2018 a las 15:13