重点:
各种操作符的介绍
表达式求值
操作符分类:
算术操作符 位操作符 单目操作符 逻辑操作符 逗号表达式
移位操作符 赋值操作符 关系操作符 条件操作符 下标引用、函数调用和结构成员。
## 算术操作符
+ - * / %
1.除了%操作符之外,其他的几个操作符可以用于整数和浮点数
2.对于/操作符如果两个操作数都为整数 ,执行整数除法。而只要有浮点数执行的就是浮点数除法
3.%操作符的两个操作数必须为整数。返回的是整除之后的余数。
## 移位操作符
<<左移操作符
>>右移操作符
### 左移操作符移位规则:
左边抛弃、右边补零
### 右移操作符
1.算术右移
右边丢弃,左边补原符号位。
2.逻辑右移
右边丢弃,左边补零。
注意:对于移位运算符,不要移动负数位,这个是标准未定义的。
int num=10;
num>>-1;
## 位操作符
位操作符有:
&//按位与
|//按位或
^//按位异或
注:他们的操作数必须是整数。
## 赋值操作符
赋值操作符是一个很棒的操作符,它可以让你得到之前你不满意的一个值,也就是你可以重新给它进行赋值。
int weight=120;
赋值操作符可以连续使用,比如:
int a=10;
int x=0;
int y=20;
a=x=y+1;
## 复合赋值符
+= -= *= /= %= >>= <<= %= |= ^=
a+=1;
等于a=a+1;
## 单目操作符 //只有一个操作数
! 逻辑反操作 + 正值 sizeof 操作数类型长度(以字节为单位)
- 负值 & 取地址 ~ 对一个数的二进制位按位取反
-- 前置、后置--; ++ 前置后置++; * 间接访问操作符(解引用操作符)
(类型) 强制类型转换。
a++:先使用,后加加;
++a:先加加,再使用;
## 条件操作符(三目操作符)
exp1? exp2 : exp3
if(a>3){
b=-1;
}
else{ 转换为:b=(a>3?-1;1);
b=1;
}
## 逗号表达式
exp1,exp2,exp3,...expn
逗号表达式,就是用逗号隔开的多个表达式。逗号表达式,从左向右依次执行。整个表达式的结果是最后一个表达式的结果。
c的结果是13.
## 下标引用、函数调用和结构成员
1.[] 下标引用操作符
操作数:一个数组名+一个索引值
int arr[10];//创建数组
arr[9]=10;//实用下标引用操作符
[]的两个操作数是arr和9。
2.()函数调用操作符接受一个或者多个操作数:第一个操作数是函数名,剩余的操作数就是传递函数的参数。
## 访问一个结构的成员
. 结构体.成员名
-> 结构体指针->成员名
## 表达式求值
表达式求值的顺序一部分是由操作符的优先级和结合性决定
同样,有些表达式的操作数在求值的过程中可能需要转换为了其他类型。
## 隐式类型转换
C的整型算术运算总是至少以缺省整形类型的精度来进行的。
为了获得这个精度,表达式中的字符和短整形操作数在使用之前被转换为普通整形,这种转换称为整形提升。
char a=3;
char b=127;
char c;
c=a+b;
c=-126;
整型提升是按照变量的数据类型的符号位来提升的
## 算术转换
如果某个操作符的各个操作数属于不同的类型,那么除非其中一个操作数的转换为另一个操作数的类型,否则操作就无法进行。下面的层次体系称为寻常算术转换。
long double, double, float, unsigned long int, long int unsigned int , int
如果某个操作数的类型在上面这个列表中排名较低,那么首先要转换为另外一个操作数的类型后执行运算。
警告:但是算术转换要合理,要不然会有一些潜在的问题;
## 操作符的属性
复杂表达式的求值有三个影响的因素
1.操作符的优先级
2.操作符的结合性
3.是否控制求值顺序
两个相邻的操作符先执行那个?取决于他们的优先级。如果两者的优先级相同,取决于他们的结合性