Java goes through a single compilation step to translate source code (.java) to bytecode (.class). C++ goes through a few more steps to reach binary code. (.exe/.dll)
Source Code (.c) -> PREPROCESSOR -> COMPILER -> Assembly Code (.o)
Assembly Code (.o) -> LINKER (+Libraries) -> Executable Code (.exe/.dll)
The Preprocessor processes # preprocessor directives. For example this will #include the contents of the header file into this position. #define will define pre-processor variables, do substitution and include only relevant #ifdef sections.
The compiler will then translate source code into assembly code, similar to the Java compiler step. This step will catch all syntax errors. The compiler should be able to locate all #include files through the additional include directories specified by the /I command line.
The linker then produces the binary for the assembly code. Linker errors can occur here if the compiled libraries referenced are not found.
The end result of a compilation/linking is usually an .exe file, which can be directly executed on a Windows machine. There are also options to create a dynamic library (dll) or a static library (lib). A dynamic library is looked up at runtime, and is usually shared among multiple programs. A static library is compiled into the executable directly, and does not require the existance of the lib during execution. A program referencing a DLL library will be smaller than one referencing a LIB, since the DLL code is located inside the DLL.
To call another method, the method must be “declared” before the calling line. Declaration may mean the actual method implementation, or just a “header” specifying the method name and parameters. Thus the use of #include files often at the top which includes the method definitions so they may be referenced. Actual implementation is later linked using the linker.