爱上C语言:操作符详解(下)

2024-02-26 1833阅读

温馨提示:这篇文章已超过393天没有更新,请注意相关的内容是否还可用!

🚀 作者:阿辉不一般

🚀 你说呢:生活本来沉闷,但跑起来就有风

🚀 专栏:爱上C语言

🚀作图工具:draw.io(免费开源的作图网站)

爱上C语言:操作符详解(下)

如果觉得文章对你有帮助的话,还请点赞,关注,收藏支持博主,如有不足还请指点,博主及时改正,感谢大家支持!!!

文章目录

  • 🚀前言
  • 🚀整型的存储以及原、反、补码
  • 🚀移位操作符
    • ✈️左移操作符()
    • 🚀位操作符
      • ✈️一道变态面试题
      • 🚀单目操作符
        • ✈️ 逻辑反操作(!)
        • ✈️sizeof
        • 🚀剩下的操作符
        • 🚀复杂的表达式如何计算
          • ✈️优先级
          • ✈️结合性

            🚀前言

            大家好啊😉!承接之前的操作符上篇,今天阿辉将介绍剩下的操作符,包括移位操作符,位操作符以及单目操作符,持续输出干货中,关注阿辉不迷路哦 😘 ,内容干货满满😋,接下来就跟着阿辉一起学习吧👊

            🚀整型的存储以及原、反、补码

            介绍移位操作符和位操作符前得先了解整型在内存中的存储以及原反补码,阿辉上篇文章上篇文章整型的存储里面有详细的讲解(点击直接跳转哦 😘)

            🚀移位操作符

            移位操作符有何作用?

            移位操作符移动的是数据在内存中存储的补码的二进制位,其中移位操作符的“位”字就是指二进制位

            移位操作符有左移操作符和右移操作符两种

            ✈️左移操作符( int a = 10; 0000 0000 0000 0000 0000 0000 0000 1010 -a原码 0000 0000 0000 0000 0000 0000 0000 1010 -a反码 0000 0000 0000 0000 0000 0000 0000 1010 -a补码 int b = a b补码 b也就是40 return 0; }

            爱上C语言:操作符详解(下)

            是不是有点懵😏,别急阿辉用图演示👇

            爱上C语言:操作符详解(下)

            现在是不是对左移操作符用法清晰多了😁 ,上述演示仅仅使用了正数,不过负数同样可以,负数仅仅是多了原反补码之间的转换

            ✈️右移操作符(>>)

            右移操作符的使用

            左操作数 >> 右操作数
            左操作数是要被右移位的数
            右操作数是要右移移动的位数
            

            右移操作符的规则

            • 算术右移:左边补符号位,右边丢弃
            • 逻辑右移:左边补0,右边丢弃

              对于使用逻辑右移还是算术右移从语言并未明确规定,但大部分编译器都使用算术右移,对于无符号数使用逻辑右移

              算术右移:左移用正数,咱们这次用负数演示👊

              int main()
              {
              	int a = -10;
              	1000 0000 0000 0000 0000 0000 0000 1010->a原码
              	1111 1111 1111 1111 1111 1111 1111 0101->a反码
              	1111 1111 1111 1111 1111 1111 1111 0110->a补码
              	int b = a >> 2;
              	1111 1111 1111 1111 1111 1111 1111 1101->b补码
              	1000 0000 0000 0000 0000 0000 0000 0010
              	1000 0000 0000 0000 0000 0000 0000 0011->b原码 也就是-3
              	return 0;
              }
              

              爱上C语言:操作符详解(下)

              逻辑右移:逻辑右移也与上述算数右移的运算是类似的,不过逻辑右移不管你是正数还是负数,左边通通补0

              注意

              • 移位操作符的操作数只能为整型
              • 对于移位运算符,不要移动负数位,这个是标准未定义的
              • a>>1或a int a = 3; 0000 0000 0000 0000 0000 0000 0000 0011 - 3的原反补码 int b = -5; 1000 0000 0000 0000 0000 0000 0000 0101 - -5的原码 1111 1111 1111 1111 1111 1111 1111 1010 -> -5的反码 1111 1111 1111 1111 1111 1111 1111 1011 -> -5的补码 int c = a & b; 1111 1111 1111 1111 1111 1111 1111 1011 -> -5的补码 0000 0000 0000 0000 0000 0000 0000 0011 -> 3的补码 0000 0000 0000 0000 0000 0000 0000 0011 -> 按位与结果 符号位为0,原反补码相同,值为3 return 0; }

                爱上C语言:操作符详解(下)

                | 按位或: 两操作数内存中的补码两相同二进制位均为0就为0,其中一个1就为1

                |与&的用法类似这里就不举例子了

                ^按位异或: 两操作数内存中的补码两相同二进制位相同为0,相异为1

                🌰栗子

                int main()
                {
                	int a = 3;
                	0000 0000 0000 0000 0000 0000 0000 0011 ->3原反补码
                	int b = 3;
                	int c = a ^ b;
                	0000 0000 0000 0000 0000 0000 0000 0011 ->3原反补码
                	0000 0000 0000 0000 0000 0000 0000 0011 ->3原反补码
                	0000 0000 0000 0000 0000 0000 0000 0000 异或结果
                	int d = c ^ a;
                	0000 0000 0000 0000 0000 0000 0000 0000 ->c
                	0000 0000 0000 0000 0000 0000 0000 0011 ->a
                	0000 0000 0000 0000 0000 0000 0000 0011 异或结果
                	int e = a ^ a ^ b;
                	int f = a ^ b ^ a;
                	return 0;
                }
                

                爱上C语言:操作符详解(下)

                由上面的例子,我们可以得到以下结论👇

                相同数字异或结果为0即a ^ a = 0,0与任何数字异或仍为该数字即0 ^ a = a

                并且^支持交换律与结合律即a ^ b ^ c = a ^ c ^ b

                ~按位取反: 操作数在内存中的补码按二进制位0改为1,1改为0

                🌰栗子

                int main()
                {
                	int a = 0;
                	0000 0000 0000 0000 0000 0000 0000 0000 ->0的原反补码
                	1111 1111 1111 1111 1111 1111 1111 1111 ->按位取反结果
                	1000 0000 0000 0000 0000 0000 0000 0001 ->原码值为-1
                	int c = ~a;
                	return 0;
                }
                

                爱上C语言:操作符详解(下)

                注意:他们的操作数必须为整数

                ✈️一道变态面试题

                不创建新变量交换两个整数

                int main()
                {
                	int a = 10;
                	int b = 12;
                	a = a ^ b;
                	b = a ^ b;
                	a = b ^ a;
                	return 0;
                }
                

                上面代码是不是很懵 😆,第一次我也很懵逼,我们接着看👇

                a = a ^ b这时a的值不在是10而是10 ^ 12,然后b = a ^ b实际上是b = 10 ^ 12 ^12,由上面我们知道的^的特点可知10 ^ 12 ^ 12 = 10,这时b = 10,在看这句a = a ^ b实际上是a = 10 ^ 12 ^ 10,而10 ^ 12 ^ 10 = 12这时a = 12所以a和b的值完成了交换

                🚀单目操作符

                单目操作符的分类:

                !           逻辑反操作
                -           负值
                +           正值
                &           取地址
                sizeof      操作数的类型长度(以字节为单位)
                ~           对一个数的二进制按位取反
                --          前置、后置--
                ++          前置、后置++
                *           间接访问操作符(解引用操作符)
                (类型)       强制类型转换
                

                ✈️ 逻辑反操作(!)

                🌰栗子

                int main()
                {
                	int a = 0;
                	int b = 4;
                	if (!(b == 4))
                		printf("真");
                	printf("%d ", !a);
                	printf("%d\n", !b);
                	return 0;
                }
                

                爱上C语言:操作符详解(下)

                逻辑反操作即把0 (假) 改为1 (真) ,非0 (真) 改为0 (假)

                ✈️sizeof

                sizeof这个操作符,sizeof是由来计算变量(类型)所占空间的大小,不关注存储的内容,单位是字节

                int main()
                {
                	int a = 2;
                	int b[4] = { 0 };
                	char c = '1';
                	printf("%u\n", sizeof(b));
                	printf("%u\n", sizeof(b[0]));
                	printf("%u\n", sizeof(a));
                	printf("%u\n", sizeof(c));
                	printf("%u\n", sizeof(int));
                	return 0;
                }
                

                爱上C语言:操作符详解(下)

                sizeof的操作数为数组名时计算的整个数组的大小

                🚀剩下的操作符

                其中有一些过于简单相信大家都掌握了,至于**结构体成员访问操作符(.)和(->)**会在后续结构体章节详细讲到, **解引用操作符(*)和取地址操作符(&)**会在后续数组篇中讲解

                🚀复杂的表达式如何计算

                C语言的操作符有2个重要的属性:优先级、结合性,这两个属性决定了表达式求值的计算顺序

                ✈️优先级

                相邻操作符的优先级高的先算

                int main()
                {
                	int a = 3;
                	int b = 4;
                	a - b * a;
                }
                

                上述代码*乘的优先级更高先算b * a而不是先算a - b

                ✈️结合性

                当相邻两操作符优先级相同就要看结合性了,左结合从左向右计算,右结合从右向左计算

                int main()
                {
                	int a = 3;
                	int b = 4;
                	a / b * a;
                }
                

                上述代码中/和*的优先级相同都是左结合,因此先算a / b

                下面是一张操作符优先级与结核性的表

                爱上C语言:操作符详解(下)

                虽然我们知道了操作符的结合性与优先级,但这并不能保证表达式具有唯一计算路径,因此尽量不要写过于复杂的表达式很容易出bug


                到这里,阿辉今天对于C语言中操作符的分享就结束了,希望这篇博客能让大家有所收获, 如果觉得阿辉写得不错的话,记得给个赞呗,你们的支持是我创作的最大动力🌹

                爱上C语言:操作符详解(下)

VPS购买请点击我

免责声明:我们致力于保护作者版权,注重分享,被刊用文章因无法核实真实出处,未能及时与作者取得联系,或有版权异议的,请联系管理员,我们会立即处理! 部分文章是来自自研大数据AI进行生成,内容摘自(百度百科,百度知道,头条百科,中国民法典,刑法,牛津词典,新华词典,汉语词典,国家院校,科普平台)等数据,内容仅供学习参考,不准确地方联系删除处理! 图片声明:本站部分配图来自人工智能系统AI生成,觅知网授权图片,PxHere摄影无版权图库和百度,360,搜狗等多加搜索引擎自动关键词搜索配图,如有侵权的图片,请第一时间联系我们,邮箱:ciyunidc@ciyunshuju.com。本站只作为美观性配图使用,无任何非法侵犯第三方意图,一切解释权归图片著作权方,本站不承担任何责任。如有恶意碰瓷者,必当奉陪到底严惩不贷!

目录[+]