Search code examples
cstrcmp

Can't understand small part of strcmp function


I'm reading a book in C and have seen these two strcmp algorithm.

I have learned my self how the usel for loop works.

But these two for loop are new for me. I don't understand these parts

  1. for (i = 0; s[i] == t[i]; i++) It have no length instead have this s[i] == t[i].

  2. for ( ; *s == *t; s++, t++) what means this guy ;.

The other parts i understand and I'm also aware what these function returns.

   /* strcmp: return <0 if s<t, 0 if s==t, >0 if s>t */
int strcmp(char *s, char *t)
{
   int i;
   for (i = 0; s[i] == t[i]; i++)
       if (s[i] == '\0')
     return 0;
   return s[i] - t[i];
}

int strcmp(char *s, char *t)
{
 for ( ; *s == *t; s++, t++)
  if (*s == '\0')
  return 0;
 return *s - *t;
}

Solution

  • First, some basics.

    The syntax of a for loop is

    for ( expr1opt ; expr2opt ; expr3opt ) statement
    

    Each of expr1, expr2, and expr3 are optional. The statement

    for ( ; ; ) { // do something }
    

    will loop "forever", unless there's a break or return statement somewhere in the body of the loop.

    expr1, if present, is evaluated exactly once before loop execution - it's used to establish some initial state (such as setting an index to 0, or assigning a pointer value, or something like that).

    expr2, if present, is evaluated before each iteration of the loop body. It's the test condition for continuing loop execution. If the expression evaluates to a non-zero value, the loop body is executed; otherwise, the loop exits. If expr2 is missing, it is assumed to evaluate to 1 (true).

    expr3, if present, is evaluated after each iteration of the loop body. It usually updates whatever is being tested in expr2.

    for (i = 0; s[i] == t[i]; i++) It have no length instead have this s[i] == t[i]

    This loop will execute as long as s[i] == t[i]; as soon as t[i] is not equal to s[i], the loop will exit. By itself, this means the loop will run past the end of the string in case you have identical strings - if both s and t contain "foo", then the loop will run as

    s[0] == t[0] == 'f'
    s[1] == t[1] == 'o'
    s[2] == t[2] == 'o'
    s[3] == t[3] == 0
    s[4] == t[4] // danger, past the end of the string
    

    So, within the body of the loop, the code also checks to see if a[i] is 0 - if so, that means we've matched everything up to the 0 terminator, and the strings are identical.

    So, basically, it goes...

    s[0] == t[0] == 'f', s[0] != 0, keep going
    s[1] == t[1] == 'o', s[1] != 0, keep going
    s[2] == t[2] == 'o', s[2] != 0, keep going
    s[3] == t[3] == 0, s[3] == 0, at end of s, strings match
    

    for ( ; *s == *t; s++, t++)

    does exactly the same thing as the first loop, but instead of using the [] operator to index into s and t, it just uses the pointers. Since there's nothing to initialize, the first expression is just left empty.