我们经常在 C 语言中会见到三目运算符,那么我们今天来讲下三目运算符和一种特殊的逗号表达式。

首先来讲下三目运算符。什么是三目运算符呢?它的语法格式是 (a ? b : c)。三目运算符可以作为逻辑运算的载体,规则是:当 a 的值为真时,返回 b 的值;否则返回 c 的值。那么三目运算符的返回类型是怎样确定的?有两条规则:a> 通过隐式类型转换规则返回 b 和 c 中的较高类型;b> 当 b 和 c 不能隐式转换到同一类型时将编译出错。从某种程度上来说,它类似于 if ... else ... 语句,if(a) {b}; else {c}; 这样表达是不是更直观呢?

我们下来分析下面这个示例代码进行说明,代码如下:

#include<stdio.h>intmain(){charc=0;shorts=0;inti=0;doubled=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));return0;}

我们根据上面的规则可知,第11行打印的是4,返回的类型应该是 int 型,因为 char 和 short 会隐式转换成 int;第12行应该打印的是8,返回的类型是 double;第13行应该会出错,因为我们在已知的隐式类型转换中没有指针的转换。我们编译下看看是否如我们所分析的那样


那么第13行报的是类型不匹配,我们注释掉再次进行编译,结果如下

结果和我们分析的一样。

下来我们来讲讲逗号表达式:a> 它是 C 语言中的“粘贴剂”; b> 用于将多个子表达式连接为一个表达式; c> 它的值为最后一个子表达式的值; d> 前 N - 1 个子表达式可以没有返回值; e> 按照从左向右的顺序计算每个子表达式的值;

我们来以下面的示例代码进行分析说明,代码如下:

#include<stdio.h>voidhello(){printf("Hello!\n");}intmain(){inta[3][3]={(0,1,2),(3,4,5),(6,7,8)};inti=0;intj=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]);}}return0;}

我们看到第 19 行的 while 循环,因为它下面的语句后面是逗号,一直到 i++ 才是分号,所以它会打印出 0 - 4,并且每句后面跟着一个 hello 函数打印出来的语句。第 26 行的 for 循环,因为之前的数组定义的是逗号的,所以它打印出来的是最后一个数字,也就是 2 5 8 了,其他全是0。我们来看看结果是否跟我们分析的一样

结果跟我们分析的一致。我们可以利用逗号表达式的特性写出用一句话实现的 strlen 函数,代码实现如下:

#include<stdio.h>#include<assert.h>intstrlen(constchar*s){returnassert(s),(*s?strlen(s+1)+1:0);}intmain(){printf("len=%d\n",strlen("hello"));printf("len=%d\n",strlen(NULL));return0;}

在这里我们使用了递归的思想,如果 s 为空串,则调用 C 语言中自带的 assert 函数进行说明,如果不是空的,那么字符加1一直到字符串的最后一位为 '\0' 为止。我们来看看编译结果是否如此

我们会看到调用正常字符串时,会输出它的长度。但如果是空串时,它会对 a.out 中的错误信息进行说明。我们看到如果逗号表达式如果使用的好的话,就会使我们的程序变得非常短小且效率高。

通过对三目运算符和逗号表达式的探究,总结如下:1、三目运算符返回变量的值而不是变量本身,通过隐式类型转换规则确认返回值类型;2、逗号表达式按照从左向右的顺序计算每个子表达式的值,它的值为最后一个子表达式的值。后面我们会继续对 C 语言的学习。


欢迎大家一起来学习 C 语言,可以加我QQ:243343083。