C提供了所有常用的算术操作符,如下所示:
除了%操作符,其他操作符都是既适用于浮点类型又适用于整数类型。当/操作符的两个操作数都是整数时,它执行整除运算,在其他情况下则执行浮点数除法。%为取模操作符,它接受两个整型操作数,它左边操作数除以右边操作数,但它返回的值是余数而不是商。
移位操作只是简单把一个值的位向右或向左移动。在左移位中,值最左边的几位被丢弃,右边多出来的几个空位则由0补齐。
右移位操作存在一个左移位操作不曾面临的问题:从左边移入新位时,可以选择两种方案。第一种是逻辑移位。左边移入的位用0填充;第二种是算法移位,左边移入的位由原先该值的符号位决定,符号位为1则移入的为均为1,符号位为0则移入的位均为0,这样能保存原数的正负形式不变。算术左移和逻辑左移是相同的,只在右移时不同,而且只有当操作数是负值时才不一样。
左移位操作符<<,右移位操作符>>。左操作数的值将移动由右操作数指定的位数。两个操作符都必须是整型类型。
CUE:标准说明无符号值所执行的所有移位操作都逻辑移位,但对于有符号值,到底是采用逻辑移位还是算术移位取决于编译器。
位操作符:位操作符对它们的操作数的各个位执行and、or和xor(异或)等逻辑操作。
当两个位进行and操作时,如果两个位都1,结果位1,否则结果为0。当两个位进行or操作时,如果两个位都是0,结果为0,否则结果为1。当两个位进行xor操作时,如果两个位不同,结果为1,如果两个位相同,结果为0。
位操作符:
它们分别执行and、or和xor操作。它们要求操作数为整数类型,对操作数对应的位进行指定的操作,每次对左右操作数的各一位进行操作。
单目操作符:~ 。它用于对其操作数进行求补运算,即1变0,0变1。
赋值操作符,用一个等号表示。赋值是表达式的一种,而不是某种类型的语句。赋值操作符的结合性(求值的顺序)是从右到左。
复合赋值符:
单目操作符:
CUE:单目操作符只接受一个操作数。
! 操作符对它的操作数执行逻辑反操作;如果操作数位真,其结果为假,如果操作数为假,其结果为真。和关系操作符一样,这个操作符实际上产生一个整型结果,0或1。- 操作符产生操作数的负值,& 操作符产生它的操作数的地址。* 操作符是间接访问操作符,它与指针一起使用,用于访问指针所指向的值。
sizeof操作符判断它的操作数的类型长度,以字节为单位表示。操作数既可以是表达式(常常是单个变量),也可以是两边加上括号的类项名。当sizeof的操作数是个数组名时,它返回该数组的长度,以字节为单位。
(类型) 操作符被称为强制类型转换,它用于显示地把表达式的值转换为另外的类型。
增值操作符++和减值操作符– 都需要一个变量而不是表达式作为它的操作数,该操作符实际上只要求操作数必须是一个“左值”。
C常见的关系操作符
!= 操作符用于测试不相等,而==操作数用于测试相等。这些操作符产生的结果都是一个整型值,而不是布尔值。如果两端的操作数符合操作符指定的关系,表达式结果是1,相反为0。
逻辑操作符有&&和||,它们用于对表达式求值。&&操作符的左操作数总是首先进行求值,如果它的值为真,然后就紧接着对右操作数进行求值。如果左操作数的值为假,那么右操作数便不再进行求值,因为整个表达式的值肯定是假的,右操作数的值已经无关紧要。||操作符也具有相同的特点,它首先对左操作数进行求值,如果它的值是真,右操作数便不再求值。因为整个表达式的值此时已经确定。这个行为常常被称为“短路求值”。
条件操作符接受三个操作数,它也会控制子表达的求值顺序。语法如下:
逗号操作符将两个或多个表达式分割开来。这些表达式自左向右逐个进行求值,整个逗号表达式的值就是最后那个表达式的值。
下标引用操作符是一对方括号。下标引用操作符接受两个操作数:一个数组名和一个索引值。C的下标值总是从零开始,并且不会对下标值进行有效性检查。同时下表引用操作和间接访问表达式是等价的,如:array[下标]<==>*(array+(下标)),二者等价。
函数调用操作符接受一个或多个操作数。它的第1个操作数是希望调用的函数名剩余的操作数是传递给函数的参数。
. 和-> 操作符用于访问一个结果的成员。
C并不具备显示的布尔类型,所以使用整数来代替。其规则是:零是假,任何非零值皆为真。
左值(L-value)和右值(R-value):左值就是那些能够出现在赋值符号左边的东西,右值就是那些可以出现在赋值符号右边的东西。
表达式求值——隐式类型转换:C的整型算术运算总是至少以缺省整数类型的精度来进行的。为了获得这个精度,表达式中的字符型和短整型操作数在使用之前被转换为普通整型,这种转换称为整型提升。
表达式求值——算术转换:如果某个操作符的各个操作数属于不同的类型,那么除非其中一个操作数转换为另一个操作数的类型,否则操作就无法进行。下面的层次体系称为寻常算术转换。
如果某个操作数的类型在上面这个列表中排名较低,那么它首先将转换为另一个操作数的类型然后执行操作。
优先级和求值的顺序:两个相邻操作符的执行顺序由它们的优先级决定。如果它们的优先级相同,它们的执行顺序由它们的结合性决定。除此之外,编译器可以自由决定使用任何顺序对表达式进行求值,只要它们不违反逗号、&&、||和?:操作符所施加的限制。