Learn C Language – Part 6: File Divisions

Diving a large source code into several files.

The series Learn C Language is almost ending. This is one of the last sections of the C-language learning series, and we’ll learn how to divide a large source code into several files. Once you acquire the skill, you’ll be able to code almost any kind of C-based program.

Hi everyone. This is one of the very last sections of Learn C Language series. It’s been a long journey, right? Since I’m handling many other series to keep track of my learning processes, including Linux Programming, Arduino, and Algebra, my learning journey will keep going. But this is one of my accomplishments to finish this series. Once I finish this one, I’ll start learning another. What I’m thinking of at this moment is learning Kotlin and modern Android programming since being an Android developer is one of my career goals at this moment. Also, I want to improve my programming skills by learning some advanced algorithms.

Anyways, let’s get started with this section!

This time, we’ll learn how to divide a large source code into several other files and make the program readable and manageable.

Image 01 is the source code we’ll divide. I know it’s a bit difficult to read through the file. But don’t worry, we’ll go through each part one after another by explaining what’s going on in each section.

image 01

Image 02 is the executed result. The reason the error is shown in “2 Micheal” is that id 2 is already registered by another name, Sarah.

image 02

Lines 5 to 10:

image 03

MAX_STUDENT: the max number of registrable students number

LENGTH: the max length of a student’s name

MESSAGE_LENGTH: the max length of the message that going to be printed out on the console

These elements are essential parts of the entire program and will be shared among them when the whole program is divided into several files.

Lines 13 to 16:

image 04

enum automatically allocates numbers.

MESSAGE_OK: 0

MESSAGE_ERROR: 1

Lines 19 to 22

image 05

Here is the structure that contains the id and name.

Lines 25 to 29

image 06

Global variables are declared here.

num: the number of students is going to be plugged into this variable.

student_database: the database where students’ info will be inserted.

Since student_database has MAX_STUDENT, it’s allowed to accommodate up to ten students.

Error: int-type error code will be inserted.

Lines 32 to 40

image 07

initDatabase: initializing the database.

add: registering int-type and char-type data.

student* get(int); student data’s pointer(address) will be returned.

showStudentData: print out student’s data.

showError: print out errors.

Lines 42 to 55

image 08

char names[][LENGTH] = { “John”,”Sarah”,”Micheal”,”Don” };

As it’s declared in LENGTH, you can register up to 50 students.

int ids[] = { 1,2,2,3 };

The 2 are duplicated to make an intentional error.

initDatabase();

initialize the database.

for (i = 0; i < 4; i++) { // data registration

add(ids[i], names[i]);

printf(“Registered: %d %s \n”, ids[i], names[i]);

showError();

}

The for-loop will rotate through ids and names and register each student to the database. If it encounters an error, it will display it in showError().

Finally, it prints out the registered data to the console with the for-loop.

image 09

initDatabase()

image 10

From here, let’s take a look at each method one by one, starting from initDatabase().

initDatabase() initializes the database.

for (i = 0; i < MAX_STUDENT; i++)

student_database[i].id = -1;

strcpy(student_database[i].name, “”);

}

The above codes will initialize id, name with the following parts:

student_database[i].id = -1;

strcpy(student_database[i].name, “”);

Error = MESSAGE_OK;

initialize the error message too.

num = 0;

The registered student’s number is also initialized.

add()

image 11

if (get(id) == NULL && num < MAX_STUDENT)

The if-statement checks if

the student data is registrable or not as well as num is smaller than MAX_STUDENT.

student_database[num].id = id;

If it’s registrable, it registers the id.

strcpy(student_database[num].name, name);

Also, it copies the received student name by strcpy.

Error = MESSAGE_OK;

Finally, MESSAGE_OK (meaning No Error) is inserted to Error.

return 1;

If the registration is successful, it returns 1.

Error = MESSAGE_ERROR;

If it fails, MESSAGE_OK (meaning Error occured) is inserted to Error.

get()

image 12

The for-loop rotates through if (student_database[i].id == id) and it returns the id if it matches it. If not, it returns NULL.

showStudentData()

image 13

showStudentData(student* data) receives data’s pointer.

Since it handles pointers, it uses the arrow operator (data->id, data->name).

showError()

showError() determines the executed result by switch-statement.

image 14

Divided files

image 15

From here, let’s take a look at how the long program (image 01) is divided into five different files.

Header files

There are two large categories:

dataOutput.h: handles data output to the console.

studentDatabase.h: handles the database.

Source files

main.c: the program’s main() is here.

dataOutput.c: corresponds to dataOutput.h

studentDatabase.c: corresponds to studentDatabase.h

main.c

image 16

main.c includes dataOutput.h and studentDatabase.h in lines 2 and 3.

studentDatabase.h

image 17

Here, enum, structure, and methods are initialized.

dataOutput.h

image 18

studentDatabase.h is included in line 4. And what needs your attention here is that header files also include each other, not just source files. And the reason it includes studentDatabase.h is that it accesses student*, which is the structure declared in studentDatabase.h.

studentDatabase.c

image 19

In this source file, methods are defined.

What needs your attention here is that static variables are not accessible from other source codes.

Just for a reference, in the example below (image 20), dataOutput.c accesses to studentDatabase.c’s Error variable but not be able to do the same with the static ones.

image 20

And define is also usable only within the source code.

define MESSAGE_LENGTH 256

image 21

Leave a Reply