欸为巴帝,我我我我我又来了
今天咱不搞虚的,带来一期满满干货 —— C语言操作符详解
从我开始学习编程到现在,操作符一直是个让我头疼的东西,但是,铁子不要害怕,看完我这篇博客就不头疼了!
C语言中的操作符属于C语言的基础部分,俗话说,要想楼房建得高,地基可得打牢。所以咱就反手一个深度剖析操作符~
废话不多讲,正文开始 ——
1.操作符的分类
算数操作符
移位操作符
位操作符
赋值操作符
单目操作符
关系操作符
条件操作符
逻辑操作符
逗号表达式
下标引用、函数调用和结构成员
以上就是10类操作符,接下来我们依次展开讲讲
2. 算数操作符
+ - * / %
2.1 + - 就跟我们平常认识的 + -一个意思
2.2 * / 其实变化也不大,只是和数学中的 ✖ 和 ➗ 长得不太一样
但是有一点需要注意,在编程时 整数/整数 只能得到整数,是不能得到小数的,要想得到小数,需要对数字进行算术转换或者整型提升
2.3 % 就相对特殊一点,是取模,取余数的意思,例如5%3==2,因为 5/3=1…2
因为 % 的使用方法,就限制了它只能用在整数与整数之间,浮点数就不行了
还需要注意:正 % 正 ---> 正,如果操作数中至少有一个负数,那么运算结果就取决于编译器了,所以尽量避免出现负数的%
3.移位操作符
>> <<
在讲上面两个符号之前,我们先插入一点辅助知识
开始学习编程的时候我们都知道,计算机是只能执行只包含0、1的代码的,我们所编写的程序是要通过编译器进行处理,转换成只包含0、1的计算机语言,计算机才能执行的
所以呢,我们先来了解一下整数在内存中的存储方式
首先提出原码、反码、补码的3个概念
二进制码的最高位为符号位:
0 -----> 正数
1 -----> 负数
原码:十进制数直接转换成二进制数,在不同位的计算机中存放不同位数
反码:在原码的基础上,符号位不变,剩下的位1变0,0变1
补码:在反码的基础上+1
移位操作符操作的都是二进制序列
整数在内存中存放的是二进制的补码
正整数的原码、反码、补码相同,负整数的原码、反码、补码按上述规则变化
想要了解更多计算机内存中数据的储存,请移步C语言数据的类型以及在内存中的储存_Joker2373的博客-CSDN博客
3.1 << 左移操作符
把一个数的二进制序列向左移动n位,左边的位丢掉,右边补0,有乘以2^n的效果
符号位该丢就丢,不要舍不得
3.2 >> 右移操作符
右移操作符分为两种:算术右移和逻辑右移 (具体为哪种类型由编译器说了算)
算数右移:把一个数的二进制序列向右移动n位,右边的位丢掉,左边补原符号位(有除以2的效果,但不总是有)
逻辑右移:把一个数的二进制序列向右移动n位,不论原符号位是1还是0,右边的位丢掉,左边补0
有一点需注意:无论是左移还是右移,都不允许移动负数位,因为标准未定义
4.位操作符
& | ^
操作的同样是二进制序列, 位操作符是两目操作符,目就是指操作数
4.1 & 按位与
0 & 0 = 0; 0 & 1 = 0; 1 & 0 = 0; 1 & 1 = 1
我们要与 &a 这样的写法区分开来,虽然字符是同一个,但是意义大不相同,一个是对二进制数按位与,一个是取一个数在内存中的地址,而且,取地址符是单目操作符
4.2 | 按位或
0 | 0 = 0; 0 | 1 = 1; 1 | 0 = 1; 1 & 1 = 1
4.3 ^ 按位异或
0 ^ 0 = 0; 0 ^ 1 = 1; 1 ^ 0 = 1; 1 ^ 1 = 0;
按位异或只能作用于整数, a ^ a = 0; a ^ 0 = a;
了解以上三个操作符之后,我们可以利用操作符来解决很多问题,
例如:不创建临时变量交换两个数字的值
求一个数在内存中中二进制序列中1的个数
……(这些可以在各种刷题网站上找到,大家有兴趣可以自己去试试看)
5.单目操作符
! + - & * sizeof() ~ ++ -- (类型)
5.1 !逻辑反
可以实现 真-->假,假-->真 (对于整数来说,0表示假,非0表示真)
在C99标准引入之前,没有专门表示真假的变量,在C99之后,引入了bool型变量,包含头文件为
<stdbool.h>,定义类型符为 _BOOL, bool. 布尔变量的引入使得表示真假更加纯粹
5.2 + -
就很简单的操作符,正数前面为+,一般都会省略,负数前面为-
5.3 & 取地址操作符 *解引用操作符(间接操作符)
p = &a, 将变量a的地址取出来存放在p中,只要是对象,在内存中就会占用内存,只要占用内存,就一定有确定的地址
*p刚好与&相反,是通过p中存放的地址来找到该地址上放的数据
*(&a) ==> a
5.4 sizeof() 操作数的类型长度
int a = 0; sizeof(a); //4 sizeof(int); //4 sizeof a; //4 sizeof int; //err
sizeof()看起来像一个函数,但实际上是一个操作符,因为sizeof()括号内的如果是变量,()是可以省略的,但是()中是类型名,()就不能省略了
sizeof()括号中的表达式不参与运算,因为sizeof()在编译期间就被处理了,而表达式要在源程序生成.exe文件时才运行处理
5.5 ~ 按位取反(包括符号位)
在处理多组输入时我们常用
while(~scanf("%d", &a))
也因为在输入遇到错误时或者遇到end of file时会返回EOF,EOF定义为-1,在对-1按位取反就会得到0,循环也就不再进行
5.6 ++ 自增 --自减
均分为前置和后置,前置是先++/--,后使用,后置刚好相反
5.7 (类型) 强制类型转换
6.赋值操作符
6.1 = 普通赋值操作符,对于变量中的值不满意就改成自己满意的
6.2 复合操作符
+= -= *= /= %= >>= <<= &= |= ^=
就是一些简写,使得代码看起来更简洁,是否使用主要看个人喜好
7.关系操作符
> >= < <= != ==
不是所有东西都能用关系操作符来比较,
例如字符串的比较需要用strcmp()来进行比较,如果是直接两个字符串用关系操作符来比较,那么比较的是这两个字符串在内存空间中的地址的大小
8.逻辑操作符
&& ||
8.1 && 逻辑与
如果第一个表达式的语句为0,那么后面的语句都不再执行
8.2 || 逻辑或
如果第一个表达式的语句为1,那么后面的语句都不再执行
9.条件操作符
exp1 ? exp2 : exp3
先执行exp1,如果exp1为真,那么整个表达式的值为exp2的返回值,否则为exp3的返回值
这是C语言中唯一一个三目操作符
10. 逗号表达式
exp1, exp2, exp3,……,expN
依次执行,结果为最后一个表达式的值
11.下标引用、函数调用和结构成员
[] () -> .
11.1 [] 下标引用
双目操作符,操作数为数组名和下标,arr[4] = *(arr+4) = *(4+arr) = 4[arr] , 以为加法具有交换律,然后类比,就可以得到上述结果,但是实际编程时,不建议使用最后一种下标引用方式
因为[]是操作符,操作的是操作数,是对操作数进行运算,但是对于下面的函数调用,就不能交换操作数的位置了,因为函数调用实际上是进行传递,而不是运算,是一一对应的,改变顺序会使代码乱套
11.2 () 函数调用操作符
操作数至少为1个,因为就算函数不需要参数,函数名还是必须存在的,也就是说,函数名也是操作数
11.3 -> . 结构体成员访问操作符
使用:结构体变量指针 -> 成员名
结构体变量 . 成员名
结构的详细剖析会在接下来的文章讲解,敬请期待
关于C语言操作符的详细介绍就讲完啦,欢迎各位uu的建议和指正
上一个:卖猫的市场(卖猫的市场视频)