1 三目运算符
- 三目运算符(a?b:c)可以作为逻辑运算的载体
- 规则: 当a为真时,返回b,否则返回c的值
如下面的代码:
#include <stdio.h>
int main()
{
int a = 1;
int b = 2;
int c = 0;
c = a < b ? a : b;
//(a < b ? a : b) = 3;
printf("%d\n", a);
printf("%d\n", b);
printf("%d\n", c);
return 0;
}
- 运行结果为:
1
2
1
-
上面的代码中,第11行给注释掉了。这行代码写的有问题。
-
因为三目运算符是返回变量的值,而不是变量本身,所以11行中,左操作符是返回的一个具体的值,对这个值再赋值,肯定是错误的。(虽然它返回的是一个具体的数字,但是这个数字也是有数据类型的,具体是什么类型,下面会讲。)
(a?b:c),如果b与c的类型不一样,返回值应该是什么类型?
- 通过隐式类型转换规则,返回较高类型
- 当b和c不能隐式转换为同一类型时,编译将会出错
比如在下图中的三个三目运算符中,第三个printf中的double类型和 *p 指针类型不能转换,将会编译期间报错。
1.1 三目运算符的返回类型的代码案例分析
- 代码:18-2.c
#include <stdio.h>
int main()
{
char c = 0;
short s = 0;
int i = 0;
double d = 0;
char* p = "str";
printf( "%d\n", sizeof(c ? c : s) );
printf( "%d\n", sizeof(i ? i : d) );
printf( "%d\n", sizeof(d ? d : p) );
return 0;
}
- 使用gcc 4.4.5 编译程序显示如下错误:
- 将第13行注释掉编译运行结果如下:
- 第一个为什么是4。实际上是因为第一个返回了int类型。具体类型转换的规则参考C语言中的类型转化
2 逗号表达式
在C语言中:
- 逗号表达式是C预压的一种“粘结剂”
- 逗号表达式用于将多个子表达式连接为一个表达式
- 逗号表达式的值为最后一个子表达式的值
- 逗号表达式的前N-1个子表达式可以没有返回值,最后一个子表达式有返回值即可
- 逗号表达式按照从左向右的顺序计算每个表达式的值
2.1 逗号表达式代码案例分析
- 代码 18-3.c
#include <stdio.h>
void hello(){
printf("Hello!\n");
}
int main(){
int a[3][3]={
(0,1,2),
(3,4,5),
(6,7,8)
};
int i = 0;
int j = 0;
while(i < 5)
printf("i = %d\n", i),
hello(),
i++;
for(i=0;i<3;++i){
for(j=0;j<3;++j){
printf("a[%d][%d] = %d\n", i,j,a[i][j]);
}
}
return 0;
}
- 上述代码编译运行结果为:
- 第一个while循环后的三个语句,都是逗号表达式的一员,所以while循环5次
- 定义数组a的时候,由于是使用的圆括号,里面的定义也是三个逗号表达式。应该改成下面的定义:
int a[3][3]={
{0,1,2},
{3,4,5},
{6,7,8}
};
那么结果就是正确的。注意逗号表达式的使用。
2.2 如何用一行代码实现 strlen函数
- 代码 18-4.c
#include <stdio.h>
#include <assert.h>
int strlen(const char* s){
return assert(s),(*s ? strlen(s+1)+1 : 0);
}
int main(){
printf("len = %d\n", strlen("Delphi"));
printf("len = %d\n", strlen(NULL));
return 0;
}
- 编译运行结果如下:
- 是不是体会到了逗号表达式与三目运算符的妙用?
3 总结
- 三目运算符返回变量值,而不是变量本身
- 三目运算符通过隐式类型转换的规则确定的返回值的类型
- 逗号表达式按照从左向右的顺序计算每个子表达式的值
- 逗号表达式的值为最后一个子表达式的值