Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Organization of C files

I'm used to doing all my coding in one C file. However, I'm working on a project large enough that it becomes impractical to do so. I've been #including them together but I've run into cases where I'm #including some files multiple times, etc. I've heard of .h files, but I'm not sure what their function is (or why having 2 files is better than 1).

What strategies should I use for organizing my code? Is it possible to separate "public" functions from "private" ones for a particular file?

This question precipitated my inquiry. The tea.h file makes no reference to the tea.c file. Does the compiler "know" that every .h file has a corresponding .c file?

like image 703
Kyle Cronin Avatar asked Sep 06 '08 22:09

Kyle Cronin


People also ask

What are the two main ways a file can be organized in C?

Writing to a file (fprintf or fputs)

What is file structure C?

A FILE is a type of structure typedef as FILE. It is considered as opaque data type as its implementation is hidden. We don't know what constitutes the type, we only use pointer to the type and library knows the internal of the type and can use the data. Definition of FILE is in stdio although it is system specific.


2 Answers

You should regard .h files as interface files of your .c file. Every .c file represents a module with a certain amount of functionality. If functions in a .c file are used by other modules (i.e. other .c files) put the function prototype in the .h interface file. By including the interface file in your original modules .c file and every other .c file you need the function in, you make this function available to other modules.

If you only need a function in a certain .c file (not in any other module), declare its scope static. This means it can only be called from within the c file it is defined in.

Same goes for variables that are used across multiple modules. They should go in the header file and there they have to marked with the keyword 'extern'. Note: For functions the keyword 'extern' is optional. Functions are always considered 'extern'.

The inclusion guards in header files help to not include the same header file multiple times.

For example:

Module1.c:

     #include "Module1.h"      static void MyLocalFunction(void);     static unsigned int MyLocalVariable;         unsigned int MyExternVariable;      void MyExternFunction(void)     {         MyLocalVariable = 1u;                 /* Do something */          MyLocalFunction();     }      static void MyLocalFunction(void)     {       /* Do something */        MyExternVariable = 2u;     } 

Module1.h:

     #ifndef __MODULE1.H     #define __MODULE1.H      extern unsigned int MyExternVariable;      void MyExternFunction(void);            #endif 

Module2.c

     #include "Module.1.h"      static void MyLocalFunction(void);      static void MyLocalFunction(void)     {       MyExternVariable = 1u;       MyExternFunction();     } 
like image 58
cschol Avatar answered Oct 23 '22 23:10

cschol


Try to make each .c focus on a particular area of functionality. Use the corresponding .h file to declare those functions.

Each .h file should have a 'header' guard around it's content. For example:

#ifndef ACCOUNTS_H #define ACCOUNTS_H .... #endif 

That way you can include "accounts.h" as many times as you want, and the first time it's seen in a particular compilation unit will be the only one that actually pulls in its content.

like image 20
Andrew Avatar answered Oct 23 '22 23:10

Andrew