总结几个C 语言比较高级的编写技巧
看了一些源代码,这里总结几个不常见的,但是比较好用的C 用法。也许这些功能在C++中有扩展,但是个人基本不用C++。其实这些应该是属于预处理器的功能。若是之前没有见过,遇到时会感觉云里雾里的。
-
结构体直接赋值
C99 支持直接将一个结构常量赋值给对应的结构体变量。而不用每个结构成员逐一赋值。
typedef struct rectangle{ int x0; int y0; int x1; int y1; }rect_t; void main() { rect_t a = {0, 0, 0, 0}; a = (rect_t) {0, 0, 1, 2}; }
-
如何在编译阶段就知道结构体长度?
可以定义一个数组指针:
char (*__kaboom)[sizeof( YourTypeHere )] = 1;
编译时它就会产生一个warning,这样就可以知道它的长度了:
warning C4047: 'initializing': 'DWORD (*)[88]' differs in levels of indirection from 'int'
同样也可以用 offsetof() 就知道成员的偏移量了。
-
直接定义字符串:
我们可以用#define 定义字符串常量,比如: #define HELLO “hello” 这样就相当于是: char *HELLO= “hello”; 而且使用#define 来定义的好处是可以直接拼接字符串,这些应该都是由预处理器来帮我们处理的(没有仔细考证,但想像其中原理应该是这样)。比如:``` #define HELLO “hello” #define WORLD “world”
puts( HELLO WORLD );
-
定义内存池:
在嵌入式系统中一般不用内存堆的动态分配,因为容易产生内存碎片导致大块内存分配不到(可以用带小块内存合并功能内存管理方式),或者是会因为某个模块把内存堆耗尽了导致其它模块不能工作。通常会使用内存池的方式,而且每个软件模块有自己的不同大小固定数量内存池,这样可以做到每个模块内存互不干扰。说白一点就是一系列的分配好空间的数组。这可以参考lwip中内存池的分配。
#define LWIP\_MEMPOOL(name,num,size,desc) u8\_t memp\_memory\_ ## name ## \_base \[((num) \* (MEMP\_SIZE + MEMP\_ALIGN\_SIZE(size)))\];