Linux C 编程——语句表达式
语句表达式的定义:
在GNU C中对C标准进行了扩展,允许在一个表达式里内嵌语句,允许在表达式内部使用局部变量。for 和 goto 跳转语句,这样的表达式称之为语句表达式。
语句表达式的格式如下:
({
表达式1;
表达式2;
表达式3;
})
语句表达式最外面语句使用()小括号括起来,里面使用大括号 {} 包起来的是代码块,代码块里面允许内嵌各种语句。语句的格式可以是 “表达式” 这种一般格式的语句,也可以是循环、跳转等语句。
1.语句表达式中使用for语句
#include <stdio.h>
int main(void)
{
int sum = 0;
sum =
({
int s =0;
for(int i =0;i < 10;i++)
s = S + i;
s; //添加一个S;语句表示整个语句表达式的值
});
printf("sum = %d\n", sum);
return 0;
}
下面是不加 S; 语句程序执行的结果sum =0,我们编程的思路是计算1~10 的累加和,所以最后的结果应该等于 sum = 45;,因此我们可以得知语句表达式的值等于最后一个表达式的值。
2.语句表达式中使用goto语句
#include <stdio.h>
int main(void)
{
int sum = 0;
sum =
({
int s = 0;
for(int i = 0; i < 10; i++)
s = s + i;
goto here;
s;
});
printf("sum = %d\n",sum);
here:
printf("here:\n");
printf("sum = %d\n",sum);
return 0;
}
3.在宏定义中使用语句表达式
使用语句表达式来进行宏定义,不仅可以实现复杂的功能,而且还能避免宏定义带来的歧义和漏铜。
样例1:
//定义一个宏,求两个数的最大值
#define MAX(x,y) x > y ? x : y
为了验证上面的宏定义是否正确,编写一个测试样例:
#include <stdio.h>
#define MAX(x,y) x > y ? x : y
int main()
{
printf("MAX = %d\n",MAX(1,2));
printf("MAX = %d\n",MAX(2,1));
printf("MAX = %d\n",MAX(2,2));
printf("MAX = %d\n",MAX(1!=1,1!=2);
return 0;
}
输出结果:
//输出结果
MAX = 2
MAX = 2
MAX = 2
MAX = 0
在执行第四条语句的时候,当宏的参数是一个表达式时,结果和我们预期的不一样,预期结果应该是MAX =1 。这是因为宏展开之后变成了下面这个样子:
printf("MAX =%d\n",1!=1>1!=2?1!=1:1!=2);
这是因为 > 的优先级大于 != 的优先级;为了避免这样的错误,我们要加上小括号()来防止表达式展开之后,表达式的运算顺序发生变化。
合格的宏定义:
#define MAX(x,y) (x) > (y) ? (x) :(y)
进阶宏定义:
上面的宏定义也存在一点点的漏洞,测试代码如下:
#define MAX(x,y) (x) > (y) ? (x) : (y)
int main()
{
printf("MAX = %d\n",3+MAX(1,2));
return 0;
}
//输出结果:MAX = 1
在测试程序中,我们打印表达式 3 +MAX(1,2) 的值,预期结果应该是 5。原因是我们展开后,发现了同样的问题: + 的运算符优先级大于 > ,所以结果输出为1。
改进后的宏定义如下:
#define MAX(x,y) ((x) > (y) ? ((X) :(y))
达式 3 +MAX(1,2) 的值,预期结果应该是 5。原因是我们展开后,发现了同样的问题: + 的运算符优先级大于 > ,所以结果输出为1。
改进后的宏定义如下:
#define MAX(x,y) ((x) > (y) ? ((X) :(y))
后面还有更牛逼的宏定义,咱就不在这里赘述了。以上是参考《嵌入式C语言的自我修养》中的内容进行了整理。