Can anyone explain how to create a header file in C with a simple example from beginning to end.
5 Answers
foo.h
#ifndef FOO_H_ /* Include guard */
#define FOO_H_
int foo(int x); /* An example function declaration */
#endif // FOO_H_
foo.c
#include "foo.h" /* Include the header (not strictly necessary here) */
int foo(int x) /* Function definition */
{
return x + 5;
}
main.c
#include <stdio.h>
#include "foo.h" /* Include the header here, to obtain the function declaration */
int main(void)
{
int y = foo(3); /* Use the function here */
printf("%d\n", y);
return 0;
}
To compile using GCC
gcc -o my_app main.c foo.c
9 Comments
#ifndef MY_HEADER_H
# define MY_HEADER_H
//put your function headers here
#endif
MY_HEADER_H serves as a double-inclusion guard.
For the function declaration, you only need to define the signature, that is, without parameter names, like this:
int foo(char*);
If you really want to, you can also include the parameter's identifier, but it's not necessary because the identifier would only be used in a function's body (implementation), which in case of a header (parameter signature), it's missing.
This declares the function foo which accepts a char* and returns an int.
In your source file, you would have:
#include "my_header.h"
int foo(char* name) {
//do stuff
return 0;
}
6 Comments
extern declarations of variables and functions in a separate file, historically called a header, that is included by #include at the front of each source file. The functions of the standard library, for example, are declared in headers like <stdio.h>."myfile.h
#ifndef _myfile_h
#define _myfile_h
void function();
#endif
myfile.c
#include "myfile.h"
void function() {
}
5 Comments
void function(); as a declaration does not prevent calls like function(42);. Use void in the declaration like void function(void);void function(); allows it as that is the style of early C where a declaration pretty much only told of a function name existence and return type.header files contain prototypes for functions you define in a .c or .cpp/.cxx file (depending if you're using c or c++). You want to place #ifndef/#defines around your .h code so that if you include the same .h twice in different parts of your programs, the prototypes are only included once.
client.h
#ifndef CLIENT_H
#define CLIENT_H
short socketConnect(char *host,unsigned short port,char *sendbuf,char *recievebuf, long rbufsize);
#endif /** CLIENT_H */
Then you'd implement the .h in a .c file like so:
client.c
#include "client.h"
short socketConnect(char *host,unsigned short port,char *sendbuf,char *recievebuf, long rbufsize) {
short ret = -1;
//some implementation here
return ret;
}
2 Comments
#ifndef and #define directives used in the source code for the library files (i.e., foo.c in the above example) rather than in the header file for that library? Is it because the compiler knows it only has one actual definition for foo.c?There are some excellent answers here regarding how to create header files, so I think it would also be good to bring up unity builds as a substitute for header files entirely. Header files are an important convention that separates the interface for a program's functions from the implementation of said functions. This can be very useful for large projects and is quite important to understand. However, it is important to realize that header files are a convention not enforced by the compiler. I have found that for most of my c/c++ applications, I am most comfortable simply using a unity build.
When you type #include <filename> at the top of a c file, your compiler simply replaces the include statement with the contents of filename. Simply using the implementation files in your include statement eliminates the need for headers in most cases, and prevents the proverbial "include hell" wherein you have to spend a ton of time debugging the compile process. Example below...
# include <stdio.h>
# include "functions.c"
int main(void)
{
printf("Hello from main!\n");
hello();
return 0;
}
and my functions.c file:
void
hello(void)
{
printf("Hello from functions.c!\n");
}
Compile them and run the output, and you get
Hello from main!
Hello from functions.c!
Of course, this creates all sorts of other problems especially with regards to modularity, so carefully consider your use-cases and programming style.