操作符详解
一、操作符属性
操作符有以下三个属性会影响表达式求值:
1、操作符的优先级
2、操作符的结合性
3、操作符是否控制求值顺序
注:相邻的操作符才讨论优先级,按照优先级的高低进行先后运算,优先级相同再看结合性。
二、操作符分类细致剖析
整体上按优先级由高到低进行介绍,局部可能是依照类别来介绍。
1、括号、下标引用、函数调用及结构成员
( ) 括号 优先级最高
( ) 函数表达式 function(参数)
2、[ ] 下标引用操作符
操作数为:一个数组名 + 一个索引值
//用处:
int arr[10]; //创建数组
arr[9] = 10; //操作下标使用数组
3、访问一个结构体的成员
. 结构体变量访问成员
-> 结构体指针访问成员
//用法:
struct stu
{
int age;
};
int main()
{
struct stu a;
struct stu* pa = &a;
a.age = 20; //结构体变量的访问
pa->age = 20; //结构体指针的访问
return 0;
}
2、单目操作符
++ 前置、后置加加
- - 前置、后置减减
! 逻辑反操作
~ 按位取反
+ 单目,表示正值
- 单目,表示负值
* 单目,间接访问操作符(解引用操作符)
& 单目,取地址
sizeof 求操作数的长度(以字节为单位)
(类型) 强制类型转换
1、++,- -
前置++:先++,再使用
后置++:先使用,再++
- -同理
注意:++,- -会改变变量自身
2、!:真变假,假变真
(用数值表示:!0 = 1,!(非0) = 0)
3、~:二进制的所有位的补码取反(包括符号位)
4、&:取出一个变量在内存中的地址
5、sizeof :sizeof内部的表达式只计算,不会改变表达式中变量在外部的值
int a = 1;
int b = 2;
sizeof(b = a + 2);
printf("%d ", b); //结果是 2,而不是 3,sizeof内不会改变变量值
3、算术操作符
* / % + -
乘 除 取余 加 减
1、/ 除法运算符:两边的操作数都是整数,执行整数除法(结果的小数部分直接舍弃,只保留整数部分)
如果想带上小数部分,除号的两端至少有一个操作数是浮点数
2、% 取余(取模):计算的是整除之后的余数(取余操作符两边的操作数只能是整数)
4、移位操作符
<< 左移操作符
>> 右移操作符
注:移位操作符的操作数只能是整数。
移位操作符移的是二进制位,移的是补码。数据以补码的形式储存,但原码才表示数值哦,这一点要牢记。
移动规则:
左移:二进制位向左移动,左边超出部分舍弃,右边空出部分补0
(即:左边丢弃,右边补0)
右移:右移分为 算术右移和逻辑右移两种(大部分编译器为算术右移)
算术右移:右边丢弃,左边补原来的符号位。
逻辑右移:右边丢弃,左边补0。
警告⚠ :
对于移位运算符,不要移动负数位,这个是标准未定义的
a>>-2;
b<<-1; //错误,而且移的位数也不宜过大
5、关系操作符
> 大于
>= 大于或等于
< 小于
<= 小于或等于
== 用于测试“相等”
!= 用于测试“不相等”
注意不要混淆 = 和 == 哦!
6、位操作符
& 按位与
| 按位或
^ 按位异或
注:他们的操作数必须是整数。
用数值在内存中的补码进行运算。
1、& 按位与:对应二进制位上,有0则为0,全1才为1。
2、| 按位或:对应二进制位上,有1则为1,全0才为0。
3、^ 按位异或:对应二进制位上,相同为0,不同则为1。
异或操作符小规律:
1、a ^ a = 0; //异或本身为0
2、0 ^ a = a; //异或0为本身
3、a ^ b ^ c = a ^ c ^ b //异或支持交换律
7、逻辑操作符
&& 逻辑与 就是:并且
|| 逻辑或 就是:或者
逻辑表达式为真,值为1;逻辑表达式为假,值为0。
1、&& 两边全为真表达式才为真,有假则为假。
特点:从左向右判断表达式两边的条件是否成立,左边已为假,右边则不再进行计算。
#include <stdio.h>
int main()
{
int i = 0,a=0,b=2;
i = a++ && ++b;
printf("a = %d\n b = %d\n", a, b);
//输出为:1,2 因为a = 0先使用,为假,那么右边的++b就不再计算
//若左边为 ++a,则右边的++b计算
return 0;
}
2、|| 两边全为假表达式才为假,有真则为真。
特点:从左向右判断表达式两边的条件是否成立,左边已为真,右边则不再进行计算。
#include <stdio.h>
int main()
{
int i = 0,a=0,b=2;
i = ++a||++b;
printf("a = %d\n b = %d\n", a, b);
//输出为:1,2 因为先++,再使用a = 1,为真,那么右边的++b就不再计算
//若左边为 a++,则右边的++b计算
return 0;
}
8、条件操作符
exp1 ? exp2 : esp3
表达式1为真,表达式2计算,表达式3不计算,最终结果为表达式2的结果
表达式1为假,表达式2不计算,表达式3计算,最终结果为表达式3的结果
9、赋值操作符
= += -= *= /= %=
>>= <<= &= |= ^=
10、逗号表达式
, 逗号表达式:由一串逗号隔开的表达式
逗号表达式,从左向右依次执行。整个大表达式的结果是最后一个小表达式的结果。
int a = 1;
int b = 2;
int c = (a>b, a=b+10, a, b=a+1);
//c的值是13,b=a+1的结果,最后一个表达式前面的表达式也会计算