目录
一、算术操作符
二、移位操作符
三、位操作符
四、赋值操作符
五、单目操作符
六、关系运算符
七、逻辑操作符
八、条件操作符(三目操作符)
九、逗号表达式
十、结构成员
十一、表达式求值(重点内容)
1.理解类型转换
2.理解数值提升
【前言】
操作符模块内容比较多,也是大家很常用的东西,重点内容我会说明哦,一定要记住的地方或者易错的部分我会强调出来的,OK看好吧,嘿嘿。
一、算术操作符
+ - * / %
- 对于 / 操作符,如果两个操作数都是整数,执行整数除法,而只要两端有一个操作数是浮点数,那么执行的就是浮点数除法;
- % 操作符的两个操作数必须是整数,注意,浮点数不行哦
二、移位操作符
<< >>
- 移位操作符的操作数只能是整数;
- 对于移位操作符,不要移动负数位,这个是标准为定义的,如:
int a = 10;
int b = a >> -2;//error
补充知识点 :
- 字符串和字符数组是不一样的,字符串可以使用字符串库函数,字符数组要格外注意末尾是否有'\0', 这个是特别容易出错的;
- 二、八、十、十六进制只是数值的表示形式;
整数有三种二进制表示形式:原码、反码、补码
直接按照整数的正负写成二进制表示形式就是原码
注意,正整数,原码、反码、补码相同,负整数,原码、反码、补码不同,需要进行计算,计算的规则:原码符号位不变,其余位按位取反就是反码;反码加一得到补码
- 整数在内存中存的是其二进制的补码形式,进行运算的时候,也是按照内存中补码的二进制位进行的,但是要注意的是,打印的时候,用的是原码的值,所以要强调的是最后要将补码转化为原码再打印出来
三、位操作符
& | ^
对于位操作符,对象必须是整数,而且是对位进行的操作。内容还是比较多的,这块也很重要,所以,我写了一篇关于位操作符的博文
https://blog.csdn.net/weixin_57544072/article/details/120798996
补充一道变态的笔试题:
不能创建临时变量(第三个变量),实现两个数的交换:
方法一:加减法
a = a + b;
b = a - b;
a = a - b;
这样就解决了,但是有不好的地方,如果a, b 很大,就可能会导致溢出,所以还有一种方法,就是利用异或法
方法二:异或法
a = a ^ b;
b = a ^ b;
a = a ^ b;
这样就交换完成了,但是在实际运用当中,习惯定义第三个变量来实现两个数的交换,因为鸭,上面的代码可读性都不高!
四、赋值操作符
左值:是可以放在等号左边的,一般是一块空间;
右值:是可以放在等号右边的,一般是一个值或是一块空间的内容
int a = 10; // a就是左值,代表的是一块空间
a = 20;// 20就是右值,代表一个值
int b = 10;//b 就是左值,代表的是一块空间
b = a;// a 就是右值,代表的是一块空间的内容
五、单目操作符
- !:逻辑反操作(非);
- sizeof 操作符:以字节为单位(这个大家应该都比较熟悉了吧,在我的博文中已经出现过不下三次了);
- ~: 对一个数的二进制位取反(所有位全部取反);
- (类型):强制类型转换(从高类型转换成低类型可能会丢失数据,需要强制类型转换)
六、关系运算符
注意,下面容易错哦,在编程的过程中,== 和 = 特别容易写错,尤其是在if 语句只能中,容易漏掉一个=,这里需要格外注意一下。
七、逻辑操作符
【敲黑板】:对于逻辑操作符,有一条重要的特性就是:短路求值
&&:逻辑与(左操作数为假,右操作数不计算);
||:逻辑或(左操作数为真,右操作数不计算)
补充一道笔试题:360笔试题
#include<stdio.h>
int main()
{
int i = 0, a = 0, b = 2, c = 3, d = 4;
i = a++ && ++b && d++;//对于a++,后置++,先使用,后++,a为0,0为假,造成短路
printf("a = %d\nb = %d\nc = %d\nd = %d\n", a, b, c, d);输出1 2 3 4
return 0;
}
#include<stdio.h>
int main()
{
int i = 0, a = 0, b = 2, c = 3, d = 4;
i = a++ || ++b || d++;//++b值为3,表达式为真,造成短路
printf("a = %d\nb = %d\nc = %d\nd = %d\n", a, b, c, d); //输出1 3 3 4
return 0;
}
八、条件操作符(三目操作符)
exp1 ?exp2 :exp3
九、逗号表达式
exp1,exp2,exp3,... expN
逗号表达式就是用逗号隔开的表达式
逗号表达式,从左向右依次执行,整个表达式的结果是最后一个表达式的结果,这里需要注意哦,每个表达式都会执行计算,只不过选用最后一个表达式的结果作为整个表达式的结果
#include<stdio.h>
int main()
{
int a = 1;
int b = 2;
int c = (a > b, a = b + 10, a, b = a + 1);
printf("%d\n", c);//输出13
return 0;
}
十、结构成员
访问一个结构的成员:
. 结构体变量 . 结构体成员;
-> 结构体指针->成员名
【敲黑板】:对于表达式书写的时候,我们需要注意的是:如果不能通过操作符的属性确定唯一的计算路径,那么这个表达是就是存在问题的,注意,以后在公司里写出这样的代码,可就要被当成猪队友了哦,所以要格外注意!
十一、表达式求值(重点内容)
1.理解类型转换
char a = 100; //编译通过
char b = 256; //编译错误,提示:100和256都是整数,不是字符哦!从int 型转换到char 可能会有所损失,而第一个表达式编译通过是因为char 能表示的范围是-2^8~2^7-1(-128~127),而256已经超过了这个范围。
2.理解数值提升
由于计算机的CPU通常是以4个字节为单位从内存中读写数据,所以,为了硬件上实现方便,表达式中各种长度可能小于int 长度的整型值,都必须先转换成int 或 unsigned int ,然后才能送入CPU去执行运算。比如char、short这种类型数据都需要注意整形提升的问题。
如何理解整形提升呢?
整形提升是按照变量的数据类型的符号位来提升的(补其符号位!)
实例1:
#include<stdio.h>
int main()
{
char c = 1;
printf("%u\n", sizeof(c));//输出1
printf("%u\n", sizeof(+c));//输出4
printf("%u\n", sizeof(-c));//输出4
return 0;
}
为什么呢?
c 只要参与表达式运算了,就会发生整形提升。
实例2:
#include<stdio.h>
int main()
{
short s = 20;
int a = 5;
printf("%d\n", sizeof(s = a + 4));//输出2
printf("%d\n", s);//输出20
return 0;
}
sizeof(s = a + 4) ,由于a 是整形,s 是短整型,所以a + 4 放到s 里需要截断,整个表达式s = a + 4还是得s 说了算。
OK,今天的内容就这么多,重要的部分已经标注出来咯,咱么下次再见啦。