I know that header files have forward declarations of various functions, structs, etc. that are used in the .c file that \'calls\' the #include, ri
The header provides access not only to other .c files in the same program, but likewise to libraries that may be distributed in binary form. The relationship of one .c file to another is exactly the same as a library that depends on another.
Since a programming interface needs to be in text form no matter the format of the implementation, header files make sense as a separation of concerns.
As others have mentioned, the program that resolves function calls and accesses between libraries and sources (translation units) is called the linker.
The linker does not work with headers. It just makes a big table of all the names that are defined in all the translation units and libraries, then links those names to the lines of code that access them. Archaic usage of C even allows for calling a function without any implementation declaration; it was just assumed that every undefined type was an int.