• C语言——运算符


    C语言目录:

    1. 概述

    2. 数据类型

    3. 量

    4. 运算符

    5. 流程控制

    6. 函数

    7. C程序编译过程

    8. 文件

    9. 内存管理


    4.1 基本概念

    运算符:告诉程序执行特定的算术或逻辑操作的符号

    表达式:利用运算符连接在一起的有意义、有结果的语句

    • 表达式一定要有结果

    4.1.1 分类

    按功能化划分:

    • 算术运算符
    • 赋值运算符
    • 关系运算符
    • 逻辑运算符
    • 位运算符

    按照参与运算符的个数划分:

    • 单目运算符

      如:i++

    • 双目运算符

      如:a+b

    • 三目运算符

      如:a>b ? 1 : 0;

    4.1.2 优先级与结合性

    不同优先级 的运算符,运算次序按照 优先级从高到低执行

    相同优先级 的运算符,运算次序按结合性规定的方向执行

    #include 
    
    int main(){
        int a = 10;
        int b = 5;
        
        // 算术运算符的结合性和优先级
        // 结合性: 左结合性, 从左至右
        int c = 50;
        result = a + b + c; // 15 + c;  65;
        printf("%i\n", result);
        
        // 优先级: * / % 大于 + -
        result = a + b * c; // a + 250; 260;
        printf("%i\n", result);
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16

    单目运算符,赋值运算符,三目运算符为右结合性;
    其余为左结合性(从左向右看)

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

    4.2 逗号运算符和括号运算符

    #include 
    
    int main(){
        int a = 10, b = 20, c;
        // ()优先级高于,和=, 先计算()中的内容
        // c = (11,21);
        // ()中是一个逗号表达式, 结果是最后一个表达式的值, 所以计算结果为21
        c = (a + 1,b + 1);
        printf("c = %d\n", c); // 21
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10

    4.3 自增自减

    • 前缀表达式:++x, --x;表示先自增再运算
    • 后缀表达式:x++, x–;表示先运算再自增
    #include 
    
    int main(){
        int n = 1;
        // ++在后, 先参与表达式运算, 再自增
        // 表达式运算时为: 3 + 1;
        int res = 3 + n++;
        printf("res = %d\n", res); // 4
        printf("n = %d\n", n); // 2
    }
    
    #include 
    
    int main(){
        int n = 1;
        // ++在前, 先自增, 再参与表达式运算
        // 表达式运算时为: 3 + 2;
        int res = 3 + ++n;
        printf("res = %d\n", res); // 5
        printf("n = %d\n", n); // 2
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21

    自增、自减运算只能用于单个变量,只要是标准类型的变量(整型、实型还是字符型变量),但不能用于表达式或常量

    • 错误用法:++(a+b); 5++;
    int i = 10;
    int b = i++; // 不推荐
    或者
    int b = ++i; // 不推荐
    或者
    int a = 10;
    int b = ++a + a++;  // 不推荐
    
    int i = 10;
    int b = i; // 推荐
    i++;
    或者;
    i++;
    int b = i; // 推荐
    或者
    int a = 10;
    ++a;
    int b = a + a; // 推荐
    a++;
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19

    4.4 sizeof

    用于计算一个变量、或常量、数据类型占用的内存字节数

    sizeof(常量 or 变量);

    sizeof(10); //sizeof 10;
    
    char c = 'a';
    sizeof(c); //sizeof c;
    
    • 1
    • 2
    • 3
    • 4

    sizeof(数据类型);

    sizeof(float);
    
    • 1

    sizeof是一个运算符,不是函数

    • sizeof 运算符优先级为2
    int a = 10;
    double b = 3.14;
    double res = sizeof(a+b);// sizeof a+b;
    
    # sizeof 运算符优先级比+高,所以会先计算sizeof(a),再利用结果和b相加
    //res = 7.14
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6

    4.5 算数运算符

    优先级符号含义表达式结合性
    3/表达式/表达式左到右双目运算符
    *表达式*表达式
    %取余表达式%表达式
    4+表达式+表达式左到右双目运算符
    -表达式-表达式
    • 如果参与运算的两个操作数都是整数,那么结果也是整数

    • 如果参与运算的两个操作数有一个是浮点数,那么结果一定是浮点数

      #include 
      int main(){
          // 整数除以整数, 结果还是整数
          printf("%i\n", 10 / 3); // 3
      
          // 参与运算的任何一个数是小数, 结果就是小数
          printf("%f\n", 10 / 3.0); // 3.333333
      }
      
      • 1
      • 2
      • 3
      • 4
      • 5
      • 6
      • 7
      • 8
    • 取余运算符,参与运算的两个操作数必须是整数,不能包含浮点数

      取余运算结果的符号与被除数有关

      #include 
      int main(){
          // 被除数是正数结果就是正数,被除数是负数结果就是负数
          result = 10 % 3;
          printf("%i\n", result); // 1
          result = -10 % 3;
          printf("%i\n", result); // -1
          result = 10 % -3;
          printf("%i\n", result); // 1
      }
      
      • 1
      • 2
      • 3
      • 4
      • 5
      • 6
      • 7
      • 8
      • 9
      • 10
    • 取余运算符,被除数为0,结果为0

    • 除法/取余运算,除数为0,没有意义

    4.6 关系运算符

    非零值都是 true ,只有零才是 false

    关系运算符的运算结果只有两种:

    • 条件成立,结果为 true
    • 条件不成立,结果为 false

    4.6.1 优先级与结合性

    # include
    
    int main(){
        //== 优先级小于 > ,所以先计算 > 
        int result = 10 == 5 > 3;//10 == 1 -> true
        printf("%d\n",result);
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    # include
    
    int main(){
        // == 和 != 优先级一样,所以按照结合性
        int res = 10 == 5 != 3;// 10 == true -> true
        printf("%d\n",res);
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7

    无论是 float 还是 double 都有精度问题, 所以一定要避免利用 == 判断浮点数是否相等

    4.7 位运算符

    程序中所有数据都是以二进制形式存储,位运算符就是直接对整数在内存中的二进制操作

    符号名称运算结果
    &按位与同1为1,有0则0
    |按位或同0位0,有1为1
    ^按位异或同0异1
    ~按位取反0变1,1变0
    <按位左移乘以2的n次方
    >>n按位右移除以2的n次方

    4.7.1 按位与

    9&5 = 1
    
        1001
      & 0101
        ----
        0001
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6

    a. 判断奇偶

    任何数和1进行&操作,得到这个数的最低位

    	1000
       &0001
        ----
        0000  // 结果为0, 代表是偶数
    
    	1011
       &0001
        ----
        0001 // 结果为1, 代表是奇数
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9

    4.7.2 按位或

    9|5 = 13
    
        1001
      | 0101
        ----
        1101
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6

    a. 权限设置

    enum Unix {
        S_IRUSR = 256,// 100000000 用户可读
        S_IWUSR = 128,//  10000000 用户可写
        S_IXUSR = 64,//    1000000 用户可执行
        S_IRGRP = 32,//     100000 组可读
        S_IWGRP = 16,//      10000 组可写
        S_IXGRP = 8,//        1000 组可执行
        S_IROTH = 4,//         100 其它可读
        S_IWOTH = 2,//          10 其它可写
        S_IXOTH = 1 //           1 其它可执行
    };
    // 假设设置用户权限为可读可写
    printf("%d\n", S_IRUSR | S_IWUSR); // 384 // 110000000
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13

    4.7.3 按位异或

    相同整数异或为0,如 5^5=0

    多个整数相异或的结果跟顺序无关,如 5^6^7 == 5^7^6

    • 同一数异或另外一个数两次,结果还是那个数,如 5^7^7=5
    9^5 = 12
    
        1001
      ^ 0101
        ----
        1100
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6

    a. 交换两个数的值

    a = a^b;
    b = b^a; // b = b^a^a = a;
    a = b^a; // a = b^a^b = a^a^b = b;
    
    • 1
    • 2
    • 3

    4.7.4 按位取反

    ~9 = -10
    
    原码    0000 1001
    补码    1111 0110
    
    转为十进制    0000 1001+1 = 0000 1010 = -10
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6

    4.7.5 按位左移

    2< :相当于乘2的n次方

    高位舍弃,低位补0,高位丢弃,但符号位也会丢弃,造成正负性改变

    2<<1; //相当于 2 *= 2 // 4
      0010
    <<0100
    
    2<<2; //相当于 2 *= 2^2; // 8
      0010
    <<1000
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7

    4.7.6 按位右移

    2>>n :相当于除以2的n次方

    正数时,符号位为0,最高位补0

    负数时,符号位为1,最高位是补0 或 是补1取决于编译系统

    4.8 逻辑运算符

    优先级符号名称符号结合性
    2!逻辑非!表达式右结合性单目运算符
    11&&逻辑与表达式&&表达式左到右双目运算符
    12||逻辑或表达式||表达式左到右双目运算符

    4.8.1 逻辑非

    ! 条件A;

    运算结果:

    • !true = false;
    • !false = true;

    4.8.2 逻辑与

    条件A && 条件B;

    判断过程

    • 条件A为真,则接着判断条件B,也真,则表达式为 true
    • 条件A为假,则不执行B,则表达式为 false

    4.8.3 逻辑或

    条件A || 条件B;

    判断过程

    • 条件A为假,且条件B为假,则表达式为 false
    • 条件A为假,条件B为真,则表达式为 true
    • 条件A为真,则不会执行条件B,则表达式为 false
  • 相关阅读:
    网工内推 | 急招网工,思科、华为认证优先,法定节假日三薪
    L46.linux命令每日一练 -- 第七章 Linux用户管理及用户信息查询命令 -- w和who
    技术分享 | app自动化测试(Android)--显式等待机制
    《深度学习500问》外链笔记
    网络安全(黑客技术)——如何高效自学
    jetson机器上对lxde桌面设置中文输入法详细过程(图文展示)
    Vue3笔记
    仪表板:实体别名和筛选器
    Louvain算法在反作弊上的应用
    vc++ mfc 操作注册表
  • 原文地址:https://blog.csdn.net/qq_40479037/article/details/126165419