This is a function that counts the number of characters in a string:
int str_len(const char* s) {
int i = 0;
while(*(s++)) {
i++;
}
return i;
}
Why does this return the correct length?
Let's say I call this function with a simple String "a"
. Then s
is incremented in the while loop, therefore the value of s
and i
are both 0.
The value of s++
is the original value of s
, before increment, the increment occurs at an unspecified time before the next sequence point.
Hence *s++
and *(s++)
are equivalent: they both dereference the original value of s
. Another equivalent expression is *(0, s++)
and, not for the faint of heart, such is this one: 0[s++]
Note however that your function should use type size_t
for i
and its return type:
size_t str_len(const char *s) {
size_t i = 0;
while (*s++) {
i++;
}
/* s points after the null terminator */
return i;
}
Here is a potentially more efficient version with a single increment per loop:
size_t str_len(const char *s) {
const char *s0 = s;
while (*s++) {
/* nothing */
}
return s - 1 - s0;
}
For those who wonder about the weird expressions in the second paragraph:
0, s++
is an instance of the comma operator ,
that evaluates its left part, then its right part which constitutes its value. hence (0, s++)
is equivalent to (s++)
.
0[s++]
is equivalent to (s++)[0]
and *(0 + s++)
or *(s++ + 0)
which simplify as *(s++)
. Transposing the pointer and the index expressions in []
expressions is not very common nor particularly useful but conforms to the C standard.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With