You have to understand what happens when a pointer is created. When created and not explicitly initialized (case 2: FILE *file_out; ), the pointer is created, the memory space is allocated, but most importantly, the memory's contents will be whatever garbage data was there when the pointer was created! This means that if there's a way that the pointer can be used before it is explicitly assigned to a file (or whatever data type it is)in later code, it contains garbage data that the program will treat as an address at runtime. This can lead to a seg fault (best case), or will access some memory within the program's memory space that is not valid and may possibly corrupt some data with no indication that anything went wrong (worst case). In other words, the behavior is unpredictable.
If, however, a pointer is set to null when created (case 1), the system will explicitly see that it is null and will not access a random memory location based on the garbage data in the pointer's physical memory. That's why it's best practice to assign a pointer to NULL or to an active memory location immediately upon creation.
It's also best practice to initialize the pointer immediately upon creation. For example,
FILE *file_out = fopen("myfile.txt","r");
The bottom line: One should always initialize a pointer when it's created, either with NULL or a valid memory address or function call like fopen() or malloc().
As for both cases working for you, that's simple. Your code is likely clean in that it's impossible for any garbage data to be accessed before fopen is called. Still, best to use "best practice". ;-)