You’ve written functions that work. The rand generator and the bubble_sort algorithm are solid. Now you need them elsewhere. Copy-pasting code is messy. It creates bugs. It makes maintenance a nightmare.

The solution is a utility library.

In C, a library isn’t a magic box. It’s two specific files working together: a header (.h ) and a source (.c ). The header tells the compiler what’s available. The source file contains the actual logic.

Here is how you structure a basic C library to keep your code clean and modular.

Defining the Interface

Every public function needs a declaration. This lives in the header file.

Create a file named util.h.

Those lines are function prototypes. The extern keyword is important. It tells the compiler: “This function exists, but I don’t know where yet. I will find it later during linking.”

If you are using a very old-style C compiler, you might need to remove the parameter names from bubble_sort. Modern standards prefer full prototypes, but legacy code often strips them.

Implementing the Logic

Now for the heavy lifting. Create util.c.

Notice the inclusion. You use quotes ("util.h" ) instead of angle brackets ( ). Angle brackets are reserved for system libraries found in standard directories. Quotes tell the compiler to look in the current directory.

There is a subtle security feature here. The variable rand_seed is defined in the .c file but not in the .h file. This is information hiding.

Programs that include util.h know about rand(). They don’t know about rand_seed. They can’t accidentally modify the seed. If you want to enforce this strictly, you can add the static keyword before int rand_seed. This makes the variable visible only within this single file.

Using the Library

Your main program doesn’t need the implementation. It only needs the interface.

Create main.c.

The benefit is immediate. The main logic is shorter. You don’t clutter your primary code with sorting algorithms or random number generators. You just call them.

Compiling and Linking

This is where most beginners stumble. You cannot compile everything at once if you want separate object files. You have to compile separately, then link.

Assuming you are on a UNIX-like system, here is the workflow.

First, compile the library source into an object file.

The -c flag tells GCC to compile but not link. It stops after creating machine code. The -g flag adds debug symbols, which is useful if things go wrong. The result is util.o. This file contains the compiled machine code for rand and bubble_sort. It cannot run on its own because it lacks a main function.

Next, compile your main program.

This produces main.o. Again, this is just machine code. It’s not an executable yet.

Finally, link them together.

This command takes main.o and util.o and stitches them into a single executable named main.

Run it with:

You will see a list of ten random numbers, followed by a dash separator, followed by the sorted list.

Why This Matters

You might ask: why bother with this extra step? Why not just paste the functions into main.c?

Because libraries scale. As your projects grow, you will have dozens of utility functions. Keeping them in separate files allows you to reuse them across different projects