当前位置:   article > 正文

C语言 ─── 操作符详解

C语言 ─── 操作符详解

目录

1. 算术操作符

2. 移位操作符

2.1 左移操作符

2.2 右移操作符

3. 位操作符

4. 复合赋值符

5. 单目操作符

6. 逗号表达式

7. 隐式类型转换

7.1 整型提升的意义:

7.2 如何进行整体提升呢?

8. 算术转换

★★★数组名



 

1. 算术操作符

 +    -   *   /   %
        1. 除了 % 操作符之外,其他的几个操作符可以作用于整数和浮点数。
        2. 对于 / 操作符如果两个操作数都为整数,执行整数除法。而只要有浮点数执行的就是浮点数除法。
        3. % 操作符的两个操作数必须为整数。返回的是整除之后的余数。

2. 移位操作符

  1. << 左移操作符
  2. >> 右移操作符
  3.    
  4. 注:移位操作符的操作数只能是整数。

2.1 左移操作符

移位规则:
左边抛弃、右边补 0

2.2 右移操作符

移位规则:
首先右移运算分两种:
        1. 逻辑移位
                左边用0填充,右边丢弃
        2. 算术移位
                左边用原该值的符号位填充,右边丢弃
警告
        对于移位运算符,不要移动负数位,这个是标准未定义的。
例如:
  1. int num = 10;
  2. num>>-1;//error

3. 位操作符

        位操作符有:
  1. & //按位与
  2. | //按位或
  3. ^ //按位异或
  4. 注:他们的操作数必须是整数。
练习:
        编写代码实现:求一个整数存储在内存中的二进制中1 的个数。
  1. #include <stdio.h>
  2. int main()
  3. {
  4. int num = -1;
  5. int i = 0;
  6. int count = 0;//计数
  7. for(i=0; i<32; i++)
  8. {
  9. if( num & (1 << i) )
  10. count++;
  11. }
  12. printf("二进制中1的个数 = %d\n",count);
  13. return 0;
  14. }
  15. //思考还能不能更加优化,这里必须循环32次的。
  16. #include <stdio.h>
  17. int main()
  18. {
  19. int num = -1;
  20. int i = 0;
  21. int count = 0;//计数
  22. while(num)
  23. {
  24. count++;
  25. //n=n&(n-1)执行一次可以把n的二进制最右面的1去掉一个
  26. num = num&(num-1);
  27. }
  28. printf("二进制中1的个数 = %d\n",count);
  29. return 0;
  30. }
  31. //这种方式是不是很好?达到了优化的效果,但是难以想到。
        判断一个数是否为2的次方
  1. int main()
  2. {
  3. int n;
  4. scanf("%d", &n);
  5. if ((n & (n - 1)) == 0)
  6. {
  7. printf("Yes ");
  8. }
  9. else
  10. {
  11. printf("No ");
  12. }
  13. }

4. 复合赋值符

+=
-=
*=
/=
%=
>>=
<<=
&=
|=
^=

5. 单目操作符

!           逻辑反操作
-           负值
+           正值
&           取地址
sizeof       操作数的类型长度(以字节为单位)
~           对一个数的二进制按位取反
--           前置、后置 --
++           前置、后置 ++
*           间接访问操作符 ( 解引用操作符 )
( 类型 )       强制类型转换
笔试题:
  1. #include <stdio.h>
  2. int main()
  3. {
  4.    int i = 0,a=0,b=2,c =3,d=4;
  5.    i = a++ && ++b && d++;
  6.    //i = a++||++b||d++;
  7.    printf("a = %d\n b = %d\n c = %d\nd = %d\n", a, b, c, d);
  8.    return 0;
  9. }
  10. //程序输出的结果是什么?

答案:1 2 3 4 

        1 3 3 5

6. 逗号表达式

exp1, exp2,exp3,exp4,...expN
        逗号表达式,就是用逗号隔开的多个表达式。
        逗号表达式,从左向右依次执行。 整个表达式的结果是最后一个表达式的结果。

7. 隐式类型转换

        C的整型算术运算总是至少以缺省整型类型的精度来进行的。
为了获得这个精度,表达式中的字符和短整型操作数在使用之前被转换为普通整型,这种转换称为 整型 提升

7.1 整型提升的意义

        表达式的整型运算要在CPU 的相应运算器件内执行 CPU 内整型运算器 (ALU) 的操作数的 字节长度一般就是int的字节长度 ,同时也是 CPU 的通用寄存器的长度。
        因此,即使两个char 类型的相加,在 CPU 执行时实际上也要先转换为 CPU 内整型操作数的标准长度。
        通用CPU general-purpose CPU )是难以直接实现两个 8 比特字节直接相加运算(虽然机器指令中可能有这种字节相加指令)。所以, 表达式中各种长度可能小于int长度的整型值 ,都必须先转换为int unsigned int ,然后才能送入 CPU 去执行运算。
  1. //实例1
  2. char a,b,c;
  3. ...
  4. a = b + c;
        b和 c 的值被提升为普通整型,然后再执行加法运算。
        加法运算完成之后,结果将被截断,然后再存储于a中。

7.2 如何进行整体提升呢?

整形提升是按照变量的数据类型的符号位来提升的
  1. //负数的整形提升
  2. char c1 = -1;
  3. 变量c1的二进制位(补码)中只有8个比特位:
  4. 1111111
  5. 因为 char 为有符号的 char
  6. 所以整形提升的时候,高位补充符号位,即为1
  7. 提升之后的结果是:
  8. 11111111111111111111111111111111
  9. //正数的整形提升
  10. char c2 = 1;
  11. 变量c2的二进制位(补码)中只有8个比特位:
  12. 00000001
  13. 因为 char 为有符号的 char
  14. 所以整形提升的时候,高位补充符号位,即为0
  15. 提升之后的结果是:
  16. 00000000000000000000000000000001
  17. //无符号整形提升,高位补0
整形提升的例子 :
  1. //实例1
  2. int main()
  3. {
  4. char a = 0xb6;
  5. short b = 0xb600;
  6. int c = 0xb6000000;
  7. if(a==0xb6)
  8. printf("a");
  9. if(b==0xb600)
  10. printf("b");
  11. if(c==0xb6000000)
  12. printf("c");
  13. return 0;
  14. }
        实例1 中的 a,b 要进行整形提升 , 但是 c 不需要整形提升
a,b 整形提升之后 , 变成了负数 , 所以表达式 a==0xb6 , b==0xb600 的结果是假 , 但是 c 不发生整形提升 , 则表达式 c==0xb6000000 的结果是真 .
所程序输出的结果是:
c
  1. //实例2
  2. int main()
  3. {
  4. char c = 1;
  5. printf("%u\n", sizeof(c));
  6. printf("%u\n", sizeof(+c));
  7. printf("%u\n", sizeof(-c));
  8. return 0;
  9. }
        实例2 中的 , c只要参与表达式运算,就会发生整形提升 , 表达式 +c , 就会发生提升 , 所以 sizeof(+c) 4 个字节.
表达式 - c 也会发生整形提升 , 所以 sizeof( - c) 4 个字节 , 但是 sizeof(c) , 就是 1 个字节 .

8. 算术转换

        如果某个操作符的各个操作数属于不同的类型,那么除非其中一个操作数的转换为另一个操作数的类型,否则操作就无法进行。
下面的层次体系称为寻常算术转换
  1. long double
  2. double
  3. float
  4. unsigned long int
  5. long int
  6. unsigned int
  7. int
        如果某个操作数的类型在上面这个列表中排名较低,那么首先要转换为另外一个操作数的类型后执行运算。
警告:
但是算术转换要合理,要不然会有一些潜在的问题。
  1. float f = 3.14;
  2. int num = f;//隐式转换,会有精度丢失

整形提升是针对小于int的值进行运算时需要整形提升,

算数转换最低也是int 

★★★数组名

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/AllinToyou/article/detail/462315
推荐阅读
相关标签
  

闽ICP备14008679号