What is the difference between declaration and a definition in C?
Although the terms are often used interchangeably, they have
distinct meanings in both C and C++. To be more precise, they have
distinct meaning to the compiler and linker.
A declaration is simply a statement to the compiler that a type exists while a definition fully describes a type to both the compiler and the linker. It is important to note that every definition is itself a declaration, but a declaration need not be a definition. In other words, it is impossible to define something that hasn't been declared, but you can declare something without defining it. A declaration without a definition is known as a "forward declaration"; a declaration of something that will (eventually) be defined somewhere.
It is also important to note that a type can only be defined once but can be declared more than once, provided those declarations are in separate translation units and are consistent with each other. Since there can only be one definition, that definition must reside in just one translation unit. To ensure all declarations of a type remain consistent, simply place the declaration in a header file and include that header file wherever it is required. It doesn't matter where the definition resides so long as there is exactly one definition in your program. Since headers may also contain definitions (and may include other headers with definitions), it is vital that you use "header guard" macros to ensure those definitions are only included once in every compilation.
The "one definition rule" (ODR) can be broken in one of two ways: either by not providing the definition of a type at all, or by providing two or more definitions for the same type. Both will be picked up by the linker.
Unlike C++, C generally doesn't care if a type is forward declared or not, just so long as it is declared somewhere in the translation unit(s) that use them.
The built-in types do not require either a declaration or a definition; they are defined by the language itself (hence they are built-in). This includes all the fundamental types: primitive data types (int, char, float and double); all modified primitive types (types declared with the signed, unsigned, long and short modifiers); all primitive array types and; all primitive pointer types.
The only type that need not be defined before being used is a function. The declaration of a function is enough for the compiler to determine the function's prototype: the type of the function (the return type) and the type of its argument (if any). So long as the declaration is visible to the translation unit(s) that use the function, the compiler can determine if calls to that function are well-formed. The definition of the function provides the implementation of that function and so long as a definition exists somewhere, the compiler will (eventually) find it and the linker will be able to link it.
Union, struct and enum types have no implementation details in C so a declaration suffices. (In C++, we must define struct methods, if any are declared, just as we must with all class types. A struct with no declared methods is treated the same as a C-style struct).
Typedefs are, by their very nature, always defined. They are
type definitions after all. This includes type definitions provided
by the C standard library (such as wchar_t) as well as all
Although we quite often use the term "declare a variable", variables are not declared they are simply instantiated. To be precise, a variable is an instance of an already declared type and memory is physically allocated to the variable according to that type. When a variable is instantiated, it is said to be in an uninitialised state. In reality, the value will be whatever value happens to reside at the memory address allocated to the variable, however most compilers will warn you if you attempt to use a variable that has not been explicitly initialised.
We also quite often use the term "define a variable" when we assign a value to the variable. However we are not defining the variable, we are either initialising the (uninitialised) variable or we are assigning a new value to the (initialised) variable. The type of the value must be the same as the variable type, or of a type that can be implicitly converted to that type by the compiler.
The same can be said of constants, the only difference being that we initialise constants at the point of instantiation since there is no such thing as an uninitialised constant.
Note that although we often use the terms "declare" and "define" interchangeably and there's nothing actually wrong with using terms such as "declare a variable", they have specific meanings with respect to the compiler.
In The Defintion of a variable space is reserved for the and some initial value is given to it, whereas a declaration only identifies the type of the variable for the function . thus definition is the place where the variable is created or assigned storage whereas declaration refers to places where the nature of the variable is stated but no storage is allocated.