Q:

fgets error and strings declaration style on c

I'm curious about one thing, the following code works perfectly. 
#include <stdio.h>
int main()
{
  FILE * fp = fopen("test.txt", "r");
  char line[100];

  while( fgets(line, sizeof(line), fp) != NULL )
    fputs(line, stdout);
  fclose(fp);
  return 0;
}

But why it is not possible to use instead:
char *line;

Without causing fgets to crash?

A:

It is possible. Just point it to some valid memory.
char line[100];
char* linep = line ;
while( fgets(linep, sizeof(line), fp) != NULL )...

If you don't assing line to linep, then linep points to random memory, and you cannot use that.

A:

fgets crashes because it is writing the result into unallocated memory.
Without any further memory allocation, char *line points to "nothing". It points to something, but not to any valid memory location -- null if your compiler sets uninitialized values to 0, or any random memory location anywhere on or not on your system.
Even if fgets does not crash, you cannot predict what it does as writing into unallocated memory results in undefined behavior (What is undefined behavior?).

