What methods are there to modularize C code?

2020-05-26 10:20发布

What methods, practices and conventions do you know of to modularize C code as a project grows in size?

8条回答
趁早两清
2楼-- · 2020-05-26 10:58

A function should do one thing and do this one thing well.

Lots of little function used by bigger wrapper functions help to structure code from small, easy to understand (and test!) building blocks.

Create small modules with a couple of functions each. Only expose what you must, keep anything else static inside of the module. Link small modules together with their .h interface files.

Provide Getter and Setter functions for access to static file scope variables in your module. That way, the variables are only actually written to in one place. This helps also tracing access to these static variables using a breakpoint in the function and the call stack.

One important rule when designing modular code is: Don't try to optimize unless you have to. Lots of small functions usually yield cleaner, well structured code and the additional function call overhead might be worth it.

I always try to keep variables at their narrowest scope, also within functions. For example, indices of for loops usually can be kept at block scope and don't need to be exposed at the entire function level. C is not as flexible as C++ with the "define it where you use it" but it's workable.

查看更多
戒情不戒烟
3楼-- · 2020-05-26 10:59

Breaking the code up into libraries of related functions is one way of keeping things organized. To avoid name conflicts you can also use prefixes to allow you to reuse function names, though with good names I've never really found this to be much of a problem. For example, if you wanted to develop your own math routines but still use some from the standard math library, you could prefix yours with some string: xyz_sin(), xyz_cos().

Generally I prefer the one function (or set of closely related functions) per file and one header file per source file convention. Breaking files into directories, where each directory represents a separate library is also a good idea. You'd generally have a system of makefiles or build files that would allow you to build all or part of the entire system following the hierarchy representing the various libraries/programs.

查看更多
做自己的国王
4楼-- · 2020-05-26 11:01

Create header files which contain ONLY what is necessary to use a module. In the corresponding .c file(s), make anything not meant to be visible outside (e.g. helper functions) static. Use prefixes on the names of everything externally visible to help avoid namespace collisions. (If a module spans multiple files, things become harder., as you may need to expose internal things and not be able hide them with "static")

(If I were to try to improve C, one thing I would do is make "static" the default scoping of functions. If you wanted something visible outside, you'd have to mark it with "export" or "global" or something similar.)

查看更多
相关推荐>>
5楼-- · 2020-05-26 11:03

OO techniques can be applied to C code, they just require more discipline.

  • Use opaque handles to operate on objects. One good example of how this is done is the stdio library -- everything is organised around the opaque FILE* handle. Many successful libraries are organised around this principle (e.g. zlib, apr)
  • Because all members of structs are implicitly public in C, you need a convention + programmer discipline to enforce the useful technique of information hiding. Pick a simple, automatically checkable convention such as "private members end with '_'".
  • Interfaces can be implemented using arrays of pointers to functions. Certainly this requires more work than in languages like C++ that provide in-language support, but it can nevertheless be done in C.
查看更多
闹够了就滚
6楼-- · 2020-05-26 11:03

The High and Low-Level C article contains a lot of good tips. Especially, take a look at the "Classes and objects" section.

Standards and Style for Coding in ANSI C also contains good advice of which you can pick and choose.

查看更多
爷的心禁止访问
7楼-- · 2020-05-26 11:03
  1. Don't define variables in header files; instead, define the variable in the source file and add an extern statement (declaration) in the header. This will tie into #2 and #3.
  2. Use an include guard on every header. This will save so many headaches.
  3. Assuming you've done #1 and #2, include everything you need (but only what you need) for a certain file in that file. Don't depend on the order of how the compiler expands your include directives.
查看更多
登录 后发表回答