• c语言 --- 运算符和表达式


    运算的基本概念

    • 左值和右值以及操作数的概念

      • a=1 a:左值 1:右值

        • error C2166:左值指定 const 对象 左值一般是变量

        • 右值:没有什么太多要求

      • 操作数:=需要两个数字运算符,操作数2

      • 单目,双目, 三目

    • 优先级:计算表达式的顺序(先算*/ 再算+ -)

    • 结合性:a=1; 正确应该是把1赋值给a

    逗号→赋值→逻辑→条件→算术→位→括号

    1. const int c_num = 1;
    2. //报错: 表达式必须是可修改的左值
    3. c_num = 1;
    4. //[]的优先级最高 数组 存储指针 指针数组
    5. int* p[3];
    6. //指针指向数组 数组指针
    7. int(*p) [3];

    基本运算符

    a=1;
    • 算术运算符

    1. //+ -
    2. //* /
    3. //2(3+4)
    4. int a=2*(3+4); //在写表达式的时候乘法不能省略
    5. //除法
    6. 1/3=0; //当除法的两边都是整数的时候,会自动取整 需要把一部分转换为浮点数结果才是小数
    7. //1/2+2/3+3/4;
    8. double result=1/2.0+2/3.0+3/4.0
    9. //取模:%
    10. int num=1%3 //1 x%n [0,n-1]--->随机数
    11. //余数的符号
    12. num=1%-2; //1 余数只和被取余数的正负有关
    • 复合赋值运算符

    1. int a=1;
    2. a+=2; //a=a+2
    3. a/=2; //a=a/2
    4. a*=2; //a=a*2
    5. a=2;
    6. a*=1+2*3; //表达式右边有没有括号,都没关系,都是一个整体
    7. //a=a*(1+2*3); //14

    条件运算符

    • 条件表达式只有两个结果: 0(表示不成立) 或者 1(成立)

    • 在计算机中非零值表示成立,只有0(\0)或者NULL 表示不成立

    • 不存在连续操作,例如描述 a 大于 1 并且小于2,1 < a < 2 错误

      • 1 < a < 2是永远成立的 1 < a 结果[0,1],[0,1] < 2 永远成立

    1. //> <
    2. //不等于 != //中间没空格,有空格是错误的
    3. //等于 ==
    4. //>= <=
    5. print("%d\n",1 > 2); //0
    6. if(a = 3)
    7. {
    8. print("执行"); //执行
    9. }
    • 逻辑运算符

    1. &&: 逻辑与运算 并且
    2. ||: 逻辑或运算 或者
    3. !: 逻辑取反 成立变不成立,不成立变成立
    4. !3 0
    5. !0 1
    aba&&ba||b
    0000
    1001
    1111
    0101

    综上:

    0 表示假,1 表示真

    a&&b:a和b都成立它才能成立,其他情况都是不成立

       a||b:a和b都不成立它才能不成立,其他情况都是成立

    逻辑与运算、逻辑或运算都会存在短路现象(计算机偷懒现象)

    1. int a = 2;
    2. a > 1 || (a = 4); //a > 1成立 所以a > 1 || (a = 4)成立
    3. a < 1 && (a = 5); //a < 1不成立 所以a < 1 && (a = 5)不成立
    4. printf("%d\n", a); //2

    位运算符

    学会运算符方式即可

    1. &: 按位与
    2. |: 按位或运算
    3. ~: 按位取反
    4. ^: 异或
    5. >>: 左移
    6. <<: 右移

    箭头指向哪边就朝哪边移位,左移两位就是把左边的两位截取掉

    左移:正负数都是右边补0

    右移:正数:左边补0 负数:左边补1

    首先转换为二进制,一个数用一个字节表示,正数三码合一,直接使用补码,需要还原成原码才能得到十进制数

    1. #include <stdio.h>
    2. int main()
    3. {
    4. printf("%d\n", 1 & 2); //0
    5. printf("%d\n", 1 | 2); //3
    6. printf("%d\n", 1 ^ 2); //3
    7. printf("%d\n", ~1); //-2
    8. printf("%d\n", 8 << 2); //32
    9. printf("%d\n", 8 >> 2); //2
    10. printf("%d\n", -1 >> 3); //-1
    11. printf("%d\n", -1 << 2); //-4
    12. return 0;
    13. }

    特殊运算符

    • ++ - -

    1. int a=1;
    2. a++; //后置 先做其他运算,再改变自己
    3. ++a; //前置 先改变自己,再做其他运算
    4. //a++ a=a+1;
    5. a--;
    6. --a;
    7. //a-- a=a-1
    8. int a = 1;
    9. int b = 1;
    10. int result;
    11. result = a++; //result=a,再a=a+1
    12. printf("result=%d\ta=%d\n", result, a); //1 2
    13. result = ++b; //先b=b+1 再做result=b
    14. printf("result=%d\tb=%d\n", result, b); //2 2
    15. a = 1;
    16. result = 3 * a++; //result=3*a,再a=a+1
    17. printf("result=%d\ta=%d\n", result, a); //3 2
    • sizeof

      • 统计类型、变量占用字节数

      • 执行过程在编译期(把代码翻译成二进的时候)完成,编译期变量没有内存

    1. //统计类型所占用的字节数
    2. printf("size_t:%d\n", sizeof(unsigned int)); //4
    3. printf("long:%d\n", sizeof(long)); //4
    4. //统计变量所占用的字节数
    5. int a = 1;
    6. printf("a:%d\n", sizeof(a)); //4
    7. int i = 1;
    8. result = sizeof(++i);
    9. //i等于1,不会改变,因为sizeof运算在编译期完成,变量没有存储这个值就已经计算好了,不会运行++i,只会检查i类型占用字节数
    10. printf("result=%d\ti=%d\n", result, i); //4 1
    • ?:

    1. 表达式1 ? 表达式2 : 表达式3
    2. 1成立 2
    3. 1不成立 3
    4. a = 2;
    5. b = 3;
    6. //求a与b的最大值
    7. int max = a > b ? a : b;
    8. //3
    9. printf("max=%d\n", max);
    10. //求a与b与c的最大值
    11. int c = 4;
    12. // ( a > b ? a : b) > c ? ( a > b ? a : b) : c;
    13. int maxabc = (max) > c ? (max) : c;
    14. printf("maxabc=%d\n", maxabc);
    15. //函数也可以算是一个表达式
    16. a > 3 ? printf("a=%d\n", a) : printf("3\n");
    • 逗号运算符

      • 有效值 是最右边的值

    1. result = (1 + 2, 3 + 4, 4 + 5, 5 + 6);
    2. //11
    3. printf("result=%d\n", result);

    内存共享问题

    计算的时候用的 a 或 b 都是一个值

    1. #include <stdio.h>
    2. int main()
    3. {
    4. int a = 1;
    5. int resultFirst = a++ + a++ + ++a + ++a; //a:3
    6. //只看前置,不看后置,再看几部分
    7. //resultFirst:3+3+3+3=12 a:5
    8. //只看前置:a++ + a++ + ++a + ++a 两个前置:a要加两次,运算时a的值3
    9. //再看几部分:a++ + a++ + ++a + ++a 有四部分:3+3+3+3
    10. //无论前置还是后置 a都需要加四次 a最终结果是5
    11. printf("result=%d\ta=%d\n", resultFirst, a); //12 5
    12. int b = 1;
    13. int resultSecond = b++ * b++ * ++b * b++ * b++;
    14. //b运算时候:b=2
    15. //resultSecond:2^5;
    16. printf("result=%d\tb=%d\n", resultSecond, b); //32 6
    17. int c = 1;
    18. int resultThree = c++ * c-- * c++ * ++c * --c * c++;
    19. printf("result=%d\tc=%d\n", resultThree,c); //1 3
    20. return 0;
    21. }
  • 相关阅读:
    C# 中的那些锁,在内核态都是怎么保证同步的?
    vue修饰符 lazy number trim
    预警期刊数量再次刷新:文章一投就拒稿,投稿之前要牢牢记住这几点
    HTML静态网页作业html+css+javascript+jquery水果商城7页
    JAVA基础总结
    update-alternatives的使用
    html表格标签的学习,什么是html的表格标签
    JavaScript【字符串数组实操、二维数组转化一维数组 、数组去重、数组排序、 函数概述、函数的重复声明、 函数名的提升、 函数的属性和方法、函数作用域、函数参数】(七)
    PackagingTool_x64_v2.0.1.0图片转档打包二进制文件合并字库生成图片软件介绍
    自己搭的centOS7虚拟机,ping baidu出现Temporary failure in name resolution
  • 原文地址:https://blog.csdn.net/weixin_60569662/article/details/123626859