【C进阶】18、三目运算符和逗号表达式

Summary 【【C进阶】18、三目运算符和逗号表达式】1)在C语言中,三目运算符返回的结果是一个右值,并不是一个变量(不能放在赋值符号左侧)
2)三目运算符的返回类型

  • 通过隐式类型转换规则返回b和c中的较高类型(注意:char和short在运算时会隐式转换成int)
  • 当b和c不能隐式转换到同一类型时编译出错
3)逗号表达式(exp1, exp2, ... expN)
  • 逗号表达式用于将多个子表达式连接为一个表达式
  • 逗号表达式的值为最后一个子表达式的值(前N-1个子表达式可以没有返回值)
  • 计算顺序为从左到右
4)一般一行代码实现某种功能时,往往需要用到递归 + 逗号表达式 + 三目运算符
三目运算符和逗号表达式 1、三目运算符 三目运算符(expression ? a : b):当expression的值为真时,返回a的值;否则返回b的值
  • 代码阅读
    int a = 1; int b = 2; int c = 0; c = a < b ? a : b; // c = 1 (a < b ? a : b) = 3; // error, lvalue required as left operand of assignment

三目运算符(expression ? a : b)的返回类型:
  • 通过隐式类型转换规则返回b和c中的较高类型
  • 当b和c不能隐式转换到同一类型时编译出错
    char c = 0; short s = 0; int i = 0; double d = 0; char* p = "str"; printf("%d\n", sizeof(c ? c : s)); // 4, 返回类型隐式转换为int printf("%d\n", sizeof(i ? i : d)); // 8,返回类型隐式转换为double printf("%d\n", sizeof(d ? d : p)); // error,double和char*不能隐式类型转换为同一类型

2、逗号表达式 逗号表达式(exp1, exp2, ... expN)
  • 逗号表达式用于将多个子表达式连接为一个表达式
  • 逗号表达式的值为最后一个子表达式的值(前N-1个子表达式可以没有返回值)
  • 计算顺序为从左到右
    // 以下代码会输出什么? int i = 0; while (i < 5) printf("i = %d\n", i),i++; // 分析,这段代码并不会编译失败,也不会死循环,因为这是一个逗号表达式 int i = 0; while(i < 5) printf("i = %d\n", i), i++;

  • // 以下代码会输出什么? int a[3][3] = { (0, 1, 2), (3, 4, 5), (6, 7, 8) }; int i=0, j=0; for(i = 0; i<3; i++) { for(j = 0; j<3; j++) { printf("a[%d][%d] = %d\n", i, j, a[i][j]); } }// 分析 这段代码并不会像乍看一样输出 0 ~ 8,而输出的是2, 5, 8, 0, 0, ... 原因在于逗号表达式。初始化时使用的是逗号表达式,而不是花括号{} 相当于: int a[3][3] = {2, 5, 8};

3、一行代码实现strlen 递归 + 三目运算符 + 逗号表达式
  • 版本一,未考虑空指针,入参为NULL时会崩溃
    int myStrlen(const char* s) { return (*s ? myStrlen(s+1)+1 : 0); }

  • 版本二,考虑空指针,使用嵌套的三目运算符
    int myStrlen(const char* s) { return (s == NULL ? -1 : *s ? myStrlen(s+1)+1 : 0); }

  • 版本三,使用assert断言,逗号表达式 + 三目运算符
    int myStrlen(const char* s) { return (assert(s), *s ? myStrlen(s+1)+1 : 0); }

本文总结自“狄泰软件学院”唐佐林老师《C语言进阶课程》。
如有错漏之处,恳请指正。

    推荐阅读