Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Why does this function return the correct length of a string? (Incrementing a char pointer)

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.

like image 485
lor Avatar asked Jan 14 '20 13:01

lor


1 Answers

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.

like image 61
chqrlie Avatar answered Oct 03 '22 01:10

chqrlie