C语言百炼成神·第三日·操作符
Posted kikokingzz
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了C语言百炼成神·第三日·操作符相关的知识,希望对你有一定的参考价值。
🌕写在前面
hello🤗大家好啊,我是kikokingzz,名字太长不好记,大家可以叫我kiko哦~
从今天开始,我将正式开启一个新的打卡专题——《C语言百炼成神计划》,没错!百炼成神,目的是通过百天刷题计划,通过题目和知识点串联的方式,完成C语言的复习和巩固;后期还会配有专门的笔记总结和文档教程哦!想要搞定,搞透C语言的同学
🎉🎉欢迎持续关注!🎉🎉
🍊博客主页:kikoking的江湖背景🍊
🌟🌟往期回顾🌟🌟
目录
📜008.昨日作业 ⭐️⭐️⭐️⭐️⭐️
008.已知int i=1, j=2;,则表达式i+++j的值为( )
A. 1
B. 2
C. 3
D. 4
🍯本题考点:前置++ 与 后置++ 的优先级
🥃解题思路:脑门子打歪做过就会法
小明:老师,这题的解题思路怎么是这个?🤨
kiko:因为,这只是一道题,平时写代码千万不要这么写!!会被🤕
小明:老师我算出来两个答案诶,一个是3,另一个是4
kiko:那你说说你这两个分别是怎么计算的呢?
小明:如果把表达式看成 i++ + j的话,算出来是3;但如果看成 i + ++j的话,算出来是4
kiko:正确答案是4,maybe因为C编译器的贪心法
🍹知识点7:编译器的贪心法
·什么是编译器的贪心?
编译器将程序分解成符号的方法是,从左到右一个字符一个字符地读入,如果该字符可能组成一个符号,那么再读入下一个字符,判断已经读入的两个字符组成的字符串是否可能是一个符号的组成部分;如果可能,继续读入下一个字符,重复上述判断,直到读入的字符组成的字符串已不再可能组成一个有意义的符号。这个处理策略有时被称为“贪心法”。当然,这与算法中的贪心法不同。
#include<stdio.h> int main() int i = 1, j = 2; printf("%d", i+++j);//+++之间没有空格,编译器读到+后,贪心往后多读一位,读成i++ //结果输出3
#include<stdio.h> int main() int i = 1, j = 2; printf("%d", i+ ++j);//+++有空格,编译器读到+后,贪心多读一位,没有读到多余符号,单纯加号 //结果输出4
kiko:实在不好理解,你就记住后置++优先级更高吧~
🍹知识点8:后置++的优先级高于前置++
小明:这题蛮离谱的。
kiko:对呗,所以是脑门子打歪了,做过一遍记住就会了咯~
🍺009.题目难度 ⭐️⭐️⭐️
009.写一个函数,不能创建临时变量(第三个变量),实现两个数的交换
🍯本题考点:位运算符的应用
🥃解题思路:见过就会法
小明:老师,这个解题思路看起来好随意啊🤣
kiko:哪里随意了😤,见多识广难道不是好方法吗(主要是老师当时也没想出来)
小明:哈哈哈哈哈哈,原来老师也不太行嘛
kiko:哼哼!赶紧做题!
🍹知识点9:位运算符
从运算符的名字来看,不难看出位运算符是对二进制位进行运算:
- 按位与 & : 同1为1;有0则0
- 按位或 |: 有1为1;同0则0
- 按位异或 ^:相异为1;相同为0
- 注: 他们的操作数必须是整数
我们具体可以看下面这个例子:
int main() int a = 3;// 00000000 00000000 00000000 00000011 —3的补码 int b = -5;// 11111111 11111111 11111111 11111011 -5的补码 int c = a & b;//按位与 00000000 00000000 00000000 00000011 == 3 int d = a | b;//按位或 11111111 11111111 11111111 11111011 ==-5 int e = a ^ b;//按位异或 11111111 11111111 11111111 11111000 ==-8 printf("%d\\n", c);// 3 printf("%d\\n", d);// -5 printf("%d\\n", e);// -8 return 0;
小明:那位运算与这道题又有什么关系呢🧐?
kiko:这里其实具体考到了位运算中的异或运算
🍹知识点10:异或运算的巧妙作用
· 按位异或 ^:相异为1;相同为0
·性质1:0 ^ (任何非0数x) = x
·性质2: x ^ x = 0 ;任意两个相同的数异或结果为0
·性质3:异或运算中的运算顺序可以任意颠倒
例如:a ^ b ^ c = a ^ c ^ b = b ^ a ^ c = b ^ c ^ a = ···
kiko:本题的巧妙交换就是通过结合上述3个性质得以实现
🍹解题步骤
例如我们需要交换 a 和 b 的值
第一步:a = a ^ b; b保持不变 第二步:b = a ^ b;//这时b = a ^ b ^ b = a ^ 0 = a, 此时a的值赋值给了b 第三步:a = a ^ b;//这时a = a ^ b ^ a = b ^ 0 = b, 此时b的值赋值给了a
具体程序实现如下:
int main() int a = 3; int b = 5; printf("交换前:a=%d b=%d\\n", a, b); a = a ^ b; b = a ^ b;//a^b^b=a a = a ^ b;//a^b^a=b printf("交换后:a=%d b=%d\\n", a, b); return 0;
小明:这也太妙啦!
kiko:是叭,赶紧码住收藏起来呀!
🍺010.题目难度 ⭐️⭐️⭐️
010.编写代码实现:求一个整数存储在内存中的二进制中1的个数
🍯本题考点:位运算符与移位运算符
🥃解题思路:见过就会法
小明:这题也是见过就会法呀🤩~
kiko:那可不,位运算这块还得靠多见多做才能拿捏住呢!
🍹知识点11:移位运算符
左移运算符
·左移运算:左边抛弃、右边补0
具体例子如下:
右移运算符
·逻辑右移:补0(无符号数必须逻辑右移)
·算术右移:补最高位(基本上对有符号数使用算术右移)
具体例子如下:
ps:对于位级运算的底层细节在我的CSAPP专栏中有详细阐述
对想要提前通过C语言深入理解计组和计算机系统的同学可以订阅哦!
移位运算具体详细内容可见:🔥2.1.9C语言中的移位运算
🍹解题步骤
解题细节:
1.如果该整数与1相&的结果为1,说明二进制位有一个1,但是这仅比较了该整数的最后一位
2.将该整数右移1位,然后继续与1相&,如果结果为1,说明二进制位还有一个1,反之
3.一直将该整数右移至其最终变为0
具体例子:
求5的二进制代码中有几个1 00000000 00000000 000000000 00000101 5的补码 00000000 00000000 000000000 00000001 1 将5&1 if(5&1==1) count++ 00000000 00000000 000000000 00000010 5>>1 00000000 00000000 000000000 00000001 1 (5>>1)&1==0 此数不为0 00000000 00000000 000000000 00000001 5>>2 00000000 00000000 000000000 00000001 1 (5>>2)&1==1 count++
具体程序实现如下:
int main() int a = 0; int count = 0; printf("输入一个整数:\\n"); scanf("%d", &a); while(a!=0) //当这个整数变为0时,退出循环 if ((a & 1) == 1) //如果该整数与1相与的结果为1,说明二进制位有一个1 count++; //这个整数中的1的个数+1 a>>= 1; //将这个整数右移1位 printf("该数二进制中1的个数为%d", count);
📜今日作业 ⭐️⭐️⭐️⭐️⭐️
下面代码的结果是:( )
#include <stdio.h>
int main()
int a, b, c;
a = 5;
c = ++a;
b = ++c, c++, ++a, a++;
b += a++ + c;
printf("a = %d b = %d c = %d\\n:", a, b, c);
return 0;
A.a = 8 b = 23 c = 8
B.a = 9 b= 23 c = 8
C.a = 9 b = 25 c = 8
D.a = 9 b = 24 c = 8
以上是关于C语言百炼成神·第三日·操作符的主要内容,如果未能解决你的问题,请参考以下文章