Значение s++
является исходным значением s
, перед приращением приращение происходит в неопределенное время перед следующей точкой последовательности.
Следовательно, *s++
и *(s++)
эквивалентны : они оба разыменовывают исходное значение s
. Другое эквивалентное выражение - *(0, s++)
, и, не для слабонервных, таково это: 0[s++]
Обратите внимание, однако, что ваша функция должна использовать тип size_t
для i
и его тип возврата:
size_t str_len(const char *s) {
size_t i = 0;
while (*s++) {
i++;
}
/* s points after the null terminator */
return i;
}
Вот потенциально более эффективная версия с одним приращением на л oop:
size_t str_len(const char *s) {
const char *s0 = s;
while (*s++) {
/* nothing */
}
return s - 1 - s0;
}
Для тех, кто интересуется странными выражениями во втором абзаце :
0, s++
является экземпляром оператора запятой ,
, который оценивает свою левую часть, а затем правую часть, которая составляет его значение. следовательно, (0, s++)
эквивалентно (s++)
.
0[s++]
эквивалентно (s++)[0]
и *(0 + s++)
или *(s++ + 0)
, что упрощается как *(s++)
. Транспонирование указателя и индексных выражений в выражениях []
не очень распространено и не особенно полезно, но соответствует стандарту C.