答疑解惑 | Linux GNU C 与 ANSI C 的区别
扫描二维码
随时随地手机看文章
Linux 上可用的 C 编译器是 GNU C 编译器,它建立在自由软件基金会的编程许可证的基础上,因此可以自由发布。GNU C对标准C进行一系列扩展,以增强标准C的功能。
1.零长度和变量长度数组
GNU C允许使用零长度数组,在定义变长对象的头结构时,这个特性非常有用。例如:struct var_data {
int len;
char data[0];
};
char data[0]仅仅意味着程序中通过var_data结构体实例的data[index]成员可以访问len之后的第index个地址,它并 没有为data[]数组分配内存,因此sizeof(struct var_data)=sizeof(int)。假设struct var_data的数据域就保存在struct var_data紧接着的内存区域中,则通过如下代码可以遍历这些数据:struct var_data s;
...
for (i = 0; i < s.len; i )
printf("x", s.data[i]);
GNU C中也可以使用1个变量定义数组,例如如下代码中定义的“double x[n]”:int main (int argc, char *argv[])
{
int i, n = argc;
double x[n];
for (i = 0; i < n; i )
x[i] = i;
return 0;
}
2.case范围
GNU C支持case x…y这样的语法,区间[x,y]中的数都会满足这个case的条件,请看下面的代码:switch (ch) {
case '0'... '9': c -= '0';
break;
case 'a'... 'f': c -= 'a' - 10;
break;
case 'A'... 'F': c -= 'A' - 10;
break;
}
代码中的case'0'...'9'等价于标准C中的:case '0': case '1': case '2': case '3': case '4':
case '5': case '6': case '7': case '8': case '9':
3.语句表达式
GNU C把包含在括号中的复合语句看成是一个表达式,称为语句表达式,它可以出现在任何允许表达式的地 方。我们可以在语句表达式中使用原本只能在复合语句中使用的循环、局部变量等,例如:#define min_t(type,x,y) \
( { type _ _x =(x);type _ _y = (y); _ _x<_ _y _ _x: _ _y; })
int ia, ib, mini;
float fa, fb, minf;
mini = min_t(int, ia, ib);
minf = min_t(float, fa, fb);
因为重新定义了__xx和__y这两个局部变量,所以用上述方式定义的宏将不会有副作用。在标准C中,对应的如 下宏则会产生副作用:#define min(x,y) ((x) < (y) (x) : (y))
代码min( ia, ib)会展开为(( ia)<( ib)( ia):( ib)),传入宏的“参数”增加两次。4.typeof关键字
typeof(x)语句可以获得x的类型,因此,可以借助typeof重新定义min这个宏:#define min(x,y) ({ \
const typeof(x) _x = (x); \
const typeof(y) _y = (y); \
(void) (