三目运算符(a?b:c)可以作为逻辑运算的载体。
规则:当a的值为真时,返回b的值,否则返回c的值。
观察下面代码:
int main() { int a=1; int b=2; int c=0; c = (a<b ? a:b); // (a<b ? a:b) = 3; *(a<b ? &a : &b) = 3; printf("%d\n", a); printf("%d\n", b); printf("%d\n", c); return 0; }需要注意的是,三目运算符返回的是一个值,而不是一个变量。但是,可以使用地址来操作变量。
上述代码的运行结果为:
3 2 1
也就是说,通过对三目运算符地址的操作,可以修改三目运算符输出变量(a)的值。
三目运算符的返回类型:
通过隐式类型转换规则返回b和c中的较高数据类型;
当b和c不能隐式类型转换为同一类型时将会发生编译错误。
运行下面代码:
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)); error! printf("sizeof(char) = %d\n", sizeof(char)); printf("sizeof(short) = %d\n", sizeof(short)); return 0; }
结果为:
4 8 sizeof(char) = 1 sizeof(short) = 2
逗号表达式:
逗号表达式是C语言中的“粘贴剂”,用于将多个表达式连接为一个表达式,其值为最后一个子表达式的值。
逗号表达式的前n-1个子表达式 都没有返回值,并且从左往右顺序计算每个子表达式的值。
观察下面代码,判断输出:(注意二维数组逗号和分号的使用)
int hello() { printf("hello world!\n"); } int main() { int a[3][3] = //逗号表达式 { (0, 1, 2), //2 (3, 4, 5), //5 (6, 7, 8) //8 }; int b[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, b[i][j]); } } return 0; }
hello world! i = 3 hello world! i = 4 hello world! a[0][0] = 0 a[0][1] = 1 a[0][2] = 2 a[1][0] = 3 a[1][1] = 4 a[1][2] = 5 a[2][0] = 6 a[2][1] = 7 a[2][2] = 8
笔试题:一行代码实现strlen()函数:
#include <stdio.h> int strlen(const char* s) { return (*s ? strlen(s+1)+1 : 0); }
上面的代码基本可以实现strlen()的功能,但是对于空指针参数的话,会出现什么结果呢?
int main() { printf("len = %d\n", strlen("willwilling")); printf("plen = %d\n", strlen(NULL)); //传入空指针 return 0; }
运行结果:
len = 11 段错误
所以针对这种情况,应该修改代码如下:
int strlen(const char *s) // { assert(NULL); return (*s ? strlen(s +1) + 1 : 0); //递归 }
但是并不是一条语句,也无法完成要求,所以这个时候可以使用逗号表达式,将代码修改如下:
int strlen(const char *s) // { return assert(NULL), (*s ? strlen(s +1) + 1 : 0); //递归 }
运行结果如下:
len = 11 a.out: test.c:6: strlen: Assertion `((void *)0)' failed. 已放弃值得注意的地方:
int a = 1; int b = 2; int c[4] = {0}; int m = ((a++) < (b) ? (a++) : (b)); 运行后m=2,a=3.
小结:
三目运算符返回变量的值,而不是变量本身;
三目运算符通过隐式类型转换规则确认返回值的类型;
逗号表达式按照从左往右的顺序运行每个子表达式;
逗号表达式的值为最后一个子表达式的值,所以说前n-1个子表达式可以没有返回值。