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