【C语言】-操作符深度解剖

本文深入探讨了整数在内存中的存储方式,重点讲解了原码、反码和补码的概念及其在正负整数表示中的差异。此外,详细阐述了算数和移位操作符的使用,包括左移和右移,并通过实例展示了位操作符如按位与、按位或和按位异或的功能。文章还介绍了单目操作符、逻辑操作符、条件操作符、逗号表达式以及结构体访问操作符的用法,并提供了实际的代码示例,帮助读者理解这些概念在编程实践中的应用。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

目录

前言

1、进制和原码、反码、补码

2、操作符解析

2.1、算数操作符   

2.2、移位操作符

2.2.1、左移操作符(<<)

2.2.2、右移操作符(>>)

2.3、位操作符

2.3.1、&--按位与

2.3.2、|--按位或

2.3.3、^--按位异或

2.3.4、应用

2.4、单目操作符

2.4.1、应用~、&、|

2.5、逻辑操作符

2.6、条件操作符

2.7、逗号表达式

2.8、访问结构体操作符

2.9、表达式求值

2.9.1、整形提升

2.9.2、算术转换

总结


前言

本次学习内容:原码、反码、补码、操作符、操作符在内存中的存储


1、进制和原码、反码、补码

大家都知道整数在内存中以二进制的形式存储,那你知道具体是怎么存储的吗?其实啊,它是以补码的方式存储的。下面就由我们一起来看看。

首先1个整数占四个字节,每个字节占8个比特位,所以一个整数占32个比特位,举个例子:

整数3,它的二进制(0~1)位是00000000000000000000000000000011,共32个比特位。同时3也可以用八进制(0~7)表示,十六进制(0~15)表示,而2本身是十进制(0~9)表示的。

那么什么是原码、反码、补码,他们之间有什么关系呢?

整数的二进制表示要分正整数和负整数

正整数:原码反码补码一样

负整数:原码:即上面所说的二进制位

              反码保留符号位->最高位,其他位置按位取反

                        注意:最高位是符号位   0->正数   1->负数

              补码反码+1,内存中,整数在内存中存的是补码

例子:5  

原码反码补码都为:

           00000000000000000000000000000101

例子:-5(位数没变,间距问题)

原码:10000000000000000000000000000101

反码:11111111111111111111111111111010

补码:11111111111111111111111111111011

2、操作符解析

2.1、算数操作符   

+    -    *    /    %

注意:/分整数除法和小数除法,要想实现小数除法,/左右至少有一个浮点数

          %  取模操作符的两端必须是整数。

2.2、移位操作符

意义:移位指向左向右移动该整数的补码,不支持小数移位,也不支持移负数位或小数位

如:1.5<<1,另外a<<-1或a<<1.5也是错的

2.2.1、左移操作符(<<)

遵循:左边丢弃,右边补0

例子:

 小结论:左移n位,相当于a*2^n

2.2.2、右移操作符(>>)

1、算数右移:右边丢弃,左边补符号位

2、逻辑右移:右边丢弃,左边补0

注意:一般来说,编译器都是用的算数右移。

例子:

7->3

-7->-4

右移的情况和左移差不多

2.3、位操作符

意义:位指的是按二进制位

2.3.1、&--按位与

遵循:有0取0,同1才1

例子:

2.3.2、|--按位或

遵循:有1则1,同0才0

2.3.3、^--按位异或

遵循:相同取0,不同取1

^异或结论

a=3    b=-5

a^0=a         a^a=0   并且^满足交换律

所以a^b^a=b       b^a^b=a

例子:

要求:不创建临时变量实现两个数的交换

代码如下

#define _CRT_SECURE_NO_WARNINGS
#include<stdio.h>
//不创建临时变量,实现两个数的交换

//如果可以创建临时变量则和平时的交换一样
int main()
{
	int a = 10;
	int b = 20;
	printf("交换前:%d %d\n", a, b);

	法一   要考虑a+b可能溢出的问题
	//a = a + b;
	//b = a - b;
	//a = a - b;
	//printf("交换后:%d %d", a, b);

	//法二
	a = a ^ b;
	b = a ^ b;       //此时的a=10^20
	a = a ^ b;
	printf("交换后:%d %d", a, b);

	return 0;
}

2.3.4、应用

编写一个代码:求一个整数存储在内存中的二进制1的个数

代码如下:

#include<stdio.h>
int main()
{
	int a = 5;
	int cnt = 0;
	int i = 0;
	for(i=0;i<32;i++)
	{
		
		if(a & 1)
		{
			cnt++;
		}
		a >>= 1;

	}
	printf("%d\n", cnt);
	return 0;
}

2.4、单目操作符

!逻辑反操作     

-   负值     

+  正值

&  取地址

sizeof  求长度(单位是字节)(而strlen()是一个求字符串长度的函数)

~  对一个数的二进制(补码)按位取反

--    前置、后置

++  前置、后置

*     间接访问操作符(即解引用操作符,配合指针使用)

(类型)  强制类型转换

2.4.1、应用~、&、|

编写一个代码:将一个数的二进制的某一位值改变

总结:把第i位改为1:a|=1<<i  其中(0<=i<=32)

           把第i位改为0:a&=~(1<<i)  其中(0<=i<=32)

 代码如下:

#include<stdio.h>
int main()
{
	int a = 13;
	printf("改变前:%d\n", a);
	a |= 1 << 1;
	printf("0->1:%d\n", a);
	a &= ~(1 << 1);
	printf("1->0:%d\n", a);
	return 0;
}

演示:

2.5、逻辑操作符

&&    --左边为假,右边就不计算了

||       --左边为真,右边就不计算了

2.6、条件操作符

遵循:

a>b?a:b

a>b为真,结果为a(b不计算),否则为b(a不计算)

2.7、逗号表达式

遵循:','前的式子依次计算,结果为最后一个表达式的结果

如:a=1,b=2     c=(a>b,a=b+10,a,b=a+1)--->c=13

2.8、访问结构体操作符

如struct Stu* p=&a   ,a是一个结构体

.(点)  --结构体+成员名          (*p).

->          --结构体指针+成员名      p ->

2.9、表达式求值

遵循:考虑优先级和结合性,还有一个:隐式类型转换

隐式类型转换:当表达式中的字符短整型在使用前被转换为整形,这种情况叫整形提升

2.9.1、整形提升

整形提升:高位补符号位,低位不变

例子:

如char a=1;

变量a的二进制补码中只有8个比特位

:00000001

因a为有符号的char,整形提升时,高位补符号位,结果为

:00000000000000000000000000000001

代码如下(证明整形提升):

//证明整形提升
#include<stdio.h>
int main()
{
	char c = 5;
	printf("c的大小:%d\n", sizeof(c));
	printf("c的大小:%d\n", sizeof(+c));

	return 0;
}

演示:

整形提升的意义:

表达式的整形运算要在CPU的相应运算器件内执行,CPU内的整形运算器(ALU)的操作数的字节长度一般就是int的字节长度,同时也是CPU通用寄存器的长度。

通用CPU是难以直接实现两个8比特字节直接相加运算,所以,表达式中各种长度可能小于int长度的整型值,都必须先转换为int 或unsigned int,然后才能送入CPU去执行运算

2.9.2、算术转换

和整形提升相对地,类型大小>=int时,会发生算术转换


总结

以上就是今天要讲的内容,本文介绍了移位操作符,位操作符,按位取反操作符等等及它们的应用,还有整形提升和算数转换等内容

评论 4
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

学Java的冬瓜

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值