Во-первых, "sample"
называется строковым литералом. Он объявляет массив const char, заканчивающийся нулевым символом.
Давайте продолжим:
char arr[]="sample";
Правая часть в массиве const char размера 7 (6 символов и '\0'
. Размерность arr выводится из его инициализации и также равна 7. Массив char затем инициализируется из буквенной строки.
char arr2[6]="sample";
arr2
имеет объявленный размер 6. Он инициализируется из строкового литерала размера 7: только объявленная позиция 6 инициализируется в {'s', 'a', 'm', 'p', 'l', 'e'}
без завершающего нуля . Здесь все в порядке, за исключением того, что передача arr2
в функцию, которая ожидает завершенную нулем строку, вызывает неопределенное поведение.
char arr3[7]="sample";
Объявленный размер и размер литеральной строки инициализации равны 7: это просто явная версия первого варианта использования. Довольно опасно, потому что если вы позже добавите один символ в строку инициализации, вы получите массив символов с ненулевым символом в конце.
char* strarr="sample";
Избегайте этого . Вы объявляете неконстантный указатель на строковый литерал. В то время как стандарт объявляет явно:
Если программа пытается изменить такой массив, поведение
не определено.
strarr[3] = 'i'
будет затем вызывать неопределенное поведение без предупреждения. При этом, при условии, что вы никогда не изменяете строку, у вас есть хорошая завершенная нулем строка.
char* strarr1=arr;
Хорошо, вы объявляете указатель на другую строку. Или, точнее, указатель на первый символ другой строки. И это правильно завершается нулем.
char* strarr2=arr2;
У вас есть указатель на первый символ массива символов с ненулевым символом в конце ... Вы не можете передать arr2
функции, ожидающей массив символов с нулевым символом в конце, и вы не можете либо передать strarr2
.
char* strarr3=arr3;
У вас есть другой указатель, указывающий на строку. То же поведение, что и strarr1
.
Согласно как проверить в GDB завершающий ноль , вы не можете напечатать его напрямую, потому что GDB знает достаточно строк C, чтобы автоматически прекратить печатать строку с первым нулевым символом. Но вы всегда можете использовать p arr[7]
, чтобы увидеть, является ли символ после массива нулевым или нет.
Для arr2
, arr2+7
- один за массивом. Так что не определено, что там и в действительно плохой системе, использование p arr[7]
может вызвать сигнал, потому что это может быть после конца сегмента памяти - но я должен признать, что я никогда не видел этого ...