For a variable, declaration and definition are much the same thing. The variable is declared to exist and its type is defined.

Depending upon circumstances (where the variable is declared), the variable may or may not receive some known initial value.

For a function, the declaration provides the signature of the function, prior to use, so that the compiler will know if subsequent calls are written correctly. That's all the compiler needs to know. The definition of the function generates the actual code, which must exist at link time and run time.

If the function definition (the writing of the actual code) occurs before it is first encountered by the compiler, then no separate declaration is needed, as the compiler can determing the signature from the definition.