#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
добавляется к возвращаемой длине.