前言:
紧接上一篇,仍旧是来讲解操作符的使用。
链接:操作符讲解1---C语言
1.赋值操作符
赋值操作符是用来为变量进行赋值操作的(内存空间里放值),分为简单赋值操作符和复合赋值操作符。
简单赋值操作符:=
int main() { int a = 10; a = 20;//这里的等号就是赋值操作符 return 0; }
赋值可以让我们改变变量里我们原先不想要的值,把我们理想的值放到变量里面去。
复合赋值操作符:+=、-=、*=、/=、%=、>>=、<<=、&=、|=、^=。
正是因为有上面这些赋值操作符,才将=与上面这些赋值符划分为简单和复合类型。那么我们来认识和使用复合赋值操作符。
我们看a那一行代码,a本身加上10再赋值给a本身。屏幕上a和b的打印出来的值都是20,这说明+=这个复合赋值符是将一个数与b相加,再赋值给b。是的,所有的复合赋值操作符都是一个能进行运算的操作符配合简单赋值操作符,结合起来的先运算再赋值的形式。
2.单目操作符
单目操作符有:!、+、-、sizeof、~、&、*、--、++、(强制类型转换)
单目操作符的概念是,这个操作符的操作数只有一个(只对一个数据进行操作)。
!的操作数只有一个,它也是逻辑操作符,在上一篇我们讲过了,加上无非就是从真变假,从假变真的效果。
+(正号),这里不是加号的意思,而是正号。加号是双目操作符,一个正数前面写上+是没问题的,不过简直是多一举罢了,我们一般都不会用到这个操作符来表示正数。
-(符号),这个操作符能将正数变成负数,负数变成正数。比如int a = 1; a = -a; a的值被赋成了-1。
2.1取地址操作符
&(取地址操作符),由于我们在创建变量的时候,会向操作系统申请空间,也就是借用内存单元给我们使用,这些内存单元都有编号,为了取得这些编号,C语言用&取地址操作符取出变量所在的内存单元编号。
&取地变量址的时候,我们以上面的例子为例吧。在这个代码样例中,一个整型所占空间的大小是4个字节,由于每个内存单元的大小是1个字节,所以一个整型占了4个内存单元,而且每一个内存单元都有它自己的地址,那我们取这个整型的地址的时候,取得是哪个内存单元的地址呢?
答案是:这个变量起始位置的内存单元地址。这是因为,当我们标明了这个变量的数据类型时,我们只需要记住这个变量从哪里开始,编译器会自动根据数据的类型,往后访问相应大小的内存单元空间。
2.2sizeof操作符
大家可能在没完全了解sizeof的时候,就在用sizeof了。和大家对sizeof的认识一样,它是用来求变量或数据类型所占用内存单元的多少的,单位是字节,比如int占用4个字节,那用sizeof来求int创建的变量的时候,结果是4。
也许你会觉得,sizeof()这样子很像是一个函数调用,实际上不是的,我们看下面的代码:
这里我改了一下,把变量名括起来的括号给去掉了,然后结果还是正确的,如果sizeof是函数的话,调用函数的时候()(函数调用操作符),是不能省略的。 可能细心的小伙伴会发现,博主博主,你为什么括起类型的括号不去掉呢?哈哈,其实是不行的,去掉的话,编译器会报错。
因为int这些数据类型本身就是C语言中的关键字,如果不用()将其束缚起来,让它明显地作为sizeof操作符的操作数,编译器的理解将会是:这里凭空出现了一个int关键字,又没有声明变量等等原因,我只处理唯一性的指令。总之就是这个有歧义,编译器无法帮我们处理就对了。
总结:所以sizeof本质上是一个操作符,用来求数据类型或变量所占空间的大小,单位是字节,求类型时,括号不能省略。
~波浪号的作用是,二进制位取反。它不像整型从原码变到反码时,符号位不变其它位按位取反;也不是!感叹号对结果取反;而是对二进制位全部位取反。比如:
补充:表达式求值的时候,其实不会对变量本身造成影响。可以这样理解,我们在用到变量名,实际上是把变量名控制的这块内存空间里的数值拷贝一份供别人去使用,不管别人怎么使用,不会影响到我变量本身。我们称这种情况为:没有副作用。但我们下面讲的操作符就有副作用了,它们会改变变量内存空间里的值。
2.3++和--
++和--操作符,这两个操作符讲一个,另一个就明白了。
++在变量的后面,是后置++,看到控制台上的结果是,b的值为5,a的值为6。这说明,a++赋值给b的时候,用的是5赋值给b,随后a自己加了个1,打印a的时候打印出来6。
后置++或--的特点是,使用变量原来的值进行表达式运算,然后变量自己再加1或减1,叫做先使用后调整。先使用值,后面再调整自身。
前置++或--:
前置的++是先调整自身变成6,再使用赋值给b为6,叫做先调整后使用。
前置--和后置--也是一样的道理,这里就不再赘述了。
练习:
*(间接访问操作符)解引用操作符,这个符号用于对指针进行解应用操作,这里简单提及一下*的用法。
这里我们首先创建一个a变量,输入一个520,然后将a变量的地址取出来放到整型指针变量pa里,*pa进行的操作是:找到pa里存放的值它相对应的内存单元的编号空间。也就是pa里的值是a变量的地址,*pa通过地址找到a变量,*pa等价于a。具有意义的5.20近在咫尺,博主没有女朋友,可以多更新几篇,用博文为身为情侣的你们送上祝福~ 哈哈。
(数据类型)是一个强制转换的操作符,它可以把原先属于整型的数据转换成浮点型,是C语言比较霸道的解决类型不兼容(不同数据之间进行运算会有不兼容的警告)的方法,因为是霸道的操作符,所以还是有一点破坏的,比如数据可能会丢失之类的,所以数据类型能写对就写对,到一些需要用的场所就用。
整型没有小数,所以强制转换成整数打印,会把小数部分去掉。
3.关系操作符
关系操作符有:>,<,>=,<=,==,!=
关系操作符主要用在测试条件(选择,循环的判断部分),如果表达式是对的,那结果为真,反之为否。注意的一点是,计算机中大于等于和小于等于的写法不像数学那样。
==用来判断相等,千万不要在写判断条件的时候把两个等号写成了一个,那样是赋值而不是判断相等。!=用来判断不相等。
#include <stdio.h> int main() { int a = 0; if(a = 0) { printf("haha\n"); } return 0; }
这道编程会不会打印haha?答案是不会的,因为这里不是判断,a是否等于0,而是将0赋值给了a,这个赋值表达式的结果是0,在测试条件部分,0为假,所以不会打印。
#include <stdio.h> int main() { int a = 0; if(0 = a) { printf("haha\n"); } return 0; }
这种写法呢?如果我们运行起来,编译器会报错,因为我们把a赋值给了0,0是常量。第一种写法往往会让我们得到意向不到的结果,而且我们不知道错在哪里,需要去调试。第二种写法可以防止我们因为少写了一个等号而需要去通过调试找到这个bug,编译器会报错错误在第几行的。
补充:赋值操作符是从右像左进行的,表达式的值是左边操作符数里的值。比如 a = 10;把10赋给a,结果为a,是10。