【C语言】浅谈操作符

今天我分享的主要是操作符中位操作符的知识点讲解,并将我觉得比较有挑战性有价值的题目分享出来,你们可以做一做,挑战一下自己!

目录

一、如何不利用第三个变量,实现两个变量的交换

二、如何把一个数的内存形式的某一位置1或0呢

三、如何统计二进制中1的个数

 四、如何判断1个数是不是2的n次方???

五、判断两个数不同的二进制位的位数 

六、输出一个数的奇数位序列和偶数列序列

 七、

八、整型提升


一、如何不利用第三个变量,实现两个变量的交换

位操作符:按位与&、按位或|、按位异或^(同为0,异为1)

a^a=0,a^0=a

借助第三个变量实现这个功能很简单

#include <stdio.h>
int main(){
int a=3;
int b=5;
int c=a;
a=b;
b=c;
printf("%d %d",a,b);
return 0;
}

那么如果不借助第三个变量呢,这个功能又该怎么实现呢

#include <stdio.h>
int main(){
int a=3;
int b=5;
a=a^b;
b=a^b;
a=a^b;
printf("%d %d",a,b);
return 0;
}

也不难,对吧,嘿嘿~

二、如何把一个数的内存形式的某一位置1或0呢

一个数有三种二进制表示方法:原码、反码、补码;内存是以补码形式存储。

正数:原码=反码=补码;

负数:反码是原码符号位不变,其他位按位取反,补码是反码+1。

左移<<:丢弃左边码,右边码补0;

右移>>:逻辑右移:丢弃右边码,左边码补0;

             算术右移:丢弃右边码,左边码补符号位(负数补1,正数补0);

~:对一个数的二进制数按位取反,符号位也是。

#include <stdio.h>
int main(){
int a=10;//  00000000000000000000000000001010
a=a|(1<<2);//00000000000000000000000000001110
printf("%d",a);//14
return 0;
}

如何让它变回去

#include<stdio.h>
int main(){
int a=14;     //00000000000000000000000000001110
a=a&(~(1<<2));//11111111111111111111111111111011
printf("%d",a);//10
return 0;
}

嘿嘿,你学会了蛮

考考你,这道题答案是几,可以评论区留言哦~

#include <stdio.h>
int main() {
	int a = -1;
	a = a & (~(1 << 3));
	printf("%d", a);
	return 0;
}

三、如何统计二进制中1的个数

方法一:

#include <stdio.h>
int main(){
int a=15;
int i=0;
int count=0;
for(i=0;i<32;i++){
count+=(a>>i)&1;
}
printf("%d",count);
return 0;
}

方法二:

a=a&(a-1)

a     00001111 

a-1  00001110

a     00001110

a-1  00001101

a     00001100

a-1  00001011

a     00001000

a-1  00000111

a     00000000

操作的次数与1的个数相同

#include<stdio.h>
int main(){
int a=15;
int count=0;
while(a){
a=a&(a-1);
count++;
}
printf("%d",count);
return 0;
}

 四、如何判断1个数是不是2的n次方???

如果上一道题学会的话,就来看看这道题吧!

#include <stdio.h>
int main(){
int a=15;
if((a&(a-1))==0)printf("Y\n");
else printf("N\n");
return 0;
}

五、判断两个数不同的二进制位的位数 

思路就是先将两数进行按位异或,再统计异或后的结果的1的个数。

#include<stdio.h>
int main(){
int a=15;
int b=37;
int ret=a^b;//按位异或,同为0,异为1
int count=0;
while(ret){
ret=ret&(ret-1);
count++;
}
printf("%d",count);
return 0;
}

六、输出一个数的奇数位序列和偶数列序列

#include<stdio.h>
int main() {
	int a = 1022;
	int i = 0;
	for (i = 31; i >= 1; i-=2) {
		printf("%d", (a >> i) & 1);
	}//偶数位
	printf("\n");
	for (i = 30; i >= 0; i-=2) {
		printf("%d", (a >> i) & 1);
	}//奇数位
	return 0;
}

 七、

#include<stdio.h>
int main() {
	short a = 10;
	int b = 30;
	printf("%u", sizeof(a = a + b));
	return 0;
}

这道题答案是几呢?4?2?2!

sizeof 括号中不进行运算。

八、整型提升

当运算中,不足整型长度的短整型和字符型要进行整型提升,有符号高位补齐符号位,无符号高位默认补0。

#include<stdio.h>
int main(){
char a=5;   //00000101//00000000000000000000000000000101
short b=-3; //1000000000000011原码
            //1111111111111100反码
            //1111111111111101补码
            //11111111111111111111111111111101
char c=a+b; //00000000000000000000000000000010
            //00000010
printf("%d\n",c);//00000000000000000000000000000010//2
printf("%u\n",sizeof(c));//1
printf("%u\n",sizeof(+c));//4
return 0;
}

为啥前面说sizeof括号中不进行运算,现在sizeof(+c)又进行整型提升了嘞???

因为数据有两种属性(值属性;类型属性)。.

以上就是我今天分享的内容!希望你们有所收获!!!如果有什么建议或补充欢迎评论区留言哟! 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值