【C语言详解】操作符

2021-11-18-

摘要

操作符

总结

目录

操作符分类

算术操作符

移位操作符

位操作符

赋值操作符

单目操作符

关系操作符

逻辑操作符

条件操作符

逗号表达式

下标引用、函数调用和结构成员

算术操作符

	+	-	*	 /	%
  1. % 为取余也叫模,它的操作数只能是整数,而其他的操作符的操作数既可以为整数也可以为浮点数。
  2. 操作数有浮点数时,则进行算术转换进行浮点数运算。

移位操作符

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

移位操作符对应的是在计算机种的存储形式:补码 (因此移位操作符的操作数仅仅只能是整数。)

左移操作符

对相应的二进制数进行操作。

规则:高位舍去,低位补零。

image-20220412094928520

拓展

左移意味着每一个二进制位的权重会增加1

例如:整形char

假设一个char类型的数据为 6

那么它的二进制表示为

	00000110  	//6
左移一位后:
	00001100	//12

显然任何二进制数都可以表示为:

Σ ∣ ∑ i = 0 n Σ|\sum\limits_{i=0}^{n} Σi=0n​ k * 2i

(k为0或者1)

那么左移一位后,在没有高位溢出的情况下,每一位的权重都增加了1

那么做简单变形:

Σ ∣ ∑ i = 1 n + 1 Σ|\sum\limits_{i=1}^{n+1} Σi=1n+1 k * 2i 根据分配律可得: Σ ∣ ∑ i = 0 n Σ|\sum\limits_{i=0}^{n} Σi=0n​ (k * 2i ) * 2

即乘2操作

注意:仅仅是在无溢出的情况下

右移操作符

移位规则:

  • 算数右移

左边用符号位填充,右边舍弃。

  • 逻辑右移

左边用0填充,右边舍弃。

一般来说我们只针对逻辑右移来讨论:

与左移不同的是,右移操作符在移位的过程中会经常低位非零而被舍弃的情况。

例如:将3右移1位

//逻辑右移
00000011
3 >> 1
00000001

假设 char a = n (n为任何数)

我们准备将 a 右移 k 个位置,可以将其分解为 k 次向右移动一个位置(二进制位)

那么每次分为两种情况

  1. 最低位为1
  2. 最低位为0

最低位为1,即先舍去最低位,那么对应到二进制数则可通过 -1操作来完成,然后在移位。

最低位为0,那么则直接移位,不涉及舍弃有效数问题

通过归纳总结:

可以得到 右移操作:

  1. 如果操作数为奇数 则先 -1 ,再右移。

  2. 如果为偶数,则直接右移。

通过左移操作的推到同理可得,右移可以是 除以2的操作,即与除以2的结果取整等效。

则右移与整除相同,都是结果取整。

如果是对负数进行移位操作呢?

在数据未溢出的情况下,结论是相同的。

左移 <==> 乘2

右移 <==> 除以2(整除)

思考:如果对-1,进行右移 n 位那么结果如何?

11111111111111111111111111111111
    //右移1位
11111111111111111111111111111111

可以看到是未变化的,通过上面得出的结论:

实际上 -1 右移可看作如下步骤:

  1. -1为奇数,因此先-1得到-2;
  2. 进行除以2的操作得到 -1

重复上述过程。

**注意:**对于移位运算符,移动负数位是标准为定义的。

位操作符

	&	按位与
	|	按位或
	^	按位异或	
	
注意:操作数必须为整数

位操作符可以做很多有趣的事情。

对于位操作,我们通常只用进行某一位上对应的二进制值,来获得规律;

异或记住口诀:

相同为0, 相异为1.

可以试想两个个极端情况:

  1. 一个数二进制全为0
  2. 两个数二进制相同

其中一个数全为0的情况:

0 ^ 1 -> 1

0 ^ 0 -> 0

非零数的每一个二进制都没变

那么可以轻松得出异或的值还是等于另一个非零的值

两个数完全一样的情况:

0 ^ 0 -> 0

1 ^ 1 -> 0

无论如何,最终二进制位全为0,

即两个相同值异或会得到 0 。

利用这个特性:

思考:如何不适用第三个变量交换两个变量的值。

通常我们会写出如下代码:

void swap(int* num1, int* num2)
{
   
	int tmp = *num1;
	*num1 = *num2;
	*num2 = tmp;
}

但是这是不符合题意的,但通过位运算,我们可以做到。

void swap(int* n1, int* n2)
{
   
	*n1 = *n1 ^ *n2;
	*n2 = *n1 ^ *n2;
	*n1 = *n1 ^ *n2;
}

拿a和b来举例:

设未经过任何修改的a,b的值也等于_a, _b的值

int main()
{
   
	int a = 10;
	int b = 20;
	a = a ^ b; //(1)
	b = a ^ b; //(2)
	a 
  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值