乐趣区

关于c:C进阶18三目运算符和逗号表达式

Summary

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 语言进阶课程》。
如有错漏之处,恳请斧正。

退出移动版