目录
算术操作符:+ - * / %
移位操作符:>> <<
位操作符:& | ^
赋值操作符:= += -= /= %= >>= <<= |= &=
单目操作符:! - + & sizeof ~ -- ++ * . (类型)
关系操作符:> >= < <= != ==
逻辑操作符:&& ||
条件操作符:exp1?exp2:exp3
逗号表达式:exp1,exp2,exp3……expn
下标引用,函数调用,结构成员操作符:[ ] () . ->
首先,说起操作符,有算术操作符、赋值操作符、关系操作符、单目操作符等等一系列的操作符,接下来给大家简单的了解一下各种操作符,并给出自己的理解和需要注意的地方,那么接下来,开始进入学习环节啦!
算术操作符:+ - * / %
算数操作符就是以上五种,其中大部分大家都见过,但是乘(*)和除(/)尤其要注意,可不是我们数学中的✖和➗哦,注意这点就行。然后就是取余(%)了,这个符号意思是取结果的余数,比如7/3=2余1,那么7%3就等于1了,大家明白了没有呀,这就是算术操作符的内容。
移位操作符:>> <<
移位操作符包括>>和<<两种,其中>>是右移操作符,<<是左移操作符,注意这里的左移和右移都是指二进制位的移动,因为计算机中所有信息都是以二进制形式存放的。
说起二进制,就是指有32个0或1组成的一串数,例如a=3:00000000……00000011,运算过程是:1*2^1+1*2^0=3(^号指几次方)
a<<1,就变成了:00000000……00000110,结果就为:1*2^2+1*2^1=6
a>>1,就变成了:00000000……00000001,结果就为:1*2^0=1
这便是移位操作符。
位操作符:& | ^
其中&是按位与,|是按位或,^是按位异或,这三个也是二进制的操作符哦,接下来解释一下具体用法
&:如果 x 和 y 都为 1,则得到 1;如果 x 或 y 任何一个为 0,或都为0,则得到 0,简记为:同为1则为1
|:如果 x 或 y 为 1,或都为 1,则得到 1;如果 x 和 y 都为 0,则得到 0,简记为:有1则为1
^:如果 x 或 y 的值不同,则得到 1;如果两个值相同,则得到 0,简记为:相同为0,相异位1
下面举个例子,大家就可以明显看到区别啦
int a=6 0···00110 int b=11 0···01011 a&b 0···00010 a|b 0···01111 a^b 0···01101
赋值操作符:= += -= /= %= >>= <<= |= &=
大家可以看出来,赋值操作符有很多很多,上面所举的只是部分,大家可以注意到,=我们都知道,但+=,-=等符号是以前我们从未见到的,其实很简单
a+=2的意思就是a=a+2
b-=3的意思就是b=b-3
以此类推……
尤其注意,这里的=是赋值符,与下面的关系操作符中的==会搞混,下面关系操作符中会详细说明的。
单目操作符:! - + & sizeof ~ -- ++ * . (类型)
说起单目操作符,顾名思义,就是只有一个操作数的操作符,与之相对应的是双目操作符,即有两个操作数的,例如a++,++就是单目操作符;a+b,+就是双目操作符,接下来便详细说明各个操作符的作用,认真学哦。
这里先说一个概念,在C语言中0表示假,非0表示真
!是逻辑反操作,举个例子,int a = 0(0表示假),那么!0就表示真,在一个值前面加上!,就会真变假,假变真。
-,+:注意注意,这里的-,+表示的是负值,正值,并不是加减的意思,如+2,-3等等
&,* .:取地址操作符,间接访问操作符(解应用操作符)这个符号在后面指针部分会详细讲到,大家敬请期待呀!!
sizeof:是一个计算操作数的类型长度的操作符(单位是字节byte),例如:
打印出来结果如下
至于int类型长度为什么是4,请大家关注我前面发的初识C语言之数据类型部分。
~:对一个数的二进制按位取反,将原来的0变为1,1变为0,例如1的二进制:0……00000001,那么~以后,变为:1……11111110,就ok啦
--,++:++和--可以大致理解位+1,-1,并且这里的++和--分为前置和后置两种,前置的是先使用,后++或--,后置的是先++或--,后使用,具体是什么意思呢,看下面解释。
大家注意看,上面首先给出a的值是1,然后打印a++是前置++,那么根据我们的口诀,前置++先使用,后++,因为先使用所以先打印的就是a的值1,接着++,下一个打印的就是++以后的值2。
接着我们看一下++a的情形,是如何先++,后使用的
大家通过观察可以看到,第一次打印,先++,a+1变为2,再打印,所以打印出来就是2,第二次打印的自然就是++以后的值2啦。
--与++的情形类似,大家可以想想,并上机实践实践,这里再强调一下,一定要多上机实践啊xdm,上机才能使自己掌握知识掌握的更好喔!!
(类型):强制类型转换,比如下图的例子
大家观察上图,a开始是float类型的,然后定义一个int类型的b,将a强制类型转换为int,1.25就会变为整型1,所以打印出来的b是1。
以上便是单目操作符的全部内容啦。
关系操作符:> >= < <= != ==
这里的>,<,>=,<=大家都了解,我就不过多解释了,后面的!=就是不等于,==就是等于
这里讲一讲=和==的区别,大家通过分类可以清楚看出=是赋值操作符,而==是关系操作符,那么我们在代码中如果想表示谁和谁是否相等时,应该用的是关系操作符==,如果想表示的是把一个数赋值给另一个数,就自然用的是=啦,大家是否能辨别清楚呢
逻辑操作符:&& ||
&&:逻辑与
1、当&&左边为假,则不再进行右边的判断,结果为假;
2、当&&左边为真,判断右边,右边为假,结果为假;右边为真,结果为真;如上图所示,是有关逻辑与的,大家可以先观察结果,想一想为什么,然后再看下面的解释,看看是不是一样的想法。
首先第一个,a = ++a && b++中,&&左边的++a为真,所以左右两边的表达式都要执行,++a后a为2,b++后b为3,左右两边都为真,所以a的值最终为1,所以打印的第一个结果为1 3;
接着看第二个,c = --a && ++b中,&&左边的--a为0,左边为假,所以就不用执行右边的了,所以a变为0,b不变仍为3,由于&&左边为假,所以结果为假,所以c就为0,因此打印的结果为0 3 0。
这里重点提醒一下,&&操作符若是左边为假,则右边无需执行,这是易错点哦,牢牢记住这一点!!
||:逻辑或
1、当||左边为真,则不再进行右边的判断,结果为真
2、当||左边为假,判断右边,右边为假,结果为假;右边为真,结果为真上图是有关逻辑或的运算,大家照常先算算看和答案相同吗,再看下面的解释。
首先看a = ++a || b++,||左边为++a等于2,为真,则不进行右边的判断b++了,结果为真,即a最终为1,而b不变,仍为2,所以打印出来为1 2.
接着看c = --a || ++b,||左边为--a等于0,为假,所以左右都做判断,左边为0,右边++b为3,所以结果为真,即c为真,故c等于1,所以打印结果为0 3 1。
逻辑或||操作符,需要注意的便是若左边为真,则不用进行右边的判断,这个也是很容易忽视的点哦,一定注意注意再注意!
这便是逻辑与和逻辑或操作符具体讲解,想必大家已经很好的理解了吧(◦˙▽˙◦)
条件操作符:exp1?exp2:exp3
exp1?exp2:exp3的意思是,若exp1成立,则计算exp2,整个表达式结果是exp2的结果
若exp1不成立,则计算exp3,整个表达式结果是exp3的结果
举个简单的例子:
int a = 5; int b = 2; int c = a>b?a:b;
上面的意思就是,a>b成立,所以c的值就取a,所以c就等于5。
当然啦,大家有没有观察到,条件操作符有三个操作数,所以属于三目操作符哦
逗号表达式:exp1,exp2,exp3……expn
逗号表达式的意思就是几个表达式中间用逗号连接,整个表达式的结果取最后一个表达式的结果,但是前面的表达式必须都算一遍,因为前面的表达式,有可能影响后面的表达式的结果哦
举个例子,上截图
图中d后面是条件表达式,先算a+=5,算出a=15,再算b+=a,算出b=35,最后算c=a+b,算出c=15+35=50,故最后d的结果就是50.
观察上式,最后一个表达式的结果取决去前面的表达式运行后的结果,所以即使整个表达式的结果取最后一个表达式的结果,也必须按顺序算一遍的。
下标引用,函数调用,结构成员操作符:[ ] () . ->
下标引用操作符:[ ]常用于数组,例如:
int arr[5]={ 0 }; arr[4] = 5;
它的操作数的数组名和下标哦!
函数调用操作符:()
int my_min(int x,int y) { return x>y?y:x; } int main() { int min =my_min(5,8); printf("%d",min); return 0; }
图中的my_min后面的()就是典型的函数调用操作符了
在例子中它的操作数有三个:函数名,5,8
结构成员操作符:. ->
结构成员操作符会在我们后面要学习的结构体中大量出现,所以会在结构体学习中再做重点解释,敬请期待٩(๑•̀ω•́๑)۶
整型提升
C语言的整型算术运算总是以缺省整型类型的精度来进行的。(即类型是小于int的一类数)
而为了获得这个精度,表达式中的字符和短整型操作数在使用之前被转换为普通整型,这种转换称为整型提升。
整型提升中,会补字符和短整型得符号位补满32个bit位,有符号数而言,补最高位的符号位,(0表示正,1表示负);对无符号数而言,补0即可
下面来举几个例子具体说明整型提升:
eg1:
大家看一下这个例子,计算一下答案是多少。
也许会有同学看到这个题以后,脱口而出132呀,这有什么算的呢?
那么恭喜你,成功跳入了整型提升的坑!那么答案到底是怎么算的呢,具体应该是这样计算的:
首先观察,a和b都是char类型的,小于int类型,所以在进行算数操作的时候需要整型提升的!
首先看a:5,在内存中的5的二进制序列为:
5为正数原反补码相同,都为:00000000 00000000 00000000 00000101
但是是char类型的数,所以只有一个字节即8个bit位,只能留下00000101。
接着看b:127,在内存中的二进制序列为:
127也为正数原反补码相同,都为:00000000 00000000 00000000 01111111
b也是char类型的数,所以与a一样,只能保留8个bit位,即01111111
然后看char c = a + b;上面提到了,表达式中的字符和短整型操作数在使用之前被转换为普通整型,所以a和b会进行整型提升,变为普通的整型类型,需要补齐32个bit位,那么怎么补呢,上面也提到了,因为a和b都是有符号数,所以补符号位,观察可以符号位都是0,所以加0补全32位,如下:
a:00000000 00000000 00000000 00000101
b:00000000 00000000 00000000 01111111
进行c=a+b的操作,加完后为:00000000 00000000 00000000 10000100
因为c也是char类型,所以保留8个bit位后为:10000100
之后进行打印%d类型(有符号整型),所以也需要整型提升,c为有符号数,提升符号位1,即:
11111111 11111111 11111111 10000100
因为内存中存的是补码,且,c的补码符号位为1,可知c为负数,所以原码等于补码-1再取反,
算出c的原码是:10000000 00000000 00000000 01111100
计算出c为-124,那么究竟对不对呢,看下方运算结果可知:
这便是第一个整型提升的例子,大家掌握了吗?
下面再举个例子证明一下,C语言中是存在整型提升的,如下所示:
前面学习过char类型是占1个字节,short类型占2个字节,int类型占4个字节,那么观察上方案例,a是char类型,b是short类型,那么理所当然a占1个字节,b占2个字节,但为什么+a和-b就变为了4个字节呢,其实这里也是发生了整型提升,因为有算术操作符+-,整型提升为了int类型,所以理所当然就占4个字节了!
大家明白整型提升的知识了吧!
算数转换
上面说到了整型提升,是小于int类型的操作数进行的,那么接下来说到的算数转换则是大于int类型的操作数。
算数转换就是如果某个操作符的各个操作数属于不同的类型,那么除非其中一个操作数的转换为另一个数类型,否则操作就无法进行。
下面是寻常的算数类型转换:
long double
double
float
unsigned long int
long int
unsigned int
int
只需要记住,运算过程中遇到不同类型的操作数时,类型是从下往上转换即可。
算数转换和整型提升的方法也差不多,大家参照整型提升那块知识的理解一下就ok啦\(^o^)/~
终于结束啦,以上便是此次初识C语言之操作符的全部内容,谢谢大家观看,下个博客再见
ヾ( ̄▽ ̄)Bye~Bye~
(◦˙▽˙◦) (◦˙▽˙◦)