不允许你还不会用这些操作符(详解c语言操作符)

写在前面:这篇博文为c语言中所有操作符的介绍以及使用它们时要注意的一些点。博主水平有限,文章若有错误之处,望读者斧正。


操作符分类

首先我们要知道c语言的操作符可以分成十大类

  1. 算术操作符
  2. 移位操作符
  3. 位操作符
  4. 赋值操作符
  5. 单目操作符
  6. 关系操作符
  7. 逻辑操作符
  8. 条件操作符
  9. 逗号表达式
  10. 下标引用,函数调用和结构成员操作符

下面开始一个个介绍它们

1.算术操作符

+   -   *   /   %

我们可以用数学中的运算符来理解c语言中的算术操作符,前面三个操作符就没什么好介绍的。对于 / 操作符,只要除号两边的操作数存在浮点数,就执行浮点数除法运算,算出的结果为浮点数;两个操作数都为整数,就进行整数除法运算。在这里插入图片描述
虽然a和b作为两个浮点型变量,能存储浮点数,但在5/2这个表达式中,除号的两个操作数为整形,执行整数除法运算,结果为5/2的商。在表达式5.0/2中,一个操作数为浮点数,执行浮点数除法运算,得到的值就是精确的2.5。

接着是%(取模操作符),取模运算得到的结果是两数相除的余数。
在这里插入图片描述有一个地方要注意,取模操作符的两个操作数必须为整数。

但除了取模操作符之外,其他的操作符都能用作于整数或者浮点数。

2.移位操作符

移位操作符有两个

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

在学习移位操作符之前,我们先要了解整数在计算机中的储存形式。

2.1原码,反码和补码

数据在计算机中都是以补码的形式存储的,提到补码就不得不说原码与反码

原码就是把一个十进制数翻译成二进制序列。符号位不变(符号位为二进制序列的首位),对原码按位取反(把1变成0,0变成1)得到反码,对反码加一得到补码。正数的原码,反码,补码相同。举个例子,把5翻译成二进制序列是多少呢?
在这里插入图片描述
5为整形,整形有4个字节,就是32个比特位,32个二进制位,上面的图片就是计算机眼中的5。由于正数的原码,反码,补码相同,不用对5的二进制序列进行转化,5的补码就是原码。

那-5的二进制序列呢?
在这里插入图片描述
和5的二进制序列一样,只是把符号位改为1,这表示它是一个负数,而这只是-5的原码,由于-5是负数,我们需要对它进行转化,才能得到-5的补码。除了符号位,对其他位按位取反得到反码。
在这里插入图片描述
再对反码加一得到补码。
在这里插入图片描述
-5的三种二进制存储形式。

最终-5以补码的形式存储在内存中,但是我们在打印-5时,又要把-5的补码转化成原码。这个原理暂时不说,其实我不会 因为有点复杂,展开了就偏离这次的主题了。

2.1移位操作符介绍

移位操作符针对的是整数,要移动的位数必须是正整数

对移动的方向进行分类,我们把移位操作符分为左移操作符和右移操作符。先来说说左移操作符,把10左移一位,这个移动操作是怎么实现的?用图片演示左移的过程
在这里插入图片描述

可以看到,10的二进制位向左移动一位,右边空出一位,空位补0,左边舍弃一位。现在表示的数是20,因此,我们能把左移一位理解为乘以2。

与左移不同,右移操作分为逻辑右移与算术右移,具体的移动形式由编译器决定。何为逻辑右移?二进制位向右移动一位,左边的空位补0。算术右移,空位补原来的符号位。什么意思呢?
在这里插入图片描述

上图表示的是-5逻辑右移,无论数字的正负,空位补0,那-5的算术右移呢?
在这里插入图片描述
空位补充的数字由原来数字的符号位决定,原来是负数,空位补1,是正数,空位补0

最后,不要对一个数移动负数位,比如

int num = 5;
num >> -1;

这是什么意思,右移-1位?直接说左移1位不行吗吗?这种代码编译器不能识别出来,我们尽量不要写这种奇怪的代码(正常人谁这样写代码啊),平时要注意,别一不小心写成这样的错误代码了。

3.位操作符

位操作符有三种

& //按位与
| //按位或
^ //按位异或

它们的操作数必须是整数。

3.1按位与

这里的位指的是二进制位,两个数都为1,按位与的结果是1,一个数为0,按位与的结果都是0。举个例子,在这里插入图片描述
在这里插入图片描述
根据0与任何数按位与都等于0,两个数都为1按位与结果为1的原则,结合画图理解,我们就能很好的理解按位与。

3.2 按位或

而按位或也是大同小异,1与任何数按位或都等于1。两个数都为0,按位或结果才为0。这里就不画图了,还是比较简单的。

3.3 按位异或

按位异或的运算原则是:两数相同为0,不同为1。有一个有趣的规律,两个相同的数异或,结果是0;某个数与0异或,结果为本身(结果不变)。运用异或的知识,我们可以在不创建第三个变量的情况下,实现两个数的交换,在这里插入图片描述

4. 赋值操作符

=   +=  -=  *=  /=  %=  >>=   <<=  &=  |=   ^=

顾名思义,我们能运用赋值操作符把值赋给变量。在变量初始化的时候我们能用它来赋初值,之后也能用它来对变量重新赋值在这里插入图片描述
我们不满意60的分数,就对分数重新赋值,现在的分数就变为100了

注意点:不要搞混了= 与 == 这两个操作符,=在c语言中是赋值,两个=是用来判断两个操作数是否相等。

4.1 复合赋值符

当我们要写a = a + 10 时,可以用更简洁的写法,这时就要运用复合赋值符 += ,把表达式写成a += 10。其他的复合赋值符也类似,这里不再一一列举。

5. 单目操作符

!           逻辑反操作
-           负值
+           正值
&           取地址
sizeof      操作数的类型长度(以字节为单位)
~           对一个数的二进制按位取反
--          前置、后置--
++          前置、后置++
*           间接访问操作符(解引用操作符) 
(类型)      强制类型转换

有的操作符在之前已经介绍过了,这里就挑几个重点的讲讲

5.1 !逻辑反操作

我们知道,在计算机中,0表示假,非0表示真。对一个非0的数逻辑反操作得到的是0,0则是假。对0逻辑反操作得到的是1(计算机中的!0始终表示1),1表示真。这就是逻辑反操作的用法。

5.2 前置与后置++

前置++,操作数先自增,再使用。后置++,先使用操作数,再自增。举个例子
在这里插入图片描述
–与++的实现是相似的,这里不再赘述。

5.3 按位取反

对补码的每个二进制位取反(1变成0,0变成1)在这里插入图片描述

6. 关系操作符

>
>=
<
<=
!=   用于测试“不相等”
==      用于测试“相等”

用来判断两个操作数是否相等,注意赋值符=与判断相等符号==的区别

7. 逻辑操作符

&&       //逻辑与
||       //逻辑或

可以用数学里的并且和或者来理解这两个操作符。表示一个数大于0并且小于18时,在数学里是用0 < x < 18表示的,但c语言不这样表示,我们要写成

 x > 0 && x < 18

一定不能写成数学里的形式。

7.1 逻辑短路

在由&&和||组成的表达式中,逻辑短路是经常发生的,那逻辑短路又是什么呢?
在这里插入图片描述
在a++ && b-- && c++这个表达式中,程序按照从左向右的顺序计算,由于a是后置++,先使用后自增,但a的值为0,一个表达式的结果为0,整个表达式的结果就为0,这是逻辑与的特点,所以a++后面的表达式没有必要算下去,程序对a自增后,直接跳过b–与c++,所以从结果中我们看到b与c的值都没变。
在这里插入图片描述
逻辑或呢?把刚刚代码里的逻辑与改成逻辑或,看程序是怎么运行的,a先使用再自增,a为0结果为假,程序继续运行,b–,先使用b,b为1,为真,b自增后程序不再运行(逻辑或中,程序执行的表达式为真,整个表达式就为真,程序没有再运算的必要,所以直接跳出,c的值没有加一。

由于程序直接跳出,我们给这种动作起了个形象的名字:逻辑短路。一些程序阅读题会经常考查这个知识点,在平时做题时要注意逻辑的短路。

8. 条件表达式

条件表达式又叫三目表达式

exp1 ? exp2 : exp3

如果exp1成立,程序执行exp2,若不成立,程序执行exp3。这个表达式我经常用来判断两个数的最大值。

int main()
{
	int a = 10;
	int b = 20;
	max = a > b ? a : b;
}

9. 逗号表达式

(exp1,exp2,exp3...expn)

用逗号把表达式隔开(养成好习惯,逗号表达式一定要加上括号),程序会从左向右运算每一个表达式,逗号表达式的结果是最后一个表达式的结果。不过我们不能直接计算最后一个表达式,因为之前的表达式可能影响最后一个表达式的值。

int a = 1;
int b = 2;
int c = (a++, b++, a + b);

能直接说c的值是3吗?显然,直接计算最后一个式子是错误的,程序要从左向右计算,因此程序先自增a,然后自增b,最后结果是5。

10. 下标引用,结构成员和函数调用

下标引用操作符是[ ],当我们创建数组,想访问数组成员时,就要用到它在这里插入图片描述
更详细的讲解我在数组那篇博文说过了,有兴趣的欢迎访问浅谈数组

函数调用操作符我也说过,再不要脸的贴个链接函数基础知识点讲解

这里主要讲解下结构成员操作符
在这里插入图片描述
. 操作符,左边是结构体变量名,右边是结构体的成员,打印a.name我们就能知道a的书名。用指正变量时,我们也能访问结构体成员,只要对指针变量解引用就行。不对指针变量解引用,我们也可以用->操作符,左边是结构体变量,右边是结构体内容,pa->name表示的是pa指针指向的name。


最后:这篇文章内容太多,整理的时候好几次想放弃(因为自己对这块知识还是比较熟悉的),最后还是肝出来了,并且修改了好多次。如果这篇文章有帮助到你,看在博主这么用心的份上,hxd点个赞再走呗。

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值