你最喜欢的C编程技巧是什么?

例如,我最近在linux内核中遇到了这个问题:

/* Force a compilation error if condition is true */
#define BUILD_BUG_ON(condition) ((void)sizeof(char[1 - 2*!!(condition)]))

所以,在你的代码中,如果你有一些必须的结构,比如8字节的倍数,可能是因为硬件限制,你可以这样做:

BUILD_BUG_ON((sizeof(struct mystruct) % 8) != 0);

除非struct mystruct的大小是8的倍数,并且如果它是8的倍数,则不会生成运行时代码。

我所知道的另一个诀窍是来自“图形宝石”一书,它允许单个头文件在一个模块中声明和初始化变量,而在使用该模块的其他模块中,仅仅声明它们为extern。

#ifdef DEFINE_MYHEADER_GLOBALS
#define GLOBAL
#define INIT(x, y) (x) = (y)
#else
#define GLOBAL extern
#define INIT(x, y)
#endif

GLOBAL int INIT(x, 0);
GLOBAL int somefunc(int a, int b);

那样,定义x和somefunc的代码就会:

#define DEFINE_MYHEADER_GLOBALS
#include "the_above_header_file.h"

而仅仅使用x和somefunc()的代码会执行:

#include "the_above_header_file.h"

所以你得到一个头文件,它声明了全局变量和函数原型的实例,以及相应的extern声明。

那么,你最喜欢的C编程技巧是什么?


C99使用匿名数组提供了一些非常酷的东西:

删除无意义的变量

{
    int yes=1;
    setsockopt(yourSocket, SOL_SOCKET, SO_REUSEADDR, &yes, sizeof(int));
}

setsockopt(yourSocket, SOL_SOCKET, SO_REUSEADDR, (int[]){1}, sizeof(int));

传递可变数量的参数

void func(type* values) {
    while(*values) {
        x = *values++;
        /* do whatever with x */
    }
}

func((type[]){val1,val2,val3,val4,0});

静态链接列表

int main() {
    struct llist { int a; struct llist* next;};
    #define cons(x,y) (struct llist[]){{x,y}}
    struct llist *list=cons(1, cons(2, cons(3, cons(4, NULL))));
    struct llist *p = list;
    while(p != 0) {
        printf("%dn", p->a);
        p = p->next;
    }
}

任何我相信许多其他很酷的技术,我没有想到。


在阅读Quake 2源代码时,我想到了这样的东西:

double normals[][] = {
  #include "normals.txt"
};

(或多或少,我没有代码方便现在检查它)。

从那以后,一个创造性地使用预处理器的新世界在我眼前展开。 我不再仅仅包含头文件,而是包含整个代码块(它大大提高了可重用性):-p

感谢John Carmack! 的xD


我喜欢使用= {0}; 初始化结构而无需调用memset。

struct something X = {0};

这将初始化struct(或数组)的所有成员为零(但不包括任何填充字节 - 如果您还需要将这些字节清零,则使用memset)。

但是,您应该意识到,对于大型动态分配的结构,存在一些问题。

链接地址: http://www.djcxy.com/p/12773.html

上一篇: What is your favorite C programming trick?

下一篇: Practical Use of Zero