一、选择题
1、下面哪个是位操作符:( )
A.&
B.&&
C.||
D.!
答案解析:
答案:A
A正确,&——按(二进制)位与,对应的二进制位:有0则0,两个同时为1才为1。
B、C错误,&&与||——逻辑操作符
D错误,!——单目操作符
知识点:
1、位操作符:
(1)运算规则:
①&——按(2进制)位与,对应的二进制位:有0则0,两个同时为1才为1
②|——按(2进制)位或,对应的二进制位:有1则1,两个同时为0才为0
③^——按(2进制)位异或,对应的二进制位:相同为0,相异为1
(2)注意:
①他们的操作数必须是整数
②是针对二进制位进行运算的
2、逻辑操作符
(1)运算规则
①&&——逻辑与(并且:参与运算的两个逻辑值都为真时,结果为真)
②||——逻辑或(或者:参与运算的两个逻辑值都为假时,结果为假)
(2)逻辑操作符的短路特性
①&&操作符,左边为假,右边无需计算
②||操作符,左边为真,右边无需计算
(3)注意区分逻辑与(或)和按位与(或)
①逻辑与(或)----->只关注真假
②按位与(或)----->通过二进制计算得到
二、编程题
1、交换两个变量(不创建临时变量)
不允许创建临时变量,交换两个整数的内容
方法1:计算得到
方法2:使用按位异或操作符
知识点:
1、按位异或操作符
(1)运算规则:^——按(二进制)位异或,对应的二进制位:相同为0,相异为1
(2)性质:
①a^a=0
②0^a=a
③异或支持交换律:a^a^b=a^b^a
(3)异或操作符交换两个变量的局限性
①可读性差
②效率也不如使用临时变量的方法
③异或只针对整数的交换
代码1:计算得到
#include<stdio.h> int main() { int a = 0; int b = 0; //输入a,b scanf("%d %d", &a, &b); //打印交换前a,b printf("交换前:a=%d b=%d\n", a, b); //交换a,b a = a + b; b = a - b; a = a - b; //打印交换后a,b printf("交换后:a=%d b=%d\n", a, b); return 0; }
代码2:使用按位异或
#include<stdio.h> int main() { int a = 0; int b = 0; //输入a,b scanf("%d %d", &a, &b); //输出交换前a,b printf("交换前:a=%d b=%d\n", a, b); //交换a,b a = a ^ b; b = a ^ b; a = a ^ b; //输出交换后a,b printf("交换后:a=%d b=%d\n", a, b); return 0; }
2、统计二进制中1的个数
1、在网上平台答编程题(如牛客网),有两类:
①IO型:从main函数开始写,要写输入、计算、输出等
②接口型:不需要写主函数,默认主函数就是存在的(后台存在),你只需要完成函数就可以了。
本题就是一道接口型。
我们平时练习可以在自己的编译器,先实现再复制粘贴到答题平台上验证。
代码1:
我们是怎么得到10进制整数的每一位的?
类比:
这种方法虽然也能求出2进制中1的个数,但是我们把题目给的形参改变了,所以不符合题意。排除掉。
#include<stdio.h> int NumberOf1(unsigned int n) { int count = 0;//计数器,统计1的个数 //循环%2 /2,直到n等于0 while (n) { if (n % 2 == 1) { count++; }//如果是1,统计 n /= 2;//循环调整部分 } return count; } int main() { int n = 0; //输入 scanf("%d", &n); //计算--调用函数 int ret = NumberOf1(n); //输出 printf("%d\n", ret); return 0; }
代码2:
我们写的这个代码没有修改题目函数的返回类型、函数名、形参所以粘贴复制到牛客网是成功的。
知识点:
1、>>右移操作符
移位规则:
①(常见如VS)算术右移:左边补原来的符号位,右边抛弃
②逻辑右移:左边直接补0,右边抛弃
2、&——按位与
移位规则:对应的二进制位:有0则0,两个同时为1才为1
3、总结:我们判断一个数的每一位的数时,通常从低位入手
4、n虽然发生了右移,但是实际上n在没有被赋值的情况下,自身的值不会发生变化(即n>>i的结果是移位之后的效果,但是n是不变的)
#include<stdio.h> int NumberOf1(int n) { int count = 0;//计数器,统计1的个数 int i = 0;//循环变量 //循环32次,每次右移i for (i = 0; i < 32; i++) { if ((n >> i) & 1) { count++; } } return count; } int main() { int n = 0; //输入 scanf("%d", &n); //计算--调用函数 int ret = NumberOf1(n); //输出 printf("%d\n", ret); return 0; }
代码3:
但是还有效率更高的解法:
我们粘贴函数部分上牛客验证:
#include<stdio.h> int NumberOf1(int n) { int count = 0;//计数器,统计1的个数 while (n) { n = n & (n - 1); count++; } return count; } int main() { int n = 0; //输入 scanf("%d", &n); //计算--调用函数 int ret = NumberOf1(n); //输出 printf("%d\n", ret); return 0; }