Что будет напечатано?

#c #printf #c-strings #strlen

#c #printf #c-строки #strlen

Вопрос:

Не могли бы вы, пожалуйста, объяснить мне, почему результат следующей программы равен 1?

 const char *str = "mms";

printf("%dn", strlen(str   2));

return 0;
 

Если я добавлю 1, результатом будет 2.

Комментарии:

1. Вы уже изучили арифметику указателей? Это похоже на то, что должно быть частью каждого приличного курса / учебника по C

2. Обратите внимание, что strlen(str 2) отличается от strlen(str) 2 . Может быть, это ваш источник путаницы?

Ответ №1:

Для начала этот вызов

 printf("%dn", strlen(str   2));
 

может вызывать неопределенное поведение, потому что в соответствии со стандартом C (7.21.6.1 функция fprintf)

9 Если спецификация преобразования недопустима, поведение не определено.275) Если какой-либо аргумент не имеет правильного типа для соответствующей спецификации преобразования, поведение не определено.

Спецификатор преобразования d ожидает аргумент типа int , в то время как выражение strlen( str 2 ) имеет тип size_t в соответствии с объявлением функции strlen

 size_t strlen(const char *s);
 

Вы должны написать

 printf("%zun", strlen(str   2));
        ^^^
 

Вы объявили указатель на строковый литерал

 const char *str = "mms";
 

Строковый литерал внутренне представлен в виде массива символов, например

 { 'm', 'm', 's', '' }
 

То есть он содержит 4 символа, включая завершающий нулевой символ '' .

Указатель str указывает на первый символ литерала. Выражение str 2 указывает на третий символ литерала, который является символом 's' из-за арифметики указателя.

Из стандарта C (7.23.6.3 Функция strlen)

3 Функция strlen возвращает количество символов, которые предшествуют завершающему нулевому символу.

Так как выражение str 2 фактически указывает на строку "s" , то функция вернет 1 то, что будет выведено.

Ответ №2:

ну, strlen начните с указателя, который вы передаете, и считайте, пока он не найдет значение NULL или символ.

So str 2 указывает на букву s , так что до конца строки всего одна буква; str 1 указывает на m и так … вы получаете 2

Ответ №3:

Следующая инструкция

  printf("%dn", strlen(str));
 

будет печатать 3 , потому что это длина строки "mms" .

Давайте вспомним, что строка, на которую указывает, str хранится следующим образом

 ------------------
| m | m | s | 0 |
------------------
 

Таким str 1 образом, указатель на второй элемент строки (он эквивалентен amp;(str[1]) , и str 2 на третий элемент (он эквивалентен amp;(str[2]) ,

И на что указывает строка str 2 ? Это так "s" . Таким образом, его длина равна 1.


Если вашей целью было увеличить 2 длину str , вы должны обратить внимание на использование круглых скобок:

 printf("%dn", strlen(str) 2);
 

Таким образом, аргумент strlen равен str и 2 добавляется к возвращаемой длине.