AC string é uma matriz de caracteres que termina com um terminador nulo .
Todos os caracteres têm um valor de tabela de símbolos. O terminador nulo é o valor do símbolo 0
(zero). É usado para marcar o final de uma string. Isso é necessário, pois o tamanho da string não é armazenado em nenhum lugar.
Portanto, toda vez que você alocar espaço para uma sequência, você deve incluir espaço suficiente para o caractere terminador nulo. Seu exemplo não faz isso, apenas aloca espaço para os 5 caracteres de "hello"
. O código correto deve ser:
char str[6] = "hello";
Ou, de forma equivalente, você pode escrever um código de auto-documentação para 5 caracteres mais 1 terminador nulo:
char str[5+1] = "hello";
Ao alocar memória para uma sequência dinamicamente em tempo de execução, você também precisa alocar espaço para o terminador nulo:
char input[n] = ... ;
...
char* str = malloc(strlen(input) + 1);
Se você não anexar um terminador nulo no final de uma sequência, as funções da biblioteca que esperam que uma sequência não funcione corretamente e você receberá erros de "comportamento indefinido", como saída de lixo ou falhas no programa.
A forma mais comum para escrever um caractere nulo terminador em C é usando um chamado "sequência de escape octal", procurando assim: '\0'
. Isso é 100% equivalente à gravação 0
, mas \
serve como código de auto-documentação para indicar que o zero é explicitamente destinado a ser um terminador nulo. Código como if(str[i] == '\0')
verificará se o caractere específico é o terminador nulo.
Observe que o termo terminador nulo não tem nada a ver com ponteiros nulos ou com a NULL
macro! Isso pode ser confuso - nomes muito semelhantes, mas significados muito diferentes. É por isso que o terminador nulo às vezes é chamado de NUL
um L, para não ser confundido com NULL
ponteiros nulos. Veja as respostas a esta pergunta do SO para obter mais detalhes.
O "hello"
código em seu código é chamado literal de string . Isso deve ser considerado como uma sequência de somente leitura. A ""
sintaxe significa que o compilador anexará um terminador nulo no final da cadeia literal automaticamente. Portanto, se você imprimir sizeof("hello")
, receberá 6, não 5, porque obtém o tamanho da matriz, incluindo um terminador nulo.
Ele é compilado corretamente com o gcc
De fato, nem mesmo um aviso. Isso ocorre devido a um detalhe / falha sutil na linguagem C que permite que as matrizes de caracteres sejam inicializadas com uma literal de cadeia de caracteres que contenha exatamente quantos caracteres houver espaço na matriz e, em seguida, descarte silenciosamente o terminador nulo (C17 6.7.9 / 15) O idioma está propositalmente se comportando assim por razões históricas, consulte Diagnóstico inconsistente do gcc para inicialização de strings para obter detalhes. Observe também que o C ++ é diferente aqui e não permite que esse truque / falha seja usado.
char str[] = "hello";
caso.