• C语言操作符详解(二)


    统计整数在二进制中1的个数:

    这是上一篇文章留下的问题,这里为大家作答:

    1. //统计二进制中1的个数
    2. int statistics(int a)
    3. {
    4. int count = 0;
    5. for (int i = 0; i < 32; i++)
    6. {
    7. if (a & 1)
    8. {
    9. count++;
    10. }
    11. a = a >> 1;
    12. }
    13. //while (a)
    14. //{
    15. // a = a & (a - 1);//每次都会消去一个1
    16. // count++;
    17. //}
    18. return count;
    19. }
    20. int main()
    21. {
    22. int a = 0;
    23. scanf("%d", &a);
    24. int num = statistics(a);
    25. printf("%d\n", num);
    26. }

    未被注释的部分就是运用位操作符实现的代码,注释的部分也是一种方法,但是这种方法很少被想到。

    赋值操作符

    赋值操作符就是 =   可以为变量赋上一个自己满意的值:

    1. int num;
    2. num = 10;//这就是赋值

    并且赋值可以连续使用:

    1. int a;
    2. int b;
    3. int c;
    4. a = b = c+1;

    但是同样的意思下分开写不是更让人知道且易于调试:

    1. a = b;
    2. b = c+1;

    复合赋值符

    1. +=
    2. -=
    3. *=
    4. /=
    5. %=
    6. >>=
    7. <<=
    8. &=
    9. |=
    10. ^=

    这些都是复合赋值操作符

    单目操作符

    1. ! 逻辑反操作
    2. - 负值
    3. + 正值
    4. & 取地址
    5. sizeof 操作数的类型长度(以字节单位)
    6. ~ 对一个数的二进制按位取反(~0 就是 -1
    7. -- 前置或后置--
    8. ++ 前置或后置++
    9. * 解引用操作符
    10. (类型) 强制类型转换

    特别重点:sizeof和数组

    来看一段代码:这里的1 2 3 4 会输出什么?

    1. void teer1(int arr[])
    2. {
    3. printf("3:%d\n", sizeof(arr));
    4. }
    5. void teer2(char arr[])
    6. {
    7. printf("4:%d\n", sizeof(arr));
    8. }
    9. int main()
    10. {
    11. int arr1[10] = { 0 };
    12. char ch[10] = { 0 };
    13. printf("1:%d\n", sizeof(arr1));
    14. printf("2:%d\n", sizeof(ch));
    15. teer1(arr1);
    16. teer2(ch);
    17. }

     我们说过数组名其实是首元素的地址,但是sizeof是一个特例,sizeof计算的是整个数组,但是函数传参传的是数组名也就是地址,地址的大小都是一样的。

    关系操作符

    1. >
    2. >=
    3. <
    4. <=
    5. !=
    6. ==

    注意:==才是比较 ,= 是赋值

    逻辑操作符

    1. &&
    2. ||

    逻辑与,逻辑或的特点:

    1. #include
    2. int main()
    3. {
    4. int i = 0, a = 0, b = 2, c = 3, d = 4;
    5. i = a++ && ++b && d++;//逻辑与&& 如果前面已经知道为假了,后面就都不会计算了。
    6. printf("a=%d,b=%d,c=%d,d=%d\n", a, b, c, d);
    7. }

    1. #include
    2. int main()
    3. {
    4. int i = 0, a = 0, b = 2, c = 3, d = 4;
    5. i = a++ || ++b || d++;//逻辑或|| 如果知道前面有一个为真了,后面也不会计算了。
    6. printf("a=%d,b=%d,c=%d,d=%d\n", a, b, c, d);
    7. }

     条件操作符

    exp1 ? exp2 : exp3;

    条件操作符,最常用的方式就是找两个数的最大数:

    1. int a = 5;
    2. int b = 6;
    3. int i = 0;
    4. i = a > b ? a : b;

     逗号表达式

    exp1,exp2,exp3,.......

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

    1. int a = 1;
    2. int b = 2;
    3. int c = (a>b,a=b+10,b=a+1);

    上述代码中,c 是多少? 答案是13。

    表达式求值

    隐式类型转换:

    C语言中整数运算是以整形类型精度进行的,为了这个精度,表达式中的字符和短整型在使用前会被转换为普通整形,这种转换被叫做整形提升

    1. char a,b,c;
    2. .......
    3. a = b + c;

    b 和 c 就会被提升为普通整形,然后在执行加法,加法之后结果会被截断,然后再存储在a 中。

    如何整形提升的

    整形提升是按照变量的数据类型的符号位来提升。(符号位就是二进制最左边的数字,1即负,0即正

    1. char c1 = -1;
    2. 变量从c1的二进制补码是8个比特位
    3. 11111111
    4. 因为char是有符号的char
    5. 所以高位补充符号位,即1
    6. 11111111111111111111111111111111
    7. char c2 = 1;
    8. 变量c2的二进制补码也是8个比特位
    9. 00000001
    10. 因为是有符号的char
    11. 所以高位补充符号位,即0
    12. 00000000000000000000000000000001

    算术转换:

    如果某个操作符的各个操作数属于不同的类型,那么必须进行操作数的类型转换,否则无法进行操作,下面是寻常算术转换:

    1. long double
    2. double
    3. float
    4. unsigned long int
    5. long int
    6. unsigned int
    7. int

    如果在这个排行中排名低,那么要转换成高的才可以进行运算。

    算术转换要合理,要不然有潜在问题

    操作符的属性

    复杂表达式的求值有三个影响的因素:

    1.操作符的优先级

    2.操作符的结合性

    3.是否控制求值顺序

    注意:函数的调用先后顺序无法通过操作符的优先级确定,类如下面代码就是有问题的:

    1. int fun()
    2. {
    3. static int count = 1;
    4. return ++count;
    5. }
    6. int main()
    7. {
    8. int answer;
    9. answer = fun() - fun() * fun();
    10. printf("%d\n", answer);
    11. }

    总结:两个相邻的操作符先执行哪个,取决于优先级,如果相同,取决于他们的结合性(可以在网上查)。如果我们的表达式无法通过操作符的属性确定唯一的计算路径,那么就是有问题的。

  • 相关阅读:
    生产级Stable Diffusion AI服务部署指南【BentoML】
    Linux 学习总结(93)—— Linux 管道符使用总结
    新手做独立站需要掌握哪些技能
    HTML标签详解 HTML5+CSS3+移动web 前端开发入门笔记(四)
    基于分布式系统结构下Nacos配置中心的应用
    微信小程序日期增加时间完成订单失效倒计时(有效果图)
    C专家编程 第7章 对内存的思考 7.7 总线错误
    8086寄存器和常用指令缩写还原
    东华码蹄集第21周oj赛(光潮的幻像,分苹果,马走日,码哥猜想)
    Tkinter保姆级教程(上)
  • 原文地址:https://blog.csdn.net/m0_75122019/article/details/139032757