一、算术操作符:+、-、*、/、%
算术操作符其实在平时生活中,也遇到很多,并且这五类操作符基本很常见,而他们的作用与数学所学习的功能是一样的。但是“/”除号操作符与“%”取模操作符有些不同。下面就以这两个的操作符为主要说起。
1.1 “ / ” 除号
对于 “ / ” 除号操作符来说,如果操作符的两个操作数都是整数,那就执行整数除法,所得到的结果也是整数除法。而操作数只要有浮点数,那么就是浮点数除法。
int m = 7 / 3;
运行结果为:2
上面的代码中,因为7和3都是整形类型的,所以执行整数除法,所以得到的结果为2。
1.2 “ % ” 取模(求余数)
对于 “ % ” 取模操作符而言,它的操作数必须为整数,并且返回的是两个整数相除之后的余数。
int m = 7 % 3;
运行结果为:1
二、移位操作符:“<<”左移 “>>”右移
移位操作符移动的是二进制的位。
2.1 补充知识:原码、反码和补码
整数的二进制的表现形式有:原码、反码和补码。在计算机存储的过程中,都是以数的补码进行存储,并且在计算机中的操作以及打印也都利用补码进行,一个整数是4个字节(1字节=8比特位),就有32个比特位。
原码:按照数值的正负,直接写出的二进制序列就是原码。
反码:原码的符号位不变,其他位按位取反。
补码:反码的二进制加1。
而对于有符号的整数来说,最高一位的位是符号位。符号位为 “ 1 ” 表示负数,符号位为 “ 0 ” 表示正数。
对于无符号的整数来说,没有符号位,所以每一位都是有效的。
有符号的整数中正数与负数又有所差别:
- 正整数的原码、反码和补码的值相同;
- 负整数的原码、反码和补码的值不同。
所以在遇到负整数,就要通过运算来进行分析。
2.2 “ << ” 左移操作符
“ << ” 左移操作符,顾名思义,就是向左移动,将二进制的数向左移动。
“ << ” 左移操作符 使用方法:左边丢弃,右边补0
以下面这个例子来说:
int m = 7;
int n = m << 1;
运行结果为:14
7是正整数,所以它的原码、反码以及补码相同,它的二进制的写法是:
00000000 00000000 00000000 00000111
向左移动一位,给右边的补充0之后:
00000000 00000000 00000000 00001110
所以得到的这个结果就是14。
int m = 56;
int n = m << 1;
运行结果为:112
int m = -10;
int n = m << 1;
运行结果为:-10
所以不论正负,某一个数左移一位,会得到它的二倍。
2.3 “ >> ”右移操作符
“ << ”左移操作符作用效果是:左边丢弃,右边补0;那么“ >> ”右移操作符作用效果会不会就是:右边丢弃,左边补0呢?
我们刚刚说过,有符号整数在二进制的位上是有一些差异的,如果一个整数是有符号的f负数,那么最高位就是它的符号位,那么在经过右移之后,它的最高位就缺失了,那么我们还是补0吗?那么它还会不会是负数呢?
在“ >> ”右移操作符中,是有两种情况的。
“ >> ”逻辑右移
“ >> ” 逻辑右移操作符 使用方法:右边丢弃,左边补0
“ >> ”算术右移
“ >> ” 算术右移操作符 使用方法:右边丢弃,左边补符号位
在大多数编译器中都使用的是算术右移。
例如:
int m = -10;
int n = m >> 1;
运行结果为:-5
三、位操作符:&、|、^
位操作符与移位操作符也都是在2进制的位上进行运算的。并且位操作符的操作数必须都是整数。
3.1 “ & ” 按位与
“ & ” 按位与 使用口诀:两个同时为1,则为1
在按位与的作用下,我们只看两个数的相同为是否同时为1,如果是,那么就是1;如果不是,那么就是0。
例如:
int a = 3; int b = -5;
int c = a & b;
运行结果为:3
-5的原码:00000000 00000000 00000000 00000101
-5的反码:111111111 111111111 111111111 11111010
-5的补码:111111111 111111111 111111111 11111011
3的补码: 00000000 00000000 00000000 00000011
3 & -5 : 00000000 00000000 00000000 00000011
因为按位与之后的结果最高位是“0”,那么就是正数,正数的原码、反码和补码是相同的。所以将上面的二进制转化为十进制之后,结果就是-3。
“ & ” 逻辑与 小技巧:任何数&1===》得到它的最低位
这个小技巧真的很实用,希望大家能够记住。
3.2 “ | ” 按位或
“ | ” 按位或 使用口诀:有1则为1
在按位或的作用下,我们只看两个数中有一个数为1,那么就是1;如果两个数都是0,那么就是0。
例如:
int a = 3; int b = -5;
int c = a | b;
运行结果为: -5
-5的补码:111111111 111111111 111111111 11111011
3的补码: 00000000 00000000 00000000 00000011
3 | -5 : 11111111 11111111 11111111 11111011
按位或之后的结果最高位是“1”,所以是负数,负数的原码、反码和补码不同,所以需要转换为原码。这里附上一张原码、反码和补码的转化方式来便于大家理解。
补码:11111111 11111111 11111111 11111011
反码:11111111 11111111 11111111 11111010
原码:10000000 00000000 00000000 00000101
所以通过原码可得,最终的结果是-5。
3.3 “ ^ ” 按位异或
“ ^ ” 按位与 使用口诀:相同为0,相异为1
在按位与的作用下,我们看两个数相同的话,那么就是0;两个数不同的话,那么就是1。
例如:
int a = 3; int b = -5;
int c = a ^ b;
运行结果为:-8
-5的补码:111111111 111111111 111111111 11111011
3的补码: 00000000 00000000 00000000 00000011
3 ^ -5 : 11111111 11111111 11111111 11111000
因为所得的值是负数(符号位为“1”),所以是负数,负数的原码、反码和补码不同,所以需要转换为原码。
补码:11111111 11111111 11111111 11111000
反码:10000000 00000000 00000000 00000111
原码:10000000 00000000 00000000 00001000
所以通过原码可得,最终的结果是-8。
四、赋值操作符:=
赋值操作符很简单,就是在变量创建之后,重新赋值。
int a=1;//不是赋值,是初始化
a=20; //赋值
还有一些复合赋值符中,有一些简易的写法:
a=a>>1;
//可以写为
a>>=1;
五、单目操作符:! 、&、-、+、++--前置后置、sizeof、~、*、(类型)
5.1 “ ! ”逻辑反操作
其实逻辑反操作也是我们常常使用的。“天是蓝色”这句话是真的,但是如果在这句话的前边加上逻辑反操作之后,那么这句话就不是真的了“!天是蓝色”,天就不是蓝色的了。
int flag=0;
if(!flag)
{
printf("hehe");
}
运行结果为:hehe
因为在计算机中,0表示假,非0表示真,所以!flag就会是真的。
5.2 “ & ”取地址
“&”这里是取地址,大家不要和按位与“&”沦为一谈,按位与“&”是双目操作符,而取地址“&”是单目操作符。
例如:
int a = 10;
&a;//变量的地址
int arr[10];
&arr;//数组的地址
5.3 “ sizeof ” 操作数类型长度
sizeof要注意的几个点:
- sizeof 不是函数,而是操作符;
- sizeof计算的结果是size_t类型的,size_t是无符号整型,对于size_t类型的数据进行打印,可以使用%zd,而在一些老的编译器下,可以使用%u进行打印。
- sizeof是计算类型创建变量的大小或者变量的大小,单位是字节。
这里注意,“ sizeof ”不是函数,而是操作符。
int a = 10;
printf("%zd\n", sizeof(a));
printf("%zd\n", sizeof(int));
printf("%u\n", sizeof(int));
运行结果为:4 4 4
5.4 “ ~ ” 按位取反
按位取反就是对一个数的二进制按位取反。
“ ~ ” 按位取反 使用口诀:包括符号位,全部取反
例如:
int a = 2;
int b = ~a;
运行结果为:-3
5.5 “ * ” 间接访问操作符(解引用操作符)
“ * ” 间接访问操作符适用于指针,以下面的代码来说,*p是通过p存放的地址,来找到p指向的对象,*p其实也就是a。
int a = 10;
int * p = &a;
5.6 “ 类型 ” 强制类型转换
强制类型转化,顾名思义就是将一个类型转化为另一个类型,例如:
int a = (int)3.14;
printf("%d", a);
运行结果为:3
六、关系操作符:>、>=、<、<=、!=、==
关系操作符都很简单,唯一需要强调的一点就是,在编写代码的时候,切记将等于“==”写为赋值“=”,这两个是完全不同的。
七、逻辑操作符:&&、||
7.1 “ && ”逻辑与
“ && ”逻辑与 :左右都为真,才为真
左边操作数如果为假,右边无需计算
int a = 0;
int b = 5;
int c = a && b;//0-全真为1,否则为0
7.2 “ || ”逻辑或
“ || ”逻辑或:左右只要有一个真的,那就是真的
左边操作数如果为真,右边无需计算
int a = 0;
int b = 5;
int d = a || b;//1-有真为1,全假为0
八、条件操作符:“?:”
条件操作符也是唯一的三目操作符。
exp1?exp2:exp3
对语句1判断,为真则语句2,为假则语句3。
例如:
int a = 1;
int b = 5;
int m = 0;
m = (a > b ? a : b);//5
运行结果为:5
九、逗号表达式:“,”
逗号表达式,从左向右依次执行,整个表达式的结果是最后一个表达式的结果。
int a=1;
int b=2;
int c=(a>b,a=b+10,a,b=a+1);
运行结果为:13
这种情况下,每一条语句都是执行的,但是最终结果是最后一个语句。
十、下标引用、函数调用和结构体成员操作符
10.1 “ [] ”下标引用操作符
“ [] ”下标引用操作符,适用于数组中,访问数组元素个数。数组下标是从0开始。
int arr={1,2,3,4,5,6,7,8,9,10};
printf("%d\n",arr[5]);
运行结果为:6
10.2 “()”函数调用操作符
“()”函数调用操作符,在调用函数的时候,是不能缺少的。
printf("hello\n");//调用库函数
10.3 “ . ” “->”成员访问操作符
“ . ” “->”成员访问操作符,多用于结构体访问中。
成员访问操作符 使用方法:
结构体 . 成员名
结构体指针 -> 成员名
struct Book
{
char name[20];
int price;
};
int main()
{
struct Book b = { "《加油》",66 };
printf("%s %d\n", b.name, b.price);
return 0;
}
运行结果: 《加油》 66
以上就是我们需要掌握的操作符了,大家可以收藏,多多翻看哦~祝大家都拿到心仪的offer~