Q:

Why do we use extra expression?

Here is a sample from Kernighan & Ritchie's "The C Programming Language":
int getline(char s[], int lim)
{
   int c, i = 0;

   while (--lim > 0; && (c=getchar()) !=EOF && c !='\n')
   {
      s[i++] = c;
   }

   if (c =='\n') 
   {
      s[i++] = c;
   }

   s[i] = '\0';

   return i;
}

Why do we should check if c != '\n', despite we use s[i++] = c after that?

A:

The functions reads characters from the standard input until either EOF or a newline characters is found. 
The second check ensures that the only newline character is put into the char array. EOF shouldn't occur in a proper c-string. Also, if the character isn't newline that means that we might have filled up our c-string, in which case we shouldn't put any more characters into it. 
Notice we still append the '\0'. We've ensured that theres still room for one more character in our c-string, as we use the pre-fix decrementor, which evaluates before the comparison.

