C语言操作符详解

C语言操作符详解

原码 反码 补码

  1. 原码就是十进制数值转换为二进制对应的值,如果为负数,则最高位为1,否则为0.
 13--->00001101(原码)
-10--->10001010(原码)

  1. 反码,正数的反码为其原码,复数的反码则是最高位不变,其他位则取反。
 13--->00001101--->00001101(反码)
-10--->10001010--->11110101(反码)

  1. 补码,正数的补码为其原码,而负数的补码则是在其反码最低位加1
  13--->00001101--->00001101--->00001101(补码)
-10--->10001010--->11110101--->11110110(补码)

在计算机内,存储器存储的是补码,计算机进行运算时也是对补码进行加减,同时,操作符对数值进行操作时也是对补码进行操作,并且操作符不会改变原数值,只会产生一个新的结果,而当计算机要输出一个值时,输出的是其原码对应的值,printf打印出的结果也就是原码转换为后的值

补码变原码则是补码取反加一

for example

a=-7;
a对应的补码是111111111111111111111111111111001
算其原码
     先取反:100000000000000000000000000000110
     再加一:100000000000000000000000000000111

printf时,若是%d,则把100000000000000000000000000000111转换为10进制即可
          否则,若是111111111111111111111111111111001,结果一定不是-7


位移操作符

一、左移操作符

<< n

将数值的补码进行向左移动n位,同时每移动一位,右边补0.

int n=1;
int b=0;
b=n<<1;//00000001--->00000010,b=2

在这里插入图片描述

二、右移操作符

n>>

将数值向右移动n位,但是左边补位分两种情况

1. 逻辑右移:左边补0.
11111111--->01111111(向右移动一位)
2. 算术右移:左边补它的符号位
11110101--->11111010(向右移动一位)
01100101--->00110010(向右移动一位)
# include<stdio.h>
int main()
{
	int a = -6;
	a = 1 >> a;
	printf("%d\n", a);
	return 0

}

在这里插入图片描述

但是究竟是算术右移还是逻辑右移取决于编译器,大部分编译器都是算术右移

一般来说右移相当于除2的效果,而左移相当于乘2的效果

位操作符

一、 按位与&

两个数的的补码按位与时,同为1为1,不同为1时为0,与&&相同

a=6
b=-1
a&b
000000000000000000000000000000110
111111111111111111111111111111111


000000000000000000000000000000110



# include<stdio.h>
int main()
{
	int a = 6;
	
	int b = -1;
   int c = a&b;
	printf("%d\n", c);
	return 0;
}


在这里插入图片描述

二 、按位或 |

两个数的的补码按位与时,有为1为1,都为0时为0,与||相同



a=6
b=-1
a|b
000000000000000000000000000000110
111111111111111111111111111111111
111111111111111111111111111111111



# include<stdio.h>
int main()
{
	int a = 6;
	
	int b = -1;
   int c = a|b;
	printf("%d\n", c);
	return 0;
}

在这里插入图片描述

三、按位异或 ^

相同为0相异为1.

a=6
b=-1
a^b
000000000000000000000000000000110
111111111111111111111111111111111
111111111111111111111111111111001


# include<stdio.h>
int main()
{
	int a = 6;
	
	int b = -1;
   int c = a^b;
	printf("%d\n", c);
	return 0;
}

在这里插入图片描述

四按位取反 ~

简单来说就是1变0,0变1

a=6
 a:000000000000000000000000000000110
~a:111111111111111111111111111111001

1. 对于& | ~,这三个操作符,对于初学者学习单片机是非常重要的,比如说在在控制LED灯时就要用到

在这里我举一个实例

# include <REGX52.H>
void main()
{
P3=0xFF;
P2=1//让引脚接P2的LED灯全灭
while(1)
{
if P3_1==0 
{
Delay(20);//按键消抖
while(P3_1);
Delay(20);//按键消抖,同时这个函数需要自己去创建
P2_0=~P2_0;//这样当按下再松开时,就可以点亮一个灯

}

}

}




当然这里写的比较简洁,我们再看一个应用,如何做到不用创建第三个变量来交换两个变量的值

首先,a^0仍然为a原来的值
a^a=0;

	int a = 6;	
	int b = -1;
	 a=a^b;
	 b=a^b;//实际上是a^b^b--->a^0--->a
	 a=a^b;//a^a^b--->0^b--->b


在这里插入图片描述

2. 这里我们再看一个应用,统计一个数的补码的1的个数

# include<stdio.h>
int main()
{
	int n = 0, count = 0;
	printf("请输入一个值\n");
	scanf_s("%d", &n);//输入我们要统计的数
	int i = 0;
    for (i = 0; i < 32; i++)
    {7
      if (((n >> i) & 1 )== 1)
			count++;

	}
	printf("%d中1的个数时%d\n", n, count);
	return 0;
}

在这里插入图片描述

3. 接下来我们看如何判断一个数是否为为2的次方

# include<stdio.h>
int main()
{
   int n=0;
   scanf("%d",&n);
    if(n&(n-1)==0) printf("是偶数\n");
   return 0;

}

这是为什么呢,我们来分析一下

1. 首先2的次方那么它的二进制一定是只有一位是1其余为都是0,
呐有没有可能会有2位及以上是1呢,
当然不可能因为2的x次方与2的x+k次方相加结果是2^x(1+2^k),
三个呢也肯定是偶数与奇数相加(大家可以试着去推一下,还有一件事这里^是次方的意思不是按位异或)
2. 所以说如果说n为2的次方的话,减1后一定是·····01111······1的结果,如果&n的话,结果就必然是0

##五 整型提升
首先我们来看一个情况

char a=3;
char b=127;
char c=a+b;
printf("%d ",c);

那么答案应该是多少呢?是130吗?,当然不是,因为这是字符型变量,130明显超过了char的范围,而且是在整型相加。
由于CPU的整形运算器操作数的字节数长度一般为int型,所以,当进行整形运算,但是,数据类型是缺省整型类型的精度来进行的。那么为了获得整形精度就要进行整型提升(注意接下来的二进制码都为补码)
我们来一步一步看与分析

a=3:00000011
提升后a=000000000000000000000000000000011
b=127:01111111
提升后b=000000000000000000000000011111111
000000000000000000000000000000011
000000000000000000000000001111111
000000000000000000000000010000010
由于char只取8位所以a+b的结果是10000010
而对于printf("%d ",c);
%d是10进制整型格式,所以要把00000010,再次整型提升位int型
111111111111111111111111110000010
得到其原码
100000000000000000000000001111110

在这里插入图片描述

  • 22
    点赞
  • 20
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值