一.操作符
- 算数操作符
C语言提供以下算数操作符
+ - * / %
除了%操作符,其余几个操作符都是既适用于浮点类型又适用于整数类型,%操作运算符是取模运算,它接受两个整型参数,把左侧操作数除以右操作数,但它返回的是余数而不是商。
- 移位操作符
C语言提供算数移位和逻辑移位,左操作数的值将移动由右操作数指定的位数。
<<(左移) >>(右移)
逻辑左移和算数左移是一样的,右补所移位数个“0”;
逻辑右移左补所移位数个‘“0”,算数右移,如符号位为“1”,则补位所移位数个“1”,如果符号位为“0”,则补位“0”;
- 位操作符
与(&) 或(|) 异或(^)
位操作运算符要求操作数为整数,它们对操作数对应的位进行相应的操作,每一次对左右操作数的各一位进行操作。 - 赋值
=
赋值是表达式的一种,而不是某种类型的语句,所以只要允许出现表达式的地方都允许进行赋值运算,
复合赋值运算符
+= -= *= /= %=
<<= >>= &= ^= |=
举例说明,其余都相同
a += (expression); 与a = a +(expression);相等,并且expression两边的括号是有必要的。
- 单目操作符
! ++ - & sizeof()
~ -- + * (类型)
! 为逻辑反操作运算符,如果操作数为真,其结果为假,反之亦然;
~ 该操作符是对整型类型的操作数进行求补操作,操作数中所有原先的1变为0,所有原先的0变成1;
& 为地址运算符,&操作符产生它操作数的地址;
为间接访问操作符,它与指针一起使用,用于访问指针指向的值;
sizeof sizeof操作符用于判断它操作数的类型长度,以字节为单位,操作数既可以是表达式也可以是基本数据类型名称;
(类型) 操作数被称为强制类型转化*,它用于显式地把表达式的值转化成另外的类型;
++ -- 为自增自减操作符,这两个操作符的任何一个操作数都需要是一个变量而不是一个表达式作为它的操作数;前缀在使用变量的值前增加,后缀是使用变量的值乎增加;
- 关系操作符
!= >= < =
== > <
这些操作符产生的结果是一个整型值,而不是布尔值,若果两端的操作符符合给定的关系,表达式的结果是1,否则是0。
if(expression != 0)<<======>>if(expression)
if(expression == 0 )<<======>>if(!expression)
- 逻辑运算符
&& II
这两个操作符具有截断效应
,如果表达式expression1的结果为假,那么表达式 expression2将不再进行求值,其结果为假;
2.expression1 || expression2,如果表达式expression1的结果为真,那么表达式 expression2将不再进行求值,其结果为真;
- 条件操作符
expression1 ?expression2 : expression3;
条件运算符的级别比较低,所以它的表达式即使不加括号,一般也不会有问题,但是为了清楚表达还是最好加上括号。
首先对expression1进行求值,如果它的结果为真,那么整个表达式的值就是expression2,expression3不会进行求值,否则整个条件语句的值就是expression3的值,expression2不会进行求值。
- 逗号操作符
expression1,expression2,expression3,...expressionn;
逗号操作符将两个或两个以上的表达式分隔开,整个表达式的值是最后一个表达式的值
二.布尔值
在C语言中没有布尔类型的值,故有以下结论:
零是假,非零为真。
左值和右值
左值就是那些能够出现在赋值符号左边的值;
右值就是那些能够出现在赋值符号右边的值;
左值一般是标识了一个可以存储结果值的地点,但不是所有的变量都是左值,字面值常量也不是左值。
表达式也有可能是左值,如下标应用和间接操作,如:
1.a[b + 10] = 0;b+10是一个表达式,但它标识了一个具体的位置,a+b+10这个位置是可以确定的,因为a[b + 10] = (a + b + 10);
2.pi = 20,它左边显然是个表达式,但他是一个左值,是因为指针pi是内存中某个特定的值,*pi操作是其指向那个位置,当它做左值使用时,这个表达式指定需要修改的位置,当它做右值时,它就是提取存储于当前位置的这个值。
3.总结:有些操作符,如间接访问和下标应用,它们的值是一个左值,其余操作符的结果是个右值。
3.表达式求值
表达式的求值顺序一部分是由它所包含的的操作符的优先级和结合性决定,同样,有些表达式的操作数在求值过程中可能需要转换成其它类型。
隐式类型转换
C的整型算术运算总是至少以缺省整型类型的精度来进行的,为了获得这个精度,表达式中的字符型和短整型操作数在使用之前被转化为普通整型
算数转换
如果某个操作符的各个操作数属于不同的类型,那么除非其中一个操作数转换成另一个操作数的类型,否则无法进行该操作,下面的层次体系称为寻常算数转换。
long double;
double;
unsigned long int;
long int;
unsigned int;
int;
如果某个操作数的类型在上面这个列表中的排名较低,那么它首先转换为另一个操作数的类型然后进行操作。
操作符的属性
复杂操作符的求值顺序是由三个因素决定的:
- 操作符的优先级:优先级相同,那么它们执行的顺序由结合性决定。
- 操作符的结合性:一串操作符是从左向右还是从右向左逐个执行
- 操作符是否控制执行的顺序:4个操作符控制求值顺序:"&&","||","?",","。
操作符的优先级如下图:
注意:优先级只对相邻的操作符起作用。