Skip to content

[中文版本](/posts/c教程/zh-CN/10-真实项目/091-Designing Small C Libraries)

Writing libraries is how you make your C code reusable, modular, and easy to maintain. In this section, you’ll learn how to design and structure a small, portable, and well-documented C library, the kind used in real systems for decades.

Step 1. What Is a Library in C? ​

A library in C is a collection of functions and data types that can be used by multiple programs.

There are two kinds of libraries:

  • Static libraries (.a or.lib) – compiled into the final program at build time.
  • Shared libraries (.so or.dll) – loaded dynamically at runtime.

You’ll start by building a small static library that provides reusable math utilities.

Step 2. Plan the Library ​

Let’s design a library called simplemath, which provides:

  • add,subtract,multiply,divide
  • Error handling for divide-by-zero
  • Clean, consistent naming

Structure:

simplemath/
 ├── include/
 │    └── simplemath.h
 ├── src/
 │    └── simplemath.c
 └── Makefile

Step 3. The Header File (simplemath.h) ​

#ifndef SIMPLEMATH_H
#define SIMPLEMATH_H
#ifdef __cplusplus
extern "C" {
#endif
double sm_add(double a, double b);
double sm_sub(double a, double b);
double sm_mul(double a, double b);
double sm_div(double a, double b, int *error);
#ifdef __cplusplus
}
#endif
#endif

Notes:

  • Include guards prevent double inclusion.
  • extern "C" allows usage in C++ projects.
  • Prefix (sm_) prevents naming conflicts.

Step 4. The Implementation File (simplemath.c) ​

#include "simplemath.h"
#include <stdio.h>
double sm_add(double a, double b) { return a + b; }
double sm_sub(double a, double b) { return a - b; }
double sm_mul(double a, double b) { return a * b; }
double sm_div(double a, double b, int *error) {
    if (b == 0) {
        if (error) *error = 1;
        fprintf(stderr, "Division by zero\n");
        return 0.0;
    }
    if (error) *error = 0;
    return a / b;
}

Step 5. Tiny Code: Example Program Using the Library ​

#include <stdio.h>
#include "simplemath.h"
int main(void) {
    int err;
    double x = sm_div(10, 2, &err);
    printf("10 / 2 = %.2f\n", x);
    x = sm_div(10, 0, &err);
    if (err) printf("Error detected during division.\n");
    return 0;
}

Step 6. Makefile to Build the Library ​

CC = gcc
CFLAGS = -std=c23 -O2 -Wall -Wextra -Iinclude
all: libsimplemath.a test
libsimplemath.a: src/simplemath.o
    ar rcs libsimplemath.a src/simplemath.o
src/simplemath.o: src/simplemath.c include/simplemath.h
    $(CC) $(CFLAGS) -c src/simplemath.c -o src/simplemath.o
test: test.c libsimplemath.a
    $(CC) $(CFLAGS) test.c -L. -lsimplemath -o test
clean:
    rm -f src/*.o *.a test

Build it:

make

Run:

./test

Output:

10 / 2 = 5.00
Division by zero
Error detected during division.

Step 7. Design Guidelines for Clean C Libraries ​

PrincipleDescription
Prefix all symbolsAvoid global name clashes (e.g.,sm_add)
Single responsibilityEach function should do one clear thing
Minimal dependenciesDon’t rely on non-standard headers
Use header guardsPrevent duplicate inclusion
Provide error handlingReturn codes,errno, or out parameters
Write documentationUse Doxygen or simple comment blocks
Version your APITrack breaking changes cleanly

Step 8. Adding Versioning and Metadata ​

Add this to your header:

#define SIMPLEMATH_VERSION "1.0.0"

In your CMake or Makefile build scripts, you can propagate this version into your packaging system or documentation.

Step 9. Why It Matters ​

Writing a library transforms you from a script author into a systems builder. It teaches API design, separation of interface and implementation, and long-term maintenance, the same principles used in real-world software like glibc, SQLite, and curl.

Step 10. Try It Yourself ​

  1. Add new functions (sm_pow,sm_mod,sm_avg).
  2. Create a shared version of the library (libsimplemath.so).
  3. Document your API using Doxygen-style comments.
  4. Write a header-only version (static inline functions).
  5. Package your library with versioning and examples.

Next, you’ll learn how to build a full command-line tool in C (92), connecting your reusable libraries to practical, user-facing applications.

本站总访问 — 次