Search code examples
arrayscpointerswhile-loopc-strings

Iterate over *str vs str[] in while loop in C


I start learning C while ago and I was wondering... Does iterating over a string using

char *str = "Hello";
while (*str)
{
     str++;
}

Same as

char *str = "Hello";
int i = 0;
while (str[i] != '\0')
{
    i++;
}

Solution

  • According to the C Standard (6.5.2.1 Array subscripting)

    2 A postfix expression followed by an expression in square brackets [] is a subscripted designation of an element of an array object. The definition of the subscript operator [] is that E1[E2] is identical to (*((E1)+(E2))). Because of the conversion rules that apply to the binary + operator, if E1 is an array object (equivalently, a pointer to the initial element of an array object) and E2 is an integer, E1[E2] designates the E2-th element of E1 (counting from zero).

    So the expression *str is equivalent to str[0]. Or str[1] is equivalent tp *( str + 1 ) that in turn is equivalent to *( ++str + 0 ) or *++str or to the combination of the expressions ++str and *str

    The only essential difference is that after this loop

    char *str = "Hello";
    while (*str)
    {
         str++;
    }
    

    the pointer str does not point to the beginning of the string literal "Hello". While in the second code snippet

    char *str = "Hello";
    int i = 0;
    while (str[i] != '\0')
    {
        i++;
    }
    

    the pointer str is unchanged and points to the first character of the string literal.

    Pay attention to that instead of declaring the variable i as having the signed type int it is better to declare it as having type size_t because in general objects of the type int can be not large enough to store all possible lengths of strings.

    The expression in the while loop of the second code snippet can be written similarly to the expression in the while loop in the first code snippet

    while ( str[i])
    

    or like

    while ( *( str + i ) )
    

    That is any non-zero value is considered as a true expression.

    If you do not want to change the original pointer str in the first code snippet you can introduce an intermediate pointer like

    char *str = "Hello";
    
    char *p = str;
    while ( *p )
    {
         p++;
    }
    

    For example the function strlen can be implemented the following way

    size_t strlen( const char *s )
    {
        const char *p = s;
    
        while ( *p ) ++p;
    
        return p - s;
    }