zoukankan      html  css  js  c++  java
  • C 语言-运算符(算术运算符,类型转换,赋值运算符,自增,自减,sizeof 运算符,逗号运算符,关系运算符,逻辑运算符,三目运算符)

    目录

    运算符划分

    • 按照功能划分:

      • 算术运算符
      • 关系运算符
      • 逻辑运算符
      • 按位运算符
    • 按照参与运算的操作个数进行划分

      • 单目运算符

        • 只有一个操作数 如:i++
      • 双目运算符

        • 有两个操作数 如:a+b
      • 三目运算符

        • 有三个操作数 如:a > b ? 1:0 如果a>b时,a = 1,如果a<b时,a = 0

    运算符的优先级表

    • 运算符的优先级分为15级别,1级最高,15级最低

    • 在表达式中优先级高的优先于优先级低的先运算

    • 在一个运算量两侧的,优先级一样时按照运算符的结合性所规定的方向进行运算

      优先级运算符名称或含义使用形式结合方向说明
      1 [] 数组下标 数组名[常量表达式] 左到右  
        () 圆括号 (表达式)/函数名(形参表)    
        . 成员选择(对象) 对象.成员名    
        -> 成员选择(指针) 对象指针->成员名    
      2 - 负号运算符 -表达式 右到左 单目运算符
        (类型) 强制类型转换 (数据类型)表达式    
        ++ 自增运算符 ++变量名/变量名++ 单目运算符  
        -- 自减运算符 --变量名/变量名-- 单目运算符  
        * 取值运算符 *指针变量 单目运算符  
        & 取地址运算符 &变量名 单目运算符  
        ! 逻辑非运算符 !表达式 单目运算符  
        ~ 按位取反运算符 ~表达式 单目运算符  
        sizeof 长度运算符 sizeof(表达式)    
      3 / 表达式/表达式 左到右 双目运算符
        * 表达式*表达式 双目运算符  
        % 余数(取模) 整型表达式/整型表达式 双目运算符  
      4 + 表达式+表达式 左到右 双目运算符
        - 表达式-表达式 双目运算符  
      5 << 左移 变量<<表达式 左到右 双目运算符
        >> 右移 变量>>表达式 双目运算符  
      6 > 大于 表达式>表达式 左到右 双目运算符
        >= 大于等于 表达式>=表达式 双目运算符  
        < 小于 表达式<表达式 双目运算符  
        <= 小于等于 表达式<=表达式 双目运算符  
      7 == 等于 表达式==表达式 左到右 双目运算符
        != 不等于 表达式!= 表达式 双目运算符  
      8 & 按位与 表达式&表达式 左到右 双目运算符
      9 ^ 按位异或 表达式^表达式 左到右 双目运算符
      10 | 按位或 表达式|表达式 左到右 双目运算符
      11 && 逻辑与 表达式&&表达式 左到右 双目运算符
      12 || 逻辑或 表达式||表达式 左到右 双目运算符
      13 ?: 条件运算符 表达式1? 表达式2: 表达式3 右到左 三目运算符
      14 = 赋值运算符 变量=表达式 右到左  
        /= 除后赋值 变量/=表达式    
        *= 乘后赋值 变量*=表达式    
        %= 取模后赋值 变量%=表达式    
        += 加后赋值 变量+=表达式    
        -= 减后赋值 变量-=表达式    
        <<= 左移后赋值 变量<<=表达式    
        >>= 右移后赋值 变量>>=表达式    
        &= 按位与后赋值 变量&=表达式    
        ^= 按位异或后赋值 变量^=表达式    
        |= 按位或后赋值 变量|=表达式    
      15 , 逗号运算符 表达式,表达式,… 左到右 从左向右顺序运算
    • 虽然说运算符有很多,但是不用记住,使用小括号()扩起来就好了

    结合性简单介绍

    • c语言中有两种结合性,一种是左结合型,一种是右结合性
    • 左结合性--自左至右运算,右结合性--自右至左运算
    • 左结合性 例如:x + y -z,先计算x+y,计算后的结果再减z
    • 右结合性 例如:x = y = z, 将z的值赋值给y,再将y的值赋值给x

    算数运算符表

    运算符术语示例结果
    + 正号 +3 3
    - 负号 -3 -3
    + 10 + 5 15
    - 10 - 5 5
    * 10 * 5 50
    / 10 / 5 2
    % 取模(取余) 10 % 3 1
    ++ 前自增 a=2; b=++a; a=3; b=3;
    ++ 后自增 a=2; b=a++; a=3; b=2;
    -- 前自减 a=2; b=--a; a=1; b=1;
    -- 后自减 a=2; b=a--; a=1; b=2;
    #include <stdio.h>
    
    int main(int argc, const char * argv[]) {
        /*
         +  加法
         -  减法
         *  乘法
         /  除法
         %  取模(取余)
         */
        int result;
        result = 1 + 1;
        printf("加法结果:result = %i
    ",result);
        result = 1 - 1;
        printf("减法结果:result = %i
    ",result);
        result = 2 * 3;
        printf("乘法结果:result = %i
    ",result);
        result = 10 / 2;
        printf("除法结果:result = %i
    ",result); // result = 5
        result = 10 % 3;
        printf("取模结果:result = %i
    ",result); // result = 1
      
        return 0;
    }

    取模运算符的注意点

    • 注意:取模运算只能对整数取模,不能对实数取模
        // 注意取模运算只能是整数取模不能是实数取模
        // result = 10.5 % 3; // 直接报错
    • 注意:取模运算的正负性,取决于左边的操作数
        // 取模运算的正负性,取决于左边的操作数
        result = 10 % -3;
        printf("取模正负性结果:result = %i
    ",result); // result = 1
        result = -10 % -3;
        printf("取模正负性结果:result = %i
    ",result); // result = -1
        result = -10 % 3;
        printf("取模正负性结果:result = %i
    ",result); // result = -1
        result = -0 % -3;
        printf("取模正负性结果:result = %i
    ",result); // result = 0
    • 注意:如果取模运算中,左边操作数小于右边操作数,那结果直接就是左边操作数,不会进行计算了
     // 如果取模运算中,左边操作数小于右边操作数,那结果直接就是左边操作数,不会进行计算了
        result = 10 % 100;
        printf("取模结果:result = %i
    ",result); // result = 10

    算术运算符的结合性

     // 算术运算符的结合性
        result = 3 + 4 + 5 + 6;
        printf("result的值是%i",result);

    算术运算符的优先级和结合性同时存在时

    • 先优先级,再按照结合性
     // 优先级+结合性
        result = 2 + 3 * 4 -4;
        printf("result的值是%i
    ",result); // 先计算乘法,再从左至右的结合性计算

    类型转换

    • 隐式转换
        // 系统自动进行的转换
        int number = 10.8;
        printf("number的值是%i
    ",number); // number = 10,
        // 大类型的转换成小类型的,系统会自动进行转换,由大类型转换为小类型,丢失精度
    • 显式转换
        // 显式转换-只需要在值前面加(类型)
        int value = (int)10.8;
        printf("value的值是%i
    ",value); // 10;
        // 大类型的转换成小类型的,系统会自动进行转换,由大类型转换为小类型,丢失精度
    • 在算术运算中,类型不一致时,系统会先将类型统一,统一成大类型进行计算
        // 在算术运算中,类型不一致时,系统会先将类型统一,统一成大类型进行计算
        int value2 = 10 + 9.9;
        // 10是int类型,9.9是double类型,int类型占4个字节,9.9占8个字节,所以先将int转为double类型
        // int value2 = 10.0 + 9.9
        // int value2 = 19.9
        // value2 是一个int类型,但是右边的19.9是double类型,这时候系统会做隐式转换,大类型转为小类型,既结果为19
        printf("value2的值是%i
    ",value2); // 19;
    • 算术运算符的注意点-参与运算的操作数是什么类型,那么计算出来的结果就是什么类型
        // 算术运算符的注意点-参与运算的操作数是什么类型,那么计算出来的结果就是什么类型
        int value3 = 1 / 2;
        printf("value3的值是%i
    ",value3); // 打印出来的是0
        // 此时你会不会觉得是因为定义的变量是int类型导致的呢?那我就换成double类型的看看
        double value3 = 1 / 2;
        printf("value3的值是%lf
    ",value3); // 打印出来的是0.000000 此时还是0
        // 是因为右侧参与运算的都是整数,那么计算的结果肯定是整数
    
    
         // 那么如果需要打印出0.5该怎么办呢?
        double value4 = 1.0 / 2; // 此时一个double除以int类型,肯定是都先转换为doublee类型,计算出的结果就是double类型,i定义的变量也是double类型不需要转换所以打印出的是0.500000
        printf("value4的值是%.1lf
    ",value4);
        
        int value5 = 1.0 / 2;
        printf("value5的值是%i
    ",value5); // 0
    • 新手注意常犯的错误
        // 新手注意饭的错误
        double value6 = (double)(1 / 2);
        // 右边先计算括号中的1 / 2,那么两个整数相除,结果肯定是整数,所以是0 ,由强转为double类型,为0.000000
        printf("value6的值是%lf",value6); // 0.000000
    • 在算术运算符中,实数的计算都是double类型,不是float类型

    赋值运算符

    • 最简单的赋值运算符,将等号右边的值赋值给等号左边的变量
      • 赋值运算符的结合性是右结合性
    int main(int argc, const char * argv[]) {
        // 最简单的赋值运算符,将等号右边的值赋值给等号左边的变量
        // 赋值运算符的结合性是右结合性
        int number = 10;
        int a;
        int b;
        a = b = 5;
        printf("a的值是%i,b的值是%i
    ",a,b);
        return 0;
    }
    • 符合赋值运算符
      • 定义:在赋值符“=”加上其他的二目运算符可构成复合赋值运算符

    赋值运算符的作用是将常量、变量或表达式的值赋给某一个变量。

    运算符术语示例结果
    = 赋值 a=2; b=3; a=2; b=3;
    += 加等于 a=0; a+=2; a = a + 2 a=2;
    -= 减等于 a=5; a-=3; a = a - 3 a=2;
    *= 乘等于 a=2; a*=2; a = a * 2 a=4;
    /= 除等于 a=4; a/=2; a = a / 2 a=2;
    %= 模等于 a=3; a%2; a = a % 2 a=1;
        int a = 0;
        a += 3; // 这种是直接进行赋值,运算效率要好
        a = a +3; // 这一种是不是先计算再赋值给a
        printf("a的结果是%i
    ",a);
    // 复合赋值运算,会先进行右边的表达式得到的值在赋值给左边的变量

    自增,自减运算符

    • 自增自减的第一种写法: 变量++,变量--
        int result = 10;
        result++;
        result++;
        printf("变量++,自增后的result值为:%i
    ",result); // 12
        // 如果想让某一个数减1,可以使用变量--,--变量
        int value = 5;
        value--;
        printf("变量--,自增后的value值为:%i
    ",value); // 4
    • 自增自减的第二种写法: --变量,++变量
    // 第二种写法:++变量,--变量
        int result1 = 10;
        ++result1;
        printf("++变量,自增后的result1值为:%i
    ",result1); // 11
        
        int result2 = 5;
        --result2;
        printf("++变量,自增后的result1值为:%i
    ",result2); // 4
    • ​ ++,-- 在变量前面和++,-- 在变量后面的区别(在变量之前先运算再自增,在变量之后先自增再运算)
        // ++,-- 在变量前面和++,-- 在变量后面的区别
        // ++ , -- 在后面时,先参与运算然后再自增
        int a = 10;
        int b = a++;
        printf("a的值是%i,b的值是%i
    ",a,b);// a的值是11,b的值是10 注意看b的值是10,而不是11,这里是a先赋值给b,然后再自增的
        
        // ++ --在变量之前时,是先自增再赋值
        int c = 10;
        int d = ++c;
        printf("c的值是%i,d的值是%i
    ",c,d); // c的值是11,d的值是11 注意看这里d的值同样是11,所以c是先自增再赋值给d
    • 自增,自减练习
        // 练习
        /*
        int a = 10;
        int b = (a++) + (++a);
        //  b = a++ ,此时a++的结果是11, 后面++a在a=11的基础上再自增,那么a的值就是12了,10+12
        //  a =12
        printf("b的值是%i,a的值是%i
    ",b,a);
        */
        /*
        int a = 10;
        int b = (a++) + (a++);
        printf("b的值是%i,a的值是%i
    ",b,a); // b = 10 + 11 , a = 12
        */
        /*
        int a = 10;
        int b = (++a) + (++a);
        printf("b的值是%i,a的值是%i
    ",b,a); // b = 11 + 12 ,a = 12
        */
        /*
        int a = 10;
        int b = (++a) + (a++);
        printf("b的值是%i,a的值是%i
    ",b,a); // b = 11 + 11, a = 12
        */
        int a = 10;
        int b = (a++) + (a--);
        printf("b的值是%i,a的值是%i
    ",b,a); // b = 10 + 11 , a = 10
    • 自增的拆分
        // 自增的拆分
        int a = 10;
        int b = a++;
        // 拆分:
        // 1, int b = a;
        // 2, int a = a+1;
        printf("b的值是%i,a的值是%i
    ",b,a); // b = 10,a = 11
        
        int c = 10;
        int d = ++c;
        // 拆分
        // 1,int c = c + 1;
        // 2,int d = c;
        printf("d的值是%i,c的值是%i
    ",d,c);
        // 拆分之后,只是两个表达式的顺序反了. 如果有时确实难懂的话不妨拆分一下

    sizeof运算符

    • 介绍:sizeof运算符可以用来计算一个变量或一个常量,一种数据类型所占的内存节数

    • 格式:sizeof(变量/常量/数据类型)

    • 注意:sizeof 不是一个函数而是一个运算符(只要是运算符就会有一个返回值)

    • 计算常量的内存字节

        // 使用 sizeof 计算常量的内存字节
        int number = sizeof(10.9);
        printf("10.9的e内存字节是%i
    ",number); // 8
    • 计算变量的内存字节
        int a = 10;
        // int number = sizeof(a); // 只要是运算符就会有返回值
        int number = sizeof a; // 不加s括号e也可以
        printf("a的内存字节是%i
    ",number);
    • 计算数据类型的内存字节(sizeof的括号不能省略)
        // 使用 sizeof 计算数据类型的内存字节
        int numChar = sizeof(char);
        printf("char 数据类型占用%i个字节
    ",numChar); // 1
        int numInt = sizeof(int);
        printf("int 数据类型占用%i个字节
    ",numInt); // 4
        int numDouble = sizeof(double);
        printf("double 数据类型占用%i个字节
    ",numDouble); // 8
        int numFloat = sizeof(float);
        printf("float 数据类型占用%i个字节
    ",numFloat); // 8

    逗号运算符

    • 在 C 语言中逗号也是一个运算符,称之为逗号运算符,其功能是把多个表达式连接起来组成一个表达式,成为逗号表达式

    • 格式: 表达式 1,表达式 2,表达式....表达式 n;

    • 例如:a = a + 1,b = 3*4;

    • 结合性:从左到右结合性

        // 逗号运算符,从左到右依次计算表达式的结果,只要是运算符就会有结果,逗号运算符也不例外
        int a = 10;
        int b = 5;
        int result;
        a = a + 10,b = b - 1,result = a + b;
        printf("a的值是%i,b的值是%i,result 的值是%i
    ",a,b,result);
    • 逗号表达式的结果是最后一个表达式的结果
    // 定一个一个变量 number 来接收逗号表达式的结果,每个表达式用括号括起来,整体再括起来,逗号表达式的结果是最后一个逗号表达式的结果
        int number =  ((a = a + 10),(b = b - 1),(result = a + b));
        printf("a 的值是%i,b 的值是%i,result 的值是%i,number 的值是%i
    ",a,b,result,number);

    关系运算符

    • 在 c 语言中条件成立为真,条件不成立为假,判断条件是否成立就是判断条件的真假
    • 怎么判断条件的真假呢? C 语言中规定任何数值都有自己的真假性,任何非 0 的都为真,也就是说 100,-50,2.3这些都是真,只有 0 是假的
    • 关系运算符的结果只有两个结果,真和假

    C 语言的比较运算中, “真”用数字“1”来表示, “假”用数字“0”来表示。

    运算符术语示例结果
    == 相等于 4 == 3 0
    != 不等于 4 != 3 1
    < 小于 4 < 3 0
    > 大于 4 > 3 1
    <= 小于等于 4 <= 3 0
    >= 大于等于 4 >= 1 1
    • 关系运算符的返回值要么真要么假
        // > , < , >= , <= , == , !=
        int a = 10;
        int b = 5; // 怎么知道 a>b 呢? 任何的运算符都有结果
        int c = 20;
        int result = a > b;
        int result1 = a > c;
        printf("result的值是%i
    ",result); // 1
        printf("result1的值是%i
    ",result1); // 0
    • 关系运算符的优先级: > < >= <=的优先级大于 == , !=
        // 关系运算符的优先级: > < >= <=的优先级大于 == , !=
        int a = 10;
        int b = 5;
        int result = 1 == a > b; // 先计算 a 是否大于 b,再拿这个结果与 1 是否相等,
        printf("result 的值是%i",result); // 1
    • 算术运算符的优先级大于关系运算符(比较运算符)
        // 算术运算符的优先级大于关系运算符
        int result = 1 + 1 > 2+2;
        printf("result 的值是%i
    ",result);  // 0,先计算 1+1,在计算 2+2,再拿 2>4?
    • 关系运算符的结合性是左结合性
        // 关系运算符的结合性是左结合性
        int result = 10 > 5 > 20;
        printf("result 的值是%i
    ",result); // 0,先计算 10>5,再拿这个值与 20做比较
    • 如果优先级和结合性同时存在,那就先优先级,再结合性
        // 如果优先级和结合性同时存在,那就先优先级,再结合性
        int result = 10 + 1 > 5 + 4 == 3 > 1;
        // 先计算 10+1,再计算 5+4,这两个算术运算符,得出 11 > 9 == 3>1
        // 再计算 11 > 9 ,和 3 > 1 这两个优先级比较高的比较运算符表达式,
        // 最后计算 1 == 1 等于的表达式
        printf("result 的值是%i
    ",result); // 11 > 9 == 3 > 1 ---> 1 == 1 ---> 1
    • 开发中没有人会按照上面那么写的
        int result1 = (10+1) > (5+4) == (3>1);
        printf("result1 的值是%i
    ",result1); // h实际开发中为了阅读,还是加上括号

    逻辑运算符

    • 有时候我们需要满足多个条件同时成立才能执行代码,比如登录:需要输入正确的用户名,和正确的密码,才能登录.所以c 语言提供了逻辑运算符

    • C 语言中提供了三个逻辑运算符

      • && 逻辑与 表达式 1 && 表达式 2
      • || 逻辑非 表达式 1 || 表达式 2
      • ! 逻辑非 ! 表达式 2
    • 逻辑运算符的运算结果只有两个真和假

    • 逻辑与:只有表达式都为真,结果才是真,其余都是假

      • 结合性:从左至右
        // 逻辑与(一假则假)
        int result = 10 > 7 && 5 > 3; // 10>7为真,5>3 为真
        printf("result = %i
    ",result); // 1
        int result1 = 10 > 90 && 8 >1; // 10 > 90为假
        printf("result1 = %i
    ",result1); // 0
    • 逻辑或:只要有一个表达式为真,结果就是真,如果表达式都是假,结果才是假
      • 结合性:从左至右
        // 逻辑或 (一真则真)
        int result = 10 > 8 || 9 > 7;
        printf("result = %i
    ",result); // 都为真--真
        
        int result1 = 10 > 8 || 9 > 10;
        printf("result1 = %i
    ",result1); // 一个为真--真
        
        int result2 = 10 > 11 || 9 > 10;
        printf("result2 = %i
    ",result2); // 都为假--假
        
        int result3 = 10 > 11 || 9 > 8;  // 一个为真--真
        printf("result3 = %i
    ",result3);
    • 逻辑非(如果表达式为真,则为假,如果表达式为假,则为真)---取反
      • 结合性:从右至左
        // 逻辑非
        int result = ! 10; // 0
        int result1 = ! 0; // 1
        printf("result = %i
    ",result);
        printf("result1 = %i
    ",result1);
    • 注意点;C 语言规定,任何数值都有真假性,非 0 既真,所有的逻辑运算符可以直接约数值进行计算
    • 逻辑与的特点是一假则假,所以如果前面的表达式是假的话,那么后面的表达式就不会计算了
        int a = 10;
        int result = 10 < 8 && a++ > 5; // a = 10,result = 0
        // 由于 10 < 8 为假,所以后面的表达式就不会计算了,a++ 后,a 的值就没有自增
        int b = 20;
        int result1 = 10 > 8 && b++ >5; // 10 > 8 为真,后面的表达式继续计算,所以 b 的值是 21
        printf("a = %i,result = %i
    ",a,result);
        printf("b = %i,result1 = %i
    ",b,result1);
    • 逻辑或的特点是一真则真,所以如果前面的表达式是真的话,那么后面的表达式就不会计算了
        int a = 10;
        int result = 10 > 8 || a++ > 5; // a = 10,result = 0
        // 由于 10 > 8 为真,所以后面的表达式就不会计算了,a++ 后,a 的值就没有自增
        int b = 20;
        int result1 = 10 < 8 || b++ >5; // 10 < 8 为假,后面的表达式继续计算,所以 b 的值是 21
        printf("a = %i,result = %i
    ",a,result);
        printf("b = %i,result1 = %i
    ",b,result1);
    • 以上两个逻辑运算符的特点称之为:逻辑运算符的短路

    • 判断一个数值是否在一个范围内

        int a = 10;
        if (a > 3 && a < 100){
            printf("a在 3-100 之间");
        } else{
            printf("a 不在 3-100 之间");
        }

    三目运算符

    • 格式: 条件表达式 ? 结果 A: 结果 B

      • 如果表达式为真,返回结果 A,如果表达式为假,返回结果 B
    • 结合性:左结合性

        // 三目运算符
        int a = 10;
        int b = 20;
        int result = a > b;
        printf("result = %i
    ",result);
        // 如果我想获取两个数之间的最大数呢?
        if (a>b){
            printf("a 和 b 之间最大数是%i
    ",a);
        }else{
            printf("a 和 b 之间最大数是%i
    ",b);
        }
        // 可是上面的办法太麻烦了,x要写这么多行代码
        int maxNum = a > b ? a:b; // 这句话的意思是,如果a> b,那就返回 a,如果 a 不大于 b 的话,那就返回 b
        printf("a 和 b 之间最大数是%i
    ",maxNum);
    • 三目运算符练习
        // 从控制台输入三个整数,返回最大的整数
        printf("请输入三个整数以逗号隔开,回车结束
    ");
        int num1,num2,num3;
        scanf("%i,%i,%i",&num1,&num2,&num3);
        int temp = num1 > num2 ? num1 : num2; // 比较 num1 和num2 中的最大值
        int maxNum = temp > num3 ? temp : num3; // 拿到 num1 和 num2 的最大值再与 num3 做比较,返回最大值
        printf("num1,num2,num3 之间的最大值是:%i
    ",maxNum);
        
        int maxNum1 = (num1 > num2 ? num1 : num2) > num3 ? (num1 > num2 ? num1 : num2) : num3;
        // 不推荐这种写法是因为,问号之前计算了一次num1 和num2 的最大值,问号表达式之后又计算了一次,无疑消耗了性能
        printf("num1,num2,num3 之间的最大值是:%i
    ",maxNum1);
  • 相关阅读:
    Golang进阶实战之IO操作
    动态获取输入框光标在页面中的位置! || 动态添加 style标签 || 获取元素样式 || 获取元素在页面中的位置
    v-select插件
    各种创建数组的方法
    百度UEditor编辑器
    vue-router 各种守卫以及流程梳理
    Snipaste 一款好用的 windows截图工具
    ant-design-vue
    罕见的css样式
    vue图片点击放大预览v-viewer
  • 原文地址:https://www.cnblogs.com/zcyd/p/14000699.html
Copyright © 2011-2022 走看看