You're not paying attention. In the first example, printf is not actually invoked (called; run); The compiler needs to have a value to assign, and it doesn't. In the second example, the compiler recognizes that printf will be called at run time, and a value will be available.

You need to understand the build process that results in an executable file. First, a source file is preprocessed. During this phase include files are copied and pasted directly into the source file.

This new souce file is then submitted to the compiler. Certain syntactical requirements must be met for successful compilation. Not all requirements for an executable need to be present at this time; the compiler need only be assured that they will be present, in correct form, when needed.

Thirdly, the linker takes over. At this time all necessary code must be present, either as code produced by the compiler, or as distinctly specified libraries or other object files.

In some instances (embedded systems or systems without an OS or memory management), there may be a fourth step: the locator. The locator determines the final memory address for executables that aren't dynamically relocatable.

You need to refer to some books or tutorials. A forum is a place to get help with code you're having problems with, a place to expand your learning. It isn't an effective place to learn basics.