C成语和鲜为人知的事实

时间:2009-12-29 17:44:34

标签: c arrays macros

好的,我在这里看过很多关于C中奇怪的习语和常见做法的帖子,这些帖子可能最初并不直观。也许有几个例子是按顺序

数组中的元素:

#define ELEMENTS(x) (sizeof (x) / sizeof (*(x)))

Odd array indexing:

a[5] = 5[a]

Single line if/else/while/for safe #defines

#define FOO(X) do { f(X); g(X); } while (0)
#define FOO(X) if (1) { f(X); g(X); } else

我向专家C程序员提出的问题是:成语做法代码snippits 鲜为人知的事实在C代码中显示了很多,但可能不是很直观但是能够很好地洞察C编程?

3 个答案:

答案 0 :(得分:12)

从n-1倒数到0的“箭头操作符”:

for ( int i = n; i --> 0; ) ...

这并不是很常见,但这是一个有趣的例子,在某些方面,for循环的初始化/测试/更新部分是惯例。这是通常的模式,但你仍然可以在那里放任意表达。

这也是关于词汇分析如何运作的一个很好的小提醒。

答案 1 :(得分:5)

逗号运算符虽然有很好的文档记录(K& R等)出现在相当多的算法代码中,但对于之前没有遇到它的许多程序员来说往往是一个惊喜。它通常用于简化一些循环结构:

#define kITERATIONS_MAX 10
int i=0,j=0,array[kITERATIONS_MAX],outArray[kITERATIONS_MAX],temp=0;

for (i=0,j=kITERATIONS_MAX-1; i < kITERATIONS_MAX; i++,j--)
{
temp = array[i]*array[j];
outArray[i]=temp;
}

上面的代码将数组元素0到9与9到0相乘,同时避免嵌套循环。

使用逗号运算符时,将计算第一个和第二个表达式。忽略第一个表达式的结果,并返回第二个表达式的结果。

答案 2 :(得分:5)

既然有人会提到它,也可能是我:Duff's Device。这是标签在C中工作方式的一个很好的例证,理解它第一次给了我一个“aha体验”。这是他的原始代码:

send(to, from, count)
register short *to, *from;
register count;
{
    register n=(count+7)/8;
    switch(count%8){
    case 0: do{ *to = *from++;
    case 7:     *to = *from++;
    case 6:     *to = *from++;
    case 5:     *to = *from++;
    case 4:     *to = *from++;
    case 3:     *to = *from++;
    case 2:     *to = *from++;
    case 1:     *to = *from++;
        }while(--n>0);
    }
}

今天,人们不会使用register,并且避免使用旧式函数定义。