C语言操作符:算术操作符 移位操作符 位操作符 赋值操作符 单目操作符 关系操作符 逻辑操作符 条件操作符 逗号表达式 下标引用 、 函数调用和结构成员
算数操作符:+ - * / %
1.除%外,4个操作符都可以进行整数和浮点数运算。
2.%的俩个操作数必须为整数。
3./的俩个操作数都是整数就执行整数除法,只要有浮点数执行浮点数除法。
移位操作符:
<< 左移:左边丢弃,右边补0()。注:num<<1,num没有进行赋值,所以自身的值不会发生改变。
>> 右移:1.逻辑右移:左边补0,右边丢弃。
2.算数右移:左边用原来的符号位填充,右边丢弃。
注:num>>-1;//这个是标准未定义的。 哪种右移是根据编译器来选择的。
位操作符: & | ^(操作数必须为整数)
按位&: 俩个二进制必须都为1,&的结果才为1,否则为0;
按位|:有一个1,|的结果就为1,俩个都是0,结果才为0;
按位^:相同为0,相异为1;
//求一个数二进制中1的个数
int num=-1;
int count=0;
while(num)
{
count++;
num&=(num-1);
}
printf("%d\n",count);
有几个1,就几次循环,效率比较高,如果每次按位与&,得32次。
按位操作符还可以改变某一位二进制的数,比如将n的第m位从0改到1: n | (1<<(m-1))
赋值操作符: =
复合操作符: += *= /= >>= <<= &= |= ^=
单目操作符: ! - + & sizeof ~ – ++ * (类型)
! 逻辑反操作
-负值
+正值
& 取地址
sizeof 操作数的类型长度(以字节为单位)
-
注:sizeof (int),sizeof求类型的大小时必须加上()。sizeof不是函数,所以sizeof内部的表达式不进行计算。
- 对一个数的二进制按位取反
– 前置,后置–
++ 前置,后置++
*间接访问操作符(解引用操作符)
(类型) 强制类型转换
关系操作符: > >= < <= != ==
注:1.字符串进行判断时,不能直接使用关系操作符,而是用strcmp;
2.==和=的区别,别写反。
逻辑操作符: && 逻辑与
|| 逻辑或
有面试题:i=0,a=0,b=2,c=3,d=4;
i=a++ && ++b && d++; // a=1,b=2,c=3,d=4;
i=a++ || ++b ||d++; //a=1,b=3,c=3,d=4;
结论:在逻辑表达式中,左操作数如果可以确定整个表达式的结果,就不执行右操作数。
比如:0 && a, 结果已经为0, a就不进行运算,直接跳过。
1 || b, 结果已经为1, b也不进行运算了。
条件操作符
exp1 ? esp2 : esp3
if(a>5)
b=3;
else
b=-3;
a>5 ? b=3 : b=-3;
b=a>5?3:-3;//常见
逗号表达式
逗号表达式,从左向右依次执行。整个表达式的结果是最后一个表达式的结果。
下标引用、函数调用和结构成员
1、[] 下标引用操作符
操作数:一个数组名 + 一个索引值
2、() 函数调用操作符
第一个操作数是函数名,其余的操作数就是传递给函数的参数
3、 . 结构体 . 成员名
-> 结构体指针 -> 成员名
注:结构体成员赋值字符串时不能直接用=赋值,用strcpy
表达式求值:
表达式求值的顺序一部分是由操作符的优先级和结合性决定的。
整形提升:
C的整形算术运算总是至少以缺省整形类型的精度来进行的。为了获得这个精度,表达式中的字符和短整型操作数在使用之前被转换为普通整型,这种转换称为整型提升。
表达式中各种长度可能小于int长度的整形值,都必须先转换为int或unsigned int ,然后才能送入CPU去执行运算。
整形提升是按照变量的数据类型的符号位来提升的。
//负数的整形提升:高位补充符号位,即为1,11111111111111111xxxxxxxx
//正数的整形提升:高位补充符号位,即为0,00000000000000000xxxxxxxx
//无符号整形提升:高位全补0
操作符的属性:
影响复杂表达式的求值的三个因素:
1.操作符的优先级
2.操作符的结合性
3.是否控制求值顺序(&& || ?: 逗号表达式 这4个操作符可以控制求值顺序的)
注:函数的调用顺序无法从操作符的优先级得知。
我们写的表达式如果不能通过操作符的属性确定唯一的计算路径,那这个表达式就是存在问题的