好的,我在这里看过很多关于C中奇怪的习语和常见做法的帖子,这些帖子可能最初并不直观。也许有几个例子是按顺序
数组中的元素:
#define ELEMENTS(x) (sizeof (x) / sizeof (*(x)))
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编程?
答案 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
,并且避免使用旧式函数定义。