Só pra reforçar e complementar o que já disseram, não é o computador que usa o caractere \0
para terminar strings. Isso é uma convenção do C. Outras linguagens podem ou não fazer da mesma forma.
E mesmo que o \0
não conte para determinar o tamanho da string, ainda sim você sempre deve reservar um espaço para ele no final. Ele é o terminador de string, por isso sempre deve fazer parte dela.
Então se for para setar os caracteres um a um, o primeiro exemplo deveria ter feito assim:
char string[3];
string[0] = 'O';
string[1] = 'i';
string[2] = '\0';
Tem que reservar um espaço para o \0
, senão não é string.
Mas como é um texto fixo, é mais simples inicializar diretamente com o texto todo de uma vez (como já indicado em outro comentário), pois aí o \0
já é adicionado automaticamente:
// assim o \0 é adicionado automaticamente no final
char string[] = "Oi";
Enfim, se não tiver o \0
, pode até "funcionar" em alguns casos por sorte ou coincidência, mas não espere que vá funcionar sempre. Pode parecer um detalhe besta, mas não é: muitas funções (senão todas) da biblioteca padrão que manipulam strings esperam que tenha o \0
no final, e muitas podem ter comportamento indefinido se vc passar uma que não tenha, podendo inclusive causar falhas graves no programa.
Não sei se a intenção foi simplificar de propósito para facilitar o entendimento, mas de qualquer forma fica o alerta.
Por fim, como curiosidade, o código também poderia ser:
char *string = "Oi"; // o \0 é adicionado automaticamente no final
while (*string != '\0')
putchar(*string++ + 1);
A diferença é que agora a string será readonly, mas como o código não a modifica, então tudo bem (se precisasse modificar, aí teria que trocar para char string[]
).
E no loop, basta ir incrementando o ponteiro (que passará a apontar para o caractere seguinte), até chegar no \0
.