栏目分类:
子分类:
返回
名师互学网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
名师互学网 > IT > 软件开发 > 后端开发 > C/C++/C#

C语言操作符详解

C/C++/C# 更新时间: 发布时间: IT归档 最新发布 模块sitemap 名妆网 法律咨询 聚返吧 英语巴士网 伯小乐 网商动力

C语言操作符详解

关于操作符之前简单介绍过一点,这篇详细介绍C语言中的操作符的使用和一些细节

目录

1.算数操作符

2.移位操作符

2.1移位操作符基础

2.2移位操作符移动

3.位操作符

4.赋值操作符

5.单目操作符

6.关系操作符

7.逻辑操作符

8.条件操作符

9.逗号表达式

10.结构成员访问操作符

11.操作符的属性

12.表达式的求值

12.1整型提升

12.2算数转换


1.算数操作符

包括四则运算(+、-、*、/)和取模操作符(%)

算数操作符中需要注意的有一下几点:

1.操作符%只能用于整数运算

2.操作符/要进行浮点数运算,那么除数和被除数至少有一个为浮点数

2.移位操作符

2.1移位操作符基础

位指的是二进制位,是数据在内存中存储的方式

移位有左移(<<)和右移(>>),移位操作符的操作数只能是整数

之前的文章介绍过整数在内存存储的二进制的表示形式,这里作一个简单概括:

整数有3种二进制表示形式,分别是原码、反码和补码,整数在内存中以补码的形式存储,在打印时以原码打印,二进制最高位为符号位,符号位为1表示负数

对于非负整数来说,三者是相同的

对于负整数来说,原码最高位不变,其它位按位取反得反码,反码+1得补码 

那么现在有个问题,我们将二进制位移动后,缺失的部分是如何填充的?

2.2移位操作符移动

先来看操作符<<

 可以看出,当i左移一位之后,低位补的是0,这便是左移操作符移位时的规则:左边抛弃,右边补0

接着是操作符>>

对于右移,其规则有两种

算数右移:右移后左边填充原符号位

逻辑右移:右移后左边填充0

大多数的编译器采用的是算数右移

还有一点要注意:使用移位操作符时不要移动负数位,C语言标准中没有定义这样的写法,到时出现什么情况自己负责

3.位操作符

有按位与(&)、按位或(|)以及按位异或(^),它们的操作数同样只能为整数

位依旧是二进制位

操作符&:a&b,a和b对应的二进制位都为1时结果才为1,否则为0

 图中3的二进制位:00000000000000000000000000000011

        1的二进制位:00000000000000000000000000000001

   3&1的二进制位:00000000000000000000000000000001

故i为1

操作符|:a|b,a和b对应的二进制位中只要有一个为1结果就为1

图中3的二进制位:00000000000000000000000000000011

        1的二进制位:00000000000000000000000000000001

   3&1的二进制位:00000000000000000000000000000011

i的结果为3

操作符^:a^b,a和b对应二进制位相同结果为0,不同结果为1

图中3的二进制位:00000000000000000000000000000011

        1的二进制位:00000000000000000000000000000001

   3&1的二进制位:00000000000000000000000000000010

i的结果为2

4.赋值操作符

赋值操作符的内容没有过多需要介绍的地方

a+=1和a=a+1是相同的,其它的符合操作符同理

5.单目操作符

单目操作符中的“&”和“*”在后续指针的时候介绍,这里就略过

逻辑反操作符

  • ~

对一个数的二进制位按位取反

  • sizeof

求操作数的长度,单位为字节

  • ++/--

有前置和后置,效果是给一个数+1/-1,前置是先计算后使用,后置是先使用后计算,详细的区别之前博客中有过介绍,这里不再赘述

  • ()

强制类型转换,括号内写入需要转换的数据类型

6.关系操作符

==、!=、>=、<=、>、<

一般用于判断,注意==和=别弄错

7.逻辑操作符

逻辑与(&&)和逻辑或(||)

二者就是数学上的逻辑与和逻辑或,这里主要说说它们运行时候的逻辑

a&&b,若a为假,那么后面的b便不会再判断它的真假,即a为假便停止判断。只有a为真的时候才会继续去判断b

a||b,a为真的时候,同样不会判断b

8.条件操作符

条件?表达式1:表达式2

条件为真执行表达式1,否则执行表达式2

某些情况下可以代替if语句,比如说打印a和b两个整数较大的值

a>b?printf("%d",a):printf("%d",b);

9.逗号表达式

就是用逗号隔开的多个表达式

int a=1;
int b=2;
int c=(++a,++b,5);
printf("%d",c);

先来看c的值

 可以看出,c的结果是最后一个表达式的结果,那前面的++a和++b有没有执行?

 很明显,++a和++b是被执行过的

所以,逗号表达式从左向右依次执行,整个表达式的结果是最后一个表达式的结果。

10.结构成员访问操作符

访问结构体时使用的操作符(“.”和“->”)

具体在后续结构体中详细介绍

C语言的操作符就介绍到这,感谢观看

11.操作符的属性

介绍了这么多的操作数,那么有一个问题

一个表达式中有多个操作数,那么操作数进行运算的顺序是怎样的?

这由操作数的属性决定

1. 操作符的优先级

2. 操作符的结合性 (即运算是从左往右还是从右至左)

3. 是否控制求值顺序(只有&&、||、逗号表达式和 ? :可以控制求值顺序)

两个相邻的操作符先执行哪个?

这取决于他们的优先级。如果两者的优先级相同,那么就看结合性。

操作符优先级最高的是()

但即使操作符有这些属性,很多时候表达式的值还是不唯一

a*b+c*d+e*f

上述表达式*的优先级比+高,所以先计算a*b和c*d,那第三步呢?是计算e*f还是计算a*b+c*d,此时优先级并不能决定,也就是说这个表达式的运算路径不是唯一的,那么不同编译器因为运算的路径不一样就会产生不同的结果,所以在写表达式时要保证计算路径的唯一,如果不能通过操作符的属性确定唯一的计算路径,那这个表达式就是存在问题的

12.表达式的求值

不同数据类型的操作数求值时可能需要转换为其他类型。

12.1整型提升

针对char和short的计算

char a=1;
char b=2;
char c=a+b;

在执行运算时a和b要提升为int才可以计算

因为表达式的整型运算要在CPU的相应运算器件内执行,CPU内整型运算器(ALU)的操作数的字节长度 一般就是int的字节长度,同时也是CPU的通用寄存器的长度。通用CPU是难以直接实现两个8比特字节直接相加运算,所以,表达式中各种长度可能小于int长度的整型值,都必须先转 换为int或unsigned int,然后才能送入CPU去执行运算。

a和b提升至int后算出来结果为3,此时3位int型,而c是char型,所以3要放入c中的话,需要进行截断,3的32位二进制位c只取低位的8位

12.2算数转换

整数和浮点数进行计算

int a=3;
float b=1.5;
float c=a+b;

如果想要正常进行运算,a要转换成float型之后才可以进行后续的计算

double

float

unsigned long 

long

unsigned int

int

上述排在下方的操作数,和其它操作数运算时首先进行转换

转载请注明:文章转载自 www.mshxw.com
本文地址:https://www.mshxw.com/it/510532.html
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 (c)2021-2022 MSHXW.COM

ICP备案号:晋ICP备2021003244-6号