三目运算符:
在C语言中,三目运算符不能当左值使用。因为三目运算符最终返回的是一个值并不是一个变量。三目运算符作为左值时,相当于2 = 3,这种赋值,编译器当然会报错。
既然三目元算符返回的是一个值,那么有没有办法将它当做左值又不报错呢?
解决方案就是返回变量的地址。
第13行返回变量的地址。
运算结果如下:
三目运算符的返回类型是什么呢?
示例程序如下:
1 #include <stdio.h> 2 3 int main() 4 { 5 char c = 0; 6 short s = 0; 7 int i = 0; 8 double d = 0; 9 char* p = "str"; 10 11 printf( "%d ", sizeof(c ? c : s) ); 12 printf( "%d ", sizeof(i ? i : d) ); 13 printf( "%d ", sizeof(d ? d : p) ); 14 15 return 0; 16 }
编译结果如下:
提示我们第13行类型不匹配。因为d和p不能转换到同一类型。普通类型不能转换为指针类型(除非强制类型转换)。
将第13行注释掉,运行结果如下:
可见第11行转换为了int,第12行转换为了double。
逗号表达式:
逗号表达式将最后一个子表达式的值作为整个表达式的值。因此,前n-1个表达式可以没有返回值。
下面的程序输出什么?
示例程序如下:
1 #include <stdio.h> 2 3 void hello() 4 { 5 printf("Hello! "); 6 } 7 8 int main() 9 { 10 int a[3][3] = { 11 (0, 1, 2), 12 (3, 4, 5), 13 (6, 7, 8) 14 }; 15 16 int i = 0; 17 int j = 0; 18 19 while( i < 5 ) 20 printf("i = %d ", i), 21 22 hello(), 23 24 i++; 25 26 for(i=0; i<3; i++) 27 { 28 for(j=0; j<3; j++) 29 { 30 printf("a[%d][%d] = %d ", i, j, a[i][j]); 31 } 32 } 33 34 return 0; 35 }
运行结果如下:
没有大括号时,while只作用与它后面的一条语句,但是我们程序中的第19-24行是不能这样分析的,因为while后面的一条语句之后是逗号而不是分号,这就和后面的几行语句构成了逗号表达式。
变形之后如下所示:
while只作用于其后的一个表达式,只不过这个表达式是一个逗号表达式,包含三个子表达式。
第10-14行给二维数组赋值也是一样,11-13行每一行都是一个逗号表达式,每个逗号表达式只会返回最后一个数,最终返回了2,5,8。将这三个元素赋值给数组元素,其它没有赋值到的默认为0。
变形之后如下:
逗号表达式有连接剂的作用,但是并不是我们上图中程序这样用的。这样只会使程序难懂。
正确使用方法:
一行代码实现strlen:
1 #include <stdio.h> 2 #include <assert.h> 3 4 int strlen(const char* s) 5 { 6 return assert(s), (*s ? strlen(s + 1) + 1 : 0); 7 } 8 9 int main() 10 { 11 printf("len = %d ", strlen("Delphi")); 12 printf("len = %d ", strlen(NULL)); 13 14 return 0; 15 }
运行结果如下:
assert断言失败,整个进程就会退出。
小结:
三目运算符返回变量的值,而不是变量本身
三目运算符通过隐式类型转换规则确认返回值类型
逗号表达式按照从左向右的顺序计算每个子表达式的值
逗号表达式的值为最后一个子表达式的值