C成语和鲜为人知的事实

Sco*_*ott 7 c arrays macros

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

数组中的元素:

#define ELEMENTS(x) (sizeof (x) / sizeof (*(x)))
Run Code Online (Sandbox Code Playgroud)

奇数数组索引:

a[5] = 5[a]
Run Code Online (Sandbox Code Playgroud)

单行if/else/while /为安全#defines

#define FOO(X) do { f(X); g(X); } while (0)
#define FOO(X) if (1) { f(X); g(X); } else
Run Code Online (Sandbox Code Playgroud)

我对专家C程序员的问题是:在C代码中有哪些成语,实践,代码snippits鲜为人知的事实,但可能不是很直观,但是对C编程提供了很好的洞察力?

Boo*_*jum 12

用于从n-1倒数到0的"箭头运算符":

for ( int i = n; i --> 0; ) ...
Run Code Online (Sandbox Code Playgroud)

它并不常见,但它是一个有趣的例子,在某些方面,n-1循环的初始化/测试/更新部分是惯例.这是通常的模式,但你仍然可以在其中放置任意表达式.

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


Alo*_*hal 6

既然有人会提到它,也可能是我:Duff的设备.这是标签在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);
    }
}
Run Code Online (Sandbox Code Playgroud)

今天,人们不会使用register,并避免旧式功能定义.


mik*_*csh 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;
}
Run Code Online (Sandbox Code Playgroud)

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

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