Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to properly split a C program in files and include then?

I organized my program splitting every entity in its own file. Which is something like this.

main.c

#include "student.h"
#include "subject.h"
#include "classroom.h"

#define PI 3.14
int sum(int a, int b);

student.h

typedef struct st student;

student.c

#include "student.h"

subject.h

typedef struct sb subject;

subject.c

#include "subject.h"

classroom.h

typedef struct cr classroom;

classroom.c

#include "classroom.h"

My problem is, inside classroom I need student and subject. How should I include this? should I include this inside classroom.h or classroom.c?

#include "student.h"
#include "subject.h"

Second, I have things on main.c that are used by all of then like sum() and PI

How it is the right way including implementation in the header or including header in the implementation file? and should I include the header or implementation files?

If I throw everything on a single file it compiles just fine, but I'm not doing this right it does not compile.

like image 573
Vitim.us Avatar asked Feb 16 '23 11:02

Vitim.us


2 Answers

First. One thing that is important to know about .h (header) files. They should have the following.

// In the top of the file
#ifndef NAME_OF_FILE_H
#define NAME_OF_FILE_H

// Your header code goes here

// In the end of the file
#endif

Why put this? If you were to include your header file, say header.h, in multiple other files, file1.c, file2.c, you would basically be repeating the code, meaning the code in header.h will be placed in both files during compilation process.

Having those pre processor instructions assure you that the code in header.h will only exist once in the program.

Now. Where do you place your #includes? Well, I assume the student.h and the subject.h file will declare things that are implemented in the student.c and subject.c files. So if the classroom.h file uses things declared in the previous two headers then you need to place #include "student.h" and #include "subject.h" in classroom.h.

If only the classroom.c also uses things declared in the headers, place the includes only here but not in the classroom.h.

Finally, if both files use things declared in the headers, place #include "student.h" and #include "subject.h" in both files.

Basically, you place the includes in the files that need a resource defined (but not implemented) in a header. By having you header surrounded by the code above you can basically place the includes in many files and never have repeated code during the compilation process.

About the sum() and PI. Same thing. Make a header with the code above and included it where those things are needed.

like image 87
petermlm Avatar answered Mar 07 '23 07:03

petermlm


So the organisation of "x.h" and "x.c" (or "x.cpp") is a fairly standard way to do things. But some things don't fit in there, and sometimes you need a "constants.h" or some other name for things like PI and SpeedOfLight.

Something like sum would fit nicely into a "utils.h" - whether you have enough to make it worth having a "utils.c"

Your .c file should include all header files that it needs (but no more).

For example:

#ifndef X_H__
#define X_H__
 ...  
 all the contents of x.h goes here 
 ... 
#endif

And header files should include all things THEY need themselves. So for example, if "x.h" needs "a.h" and "b.h", there should be #include "a.h" and #include "b.h" in "x.h" so you don't have to remember that:

If I include "x.h", I must put "a.h" and "b.h" before it.

At the same time, don't add more includes than you actually need...

like image 45
Mats Petersson Avatar answered Mar 07 '23 06:03

Mats Petersson