I am learning at moment C
and I really do not understand how header
files works and to be sure I have two Questions.
1) Let's take a look at the following program: main.c:
#include <stdio.h>
#include <string.h>
#include "functions.h"
int main( void )
{
printf( "Num = %d\n", number );
printNumber();
return 0;
}
functions.c:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "functions.h"
void printNumber( void )
{
printf("Number = %d\n", number );
}
functions.h:
#ifndef FUNCTIONS
#define FUNCTIONS
int number;
extern void printNumber( void );
#endif // FUNCTIONS
The way the program is in the Header file there is no extern
keyword
involved so there seems to be reference to number
and the program
Outputs:
Num = 0
Number = 0
The first Question is, does number
get initialized (is number global
variable or similar if number
is present only in the header file)
and is this a legal code/program?
Second scenario, let's take a look at the following code main.c:
#include <stdio.h>
#include <string.h>
#include "functions.h"
int main( void )
{
printf( "Num = %d\n", number );
printNumber();
return 0;
}
functions.c:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "functions.h"
void printNumber( void )
{
printf("Number = %d\n", number );
}
functions.h:
#ifndef FUNCTIONS
#define FUNCTIONS
extern int number;
extern void printNumber( void );
#endif // FUNCTIONS
Here the program will not compile due the
`undefined reference to number`
Which force me to declare number
in main
:
#include <stdio.h>
#include <string.h>
#include "functions.h"
int number;
int main( void )
{
printf( "Num = %d\n", number );
printNumber();
return 0;
}
Which is the Right way and why?
Last thing, why does exactly not apply
to void printNumber( void )
as well. I see that it is working with
or without the extern
keyword.
For the first version, in your header file, you define the variable number
. That means every translation unit that includes the header file will have a definition of the variable. That's not allowed, you can only have a single definition spread over all translation units.
The solution to that problem is to declare the variable in the header file instead:
extern int number;
The use of the keyword extern
marks this as a declaration instead of a definition, the compiler will know that the variable is defined somewhere else.
Then you of course need to define it somewhere. In one single source file put the definition:
int number;
I.e. exactly what you do in your last variant.