Первый вопрос
Когда вы выполните
char string[] = "first string";
^
No size specified
, компилятор зарезервирует память, в которой может содержаться именно текст «первая строка» и завершение NUL.Если вы напечатаете размер строки, вы получите 13. Другими словами - переменная может не содержать дополнительные данные, поэтому бессмысленно объединять другую строку.
Вы можете сделать:
char string[100] = "first string";
и затем вы можете объединить другую строку.
Второй вопрос
Первое, что нужно знать, это то, что строки в C - это символымассивы, содержащие NUL-завершение.
Когда вы делаете:
char b[3];
, вы получаете неинициализированный массив, то есть b
может содержать что угодно - например, b = { ? , ? , ? }
Затем вы делаете:
strncpy(b, a, (int)(sizeof(b) - 1));
, что означает, что вы копируете 2 первых символа из a
в b
.
Итак, теперь мы знаем, что b
равно b = { 'k' , 'e' , ? }
Обратите внимание, что третий символ b
все еще неинициализирован.
Так что когда вы делаете:
printf("string length: %i\n", (int)strlen(b));
printf("%s\n", b);
вы используете b
, как будто это строка, но это не так.Нет завершения NUL.Следовательно, функции (printf
, strlen
) дают неверные результаты.Вызов этой функции с массивом символов без завершения NUL - неопределенное поведение, т. Е. Может произойти все, что угодно.
Кажется, что происходят две вещи:
a) Неинициализированныйсимвол в b
просто является буквой 'E' (в одном из ваших примеров)
b) Строковый литерал "kenny" просто находится в памяти сразу после переменной b
.
Таким образом, двухстрочная функция действительно видит строку "keEkenny", которая имеет len 8.
Чтобы исправить это, вы можете сделать:
strncpy(b, a, (int)(sizeof(b) - 1));
b[sizeof(b) - 1] = '\0';
или просто сделать:
char b[3] = { 0 };
, поскольку это инициализирует все b
, то есть b = { '\0' , '\0' , '\0' }