Когда массив объявляется без указания его размера, когда размер определяется используемыми инициализаторами.
В этом объявлении массива
char str[] = "s";
используется строковый литерал как инициализатор. Строковый литерал - это последовательность символов, заканчивающаяся включенным нулевым символом в конце. То есть строковый литерал "s"
имеет два символа { 's', '\0' }
.
Его символы используются для последовательной инициализации элементов массива str
.
Итак, если вы напишете
printf( "sizeof( str ) = %zu\n", sizeof( str ) );
, тогда вывод будет 2
. Длина строки определяется как количество символов перед завершающим нулевым символом. Поэтому, если вы напишете
#include <string.h>
//...
printf( "strlen( str ) = %zu\n", strlen( str ) );
, то на выходе будет 1
.
Если вы попытаетесь записать данные вне массива, вы получите неопределенное поведение, потому что память, которая делает не принадлежащие массиву будут перезаписаны. В некоторых случаях можно получить ожидаемый результат. В остальных случаях программа может завершить работу sh ненормально. То есть поведение программы не определено.