#include <stdio.h> int main() { char a = 5; char b[2] = "hi"; // No explicit room for `\0`. char c = 6; return 0; }Cada vez que escribimos una cadena, encerrada entre comillas dobles, C crea automáticamente una matriz de caracteres para nosotros, que contiene esa cadena, terminada con el carácter \0 http://www.eskimo.com/~scs/cclass/notes/sx8. html
En el ejemplo anterior, b solo tiene espacio para 2 caracteres, por lo que el carácter de terminación nula no tiene un lugar en el que colocarse y, sin embargo, el compilador está reorganizando las instrucciones del almacenamiento de memoria para que a y c se almacenen antes que b en la memoria para hacer espacio. para un \0 al final de la matriz.
¿Es esto esperado o estoy alcanzando un comportamiento indefinido?
Una matriz de char no necesita ser terminada por nada en absoluto. Es una matriz. Si el contenido real es más pequeño que las dimensiones de la matriz, debe realizar un seguimiento del tamaño de ese contenido.
Las respuestas aquí parecen haber degenerado en una discusión en cadena. No todas las matrices de caracteres son cadenas. Sin embargo, es una convención muy fuerte usar un terminador nulo como centinela si se van a manejar como cadenas de facto.
Su matriz puede usar algo más y también puede tener separadores y zonas. Después de todo, puede ser una Unión o superponerse a una estructura. Posiblemente un área de preparación para otro sistema.
Se permite char una matriz de caracteres con una cadena si la matriz es al menos lo suficientemente grande como para contener todos los caracteres de la cadena además del terminador nulo.
Esto se detalla en la sección 6.7.9p14 del estándar C :
Una matriz de tipo de carácter se puede inicializar mediante una cadena de caracteres literal o una cadena literal UTF-8, opcionalmente encerrada entre llaves. Los bytes sucesivos del literal de cadena (incluido el carácter nulo de terminación si hay espacio o si la matriz tiene un tamaño desconocido) inicializan los elementos de la matriz.
Sin embargo, esto también significa que no puede tratar la matriz como una cadena, ya que no tiene una terminación nula. Entonces, como está escrito, dado que no está realizando ninguna operación de cadena en b , su código está bien.
Lo que no puede hacer es inicializar con una cadena demasiado larga, es decir:
char b[2] = "hello";Como esto da más inicializadores de los que pueden caber en la matriz y es una violación de restricción. La Sección 6.7.9p2 establece esto de la siguiente manera:
Ningún inicializador intentará proporcionar un valor para un objeto que no esté contenido dentro de la entidad que se está inicializando.
Si tuviera que declarar e inicializar la matriz de esta manera:
char b[] = "hi"; Entonces b sería una matriz de tamaño 3, que es lo suficientemente grande como para mantener constantes los dos caracteres en la cadena más el byte nulo final, lo que convierte a b en una cadena.
Para resumir:
Si la matriz tiene un tamaño fijo:
Si la matriz no tiene un tamaño explícito, se dimensionará para mantener la cadena constante más el byte nulo de terminación.
Hay dos cosas en tu pregunta.
Cadena literal. El literal de cadena (es decir, algo encerrado entre comillas dobles) es siempre la cadena terminada en un carácter nulo correcto.
char *p = "ABC"; // p references null character terminated stringLa matriz de caracteres solo puede contener tantos elementos como tiene, por lo que si intenta inicializar una matriz de dos elementos con un literal de cadena de tres elementos, solo se escribirán dos primeros. Por lo tanto, la matriz no contendrá la cadena C terminada en carácter nulo
char p[2] = "AB"; // p is not a valid C string.