C 语言

关注公众号 jb51net

关闭
首页 > 软件编程 > C 语言 > C语言 操作符

C语言操作符超详细讲解上篇

作者:初学C语言者

C 语言提供了丰富的操作符,有:算术操作符,移位操作符,位操作符,赋值操作符,单目操作符,关系操作符,逻辑操作符,条件操作符等。因为篇幅过大将分两篇讲解,让我们通读本篇来详细了解吧

前言

操作符主要内容包括:各种操作符的介绍,用表达式求值。

1、操作符的分类

2、算术操作符

 +  -  *  /  %  (加法 减法 乘法 取余 取模)
int main()
{
	int a = 9 / 2;//4
	float b = 9 / 2;
	int c = 9.0 / 2;
	float d = 9.0 / 2;//4.5
	float e = (float)9.0 / 2;

	printf("%d\n", a);
	printf("%f\n", b);
	printf("%d\n", c);
	printf("%f\n", d);
	printf("%f\n", e);
	return 0;
}

运行结果见下图:

在这里插入图片描述

在这里插入图片描述

在这里插入图片描述

通过例子可发现,变量的类型使用错误的话,结果也是错误的

3、移位操作符

移位操作符的操作数只能是整数

<< 左移操作符
>> 右移操作符

3.1 左移操作符

(1)先将整数的原码转换成反码

(2)反码 +1转换成补码

(3)最后对整数的补码进行操作

(4)操作结束后,将操作后的补码 -1 转换成反码

(5)将反码转换成最终的原码

3.1.1 正数左移1位

代码如下(示例):

int main()
{
	int a = 5;
	int b = a << 1;//操作的补码二进制位,a本身结果不变
	printf("%d\n", a);//打印5
	printf("%d\n", b);// -10
	return 0;
}

在这里插入图片描述

结果运行见下图,与分析的结果一致,左移1位的效果相当于乘以2,左移在51单片机、STM32中,操作寄存器会经常用到。

在这里插入图片描述

3.1.2 负数左移1位

int main()
{
	int a = -5;
	int b = a << 1;//<< >> 操作的二进制位
	printf("%d\n", a);//打印-5
	printf("%d\n", b);// -10
	return 0;
}

在这里插入图片描述

运行结果见下图,和分析的结果一致

在这里插入图片描述

3.2 右移操作符

右移移位规则运算分两种:

3.2.1 正数右移1位

int main()
{
	int a = 5;
	int b = a >> 1;//右移不一定是除2

	printf("%d\n", a);//打印-5
	printf("%d\n", b);// -3
	return 0;
}

下面分析右移的过程:正数的原码、反码、补码一样

00000000 00000000 00000000 00000101 //5的二进制补码
//算术右移:左边用原该值的符号位1填充,右边丢弃1
00000000 00000000 00000000 00000010 //右移后的补码
//右移后的补码就是右移后的原码  2

结果见下图:

在这里插入图片描述

3.2.2 负数右移1位

int main()
{
	int a = -5;
	int b = a >> 1;//右移不一定是除2

	printf("%d\n", a);//打印-5
	printf("%d\n", b);// -3
	return 0;
}

下面分析右移的过程:

10000000 00000000 00000000 00000101 //-5的二进制原码
11111111 11111111 11111111 11111010 //反码
11111111 11111111 11111111 11111011 //补码:反码+1
//算术右移:左边用原该值的符号位1填充,右边丢弃1
11111111 11111111 11111111 11111101 //右移后的补码
11111111 11111111 11111111 11111100 //反码:补码-1
10000000 00000000 00000000 00000011 //原码  -3

结果见下图:

在这里插入图片描述

3.3 移位操作符说明

注意事项:

int num = 10;
num>>-1;//10右移-1位,这是错误的表达

4、位操作符

位操作符有:

& //按位与     相同为1, 相异为0
| //按位或     有1为1, 全0为0
^ //按位异或    相同为0, 相异为1
//注:他们的操作数必须是整数

int main()
{
	int a = 3;
	int b = -5;
	int c = a & b;
	int d = a | b;
	int e = a ^ b;//异或
	//对应的二进制位:相同位0,相异为1
	printf("%d\n", c);// 打印3
	printf("%d\n", d);// -5
	printfan("%d\n", e);// -8	
	return 0;
}

00000000 00000000 00000000 00000011   3的补码
11111111 11111111 11111111 11111011   -5的补码
//按位与:  相同为1, 相异为0
00000000 00000000 00000000 00000011    3的补码,原码表示3
//按位或:   有1为1, 全0为0
11111111 11111111 11111111 11111011   -5的补码,原码表示-5
//按位异或: 相同为0, 相异为1
11111111 11111111 11111111 11111000  补码
11111111 11111111 11111111 11110111  反码
10000000 00000000 00000000 00001000  原码 -8

输出结果见下图,与分析一致:

在这里插入图片描述

4.1 练习 1

不能创建临时变量(第三个变量),实现两个数的交换

int main()
{
	int a = 3;
	int b = 5;

	printf("a=%d b=%d\n", a, b);
	//第一种,常用的方法,创建中间变量
	int tmp = a;
	a = b;
	b = tmp;	
	//第二种,不创建变量
	a = a + b;
	b = a - b;
	a = a - b;
	//第三种,不创建变量,很难想到
	a = a ^ b;
	b = a ^ b;
	a = a ^ b;
	printf("a=%d b=%d\n", a, b);
	return 0;
}

4.2 练习 2

求一个整数存储在内存中的二进制中1的个数

//举例: 5   &1, 然后右移1位, 再&1
//00000000 00000000 00000000 00000101
//00000000 00000000 00000000 00000001

int main()
{
	int num = 0;
	scanf("%d", &num);
	int i = 0;
	int cnt = 0;
	//位操作
	for ( i = 0; i < 32; i++)
	{//每次右移一位就 &1
		if (1==((num>>i)&1))
		{
			cnt++;//所有位与1,相同为1,相异为0
		}
	}
	printf("%d", cnt);
	return 0;
}

总结

本文对部分操作符进行了,介绍,也分析了操作符的具体实现过程,这里了解原理即可,具体运算交给计算机执行,没必要每个都自己画图分析,耗时,不细心可能还会出错,32位二进制建议大家划分成4个字节,8位一组,好看一些,这在STM32 单片机对寄存器操作时,经常这样划分,一目了然。

下一篇点这里直达

到此这篇关于C语言操作符超详细讲解上篇的文章就介绍到这了,更多相关C语言 操作符内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!

您可能感兴趣的文章:
阅读全文