• 12 三目运算符和逗号表达式


    1 三目运算符

    1.1 用法

    • 三目运算符(a ? b : c)可以作为逻辑运算的载体

    • 规则:当 a 的值为真时,返回 b 的,否则返回 c 的

    • 示例

      • Demo

        #include <stdio.h>
        
        int main()
        {
            int a = 1;
            int b = 2;
            int c = 0;
            
            c = a < b ? a : b;
            
            (a < b ? a : b) = 3;
            
            printf("a = %d
        ",a);
            printf("b = %d
        ",b);
            printf("c = %d
        ",c);
            
            return 0;
        }
        
      • 编译

        • 分析:三目运算符返回的是一个值,而不是变量本身,不能作为左值
        test.c: In function ‘main’:
        test.c:11: error: lvalue required as left operand of assignment
        
    • 如果想利用三目运算符的返回值改变原先变量的值,那么可以返回地址,再对其解引用

      • Demo

        #include <stdio.h>
        
        int main()
        {
            int a = 1;
            int b = 2;
            int c = 0;
            
            *(a < b ? &a : &b) = 3;
            
            printf("a = %d
        ",a);  // 3
            printf("b = %d
        ",b);  // 2
            printf("c = %d
        ",c);  // 0
            
            return 0;
        }
        

    1.2 返回类型

    • 三目运算符(a ? b : c)的返回值的类型

      • 通过隐式类型转换规则返回 bc 中的较高类型

      • bc 不能隐式转换到同一类型时,编译出错

      • Demo1:可以通过隐式转换

        #include <stdio.h>
        
        int main()
        {
            char c = 0;
            short s = 0;
            int i = 0;
            double d = 0;
            char* p = "str";
            
            printf("sizeof(c ? c : s) = %d
        ",sizeof(c ? c : s));  // 4:int
            printf("sizeof(i ? i : d) = %d
        ",sizeof(i ? i : d));  // 8:double
            
            return 0;
        }
        
      • Demo2:不能隐式转换到同一类型

        #include <stdio.h>
        
        int main()
        {
            char c = 0;
            short s = 0;
            int i = 0;
            double d = 0;
            char* p = "str";
            
            printf("sizeof(d ? d : p) = %d
        ",sizeof(d ? d : p));  // error
            
            return 0;
        }
        
      • 编译

        test.c: In function ‘main’:
        test.c:13: error: type mismatch in conditional expression
        

    2 逗号表达式

    2.1 用法

    • 逗号表达式是 C 语言中的“粘贴剂”

    • 逗号表达式用于将多个子表达式连接为一个表达式

    • 逗号表达式的值为最后一个子表达式的值

    • 逗号表达式中的前N-1个表达式可以没有返回值

    • 逗号表达式按照从左向右的顺序计算每个子表达式的值

    • 形式:exp1,exp2,exp3,...,expN

    • 示例:逗号表达式的使用

      • Demo1

        #include <stdio.h>
        
        int main()
        {
            int i = 0;
            while(i < 5)
                printf("i = %d
        ",i),
            i++;
            
            //等价于
            /*
            while(i < 5)
            {
                printf("i = %d
        ",i);
                i++;
            }
            */
            
            return 0;
        }
        
      • 编译运行

        i = 0
        i = 1
        i = 2
        i = 3
        i = 4
        
      • Demo2

        #include <stdio.h>
        
        void hello()
        {
            printf("Hello
        ");
        }
        
        int main()
        {
            int a[3][3] = {(0,1,2),(3,4,5),(6,7,8)};
            
            int i = 0;
            int j = 0;
            
            while(i < 5)
                printf("i = %d
        ",i),
            hello(),
            i++;
            
            for(i=0;i<3;i++){
                for(j=0;j<3;j++){
                    printf("a[%d][%d] = %d
        ",i,j,a[i][j]);
                }
            }
            
            return 0;
        }
        
      • 编译运行

        • 为什么 while 循环后面没有大括号也都运行 5 次:因为三条语句构成了逗号表达式,即为一个表达式:

          while(i < 5) printf("i = %d ",i),hello(),i++;

        • 数组变成了:{2,5,8,0,0,0,0,0,0}:因为数组 a[3][3] 的定义构成了逗号表达式,相当于 int a[3][3] = {2,5,8}; ,修改:int a[3][3] = {{0,1,2},{3,4,5},{6,7,8}}

        i = 0
        Hello
        i = 1
        Hello
        i = 2
        Hello
        i = 3
        Hello
        i = 4
        Hello
        a[0][0] = 2
        a[0][1] = 5
        a[0][2] = 8
        a[1][0] = 0
        a[1][1] = 0
        a[1][2] = 0
        a[2][0] = 0
        a[2][1] = 0
        a[2][2] = 0
        
    • 示例:一行代码实现 strlen

      • Demo

        #include <stdio.h>
        #include <assert.h>
        
        int strlen(const char* s)
        {
            //s+1是将指针指向下一个字符,strlen(s+1)+1是指长度=去掉当前字符的字符串的长度加1
            return assert(NULL) , (*s ? strlen( s + 1) + 1 : 0);
        }
            
        int main()
        {
            printf("len = %d
        ",strlen("ABCDEF"));
            printf("len = %d
        ",strlen(NULL));
            
            return 0;
        }
        
      • 编译运行

        len = 6
        test: test.c:7: strlen: Assertion `((void *)0)' failed.
        已放弃
        
  • 相关阅读:
    面向接口编程详解(二)——编程实例
    面向接口编程详解(一)——思想基础
    设计模式之面向接口编程
    EF数据注解
    很多人不知道可以使用这种 key 的方式来对 Vue 组件时行重新渲染
    这是最新的一波Vue实战技巧,不用则已,一用惊人
    Node.js 进阶-你应该知道的 npm 知识都在这
    Vue响应式原理
    eslint规则
    简述vue-cli中chainWebpack的使用方法
  • 原文地址:https://www.cnblogs.com/bky-hbq/p/13599067.html
Copyright © 2020-2023  润新知