文章目录
6.1 算术运算符
算术运算符可以执行加、减、乘、除、取余运算。比如常见的
2 + 10 * 5,+和*运算符都是二元运算符,因为运算符需要两个操作数。
二元算术运算符:
操作数个数 | 加法类 | 乘法类 |
---|---|---|
二元算术运算符 | + 加法运算符 - 减法运算符 |
* 乘法运算符 / 除法运算符 % 求余运算符 |
一元算术运算符 | +一元正号运算符 -一元负号运算符 |
除了二元算术运算符,像-5这样的式子中的减号-也属于一种运算符,其作用是取操作数的相反数,由于操作数只有一个,因此是一元算术运算符。
比如,
i = +1;
j = -1;
一元运算符+什么都不做。它主要强调某数值是正的。
6.1.1 二元算术运算符详解
- 与数学中/运算符不同,C语言中整数除以整数的结果是整数,也就是说整数除以整数会丢弃小数部分,只保留整数部分。比如,1 / 2 结果是0而不是0.5,-10 / 4结果是-2而不是-2.5。
- 运算符%要求两个操作数都是整数,如果有一个不是整数,程序将无法编译通过。运算结果是两个操作数相除的余数。比如,10 % 3的余数是1,而12 % 4的余数是0。
- 除%运算符以外,二元算术运算符允许操作数都是整数、都是浮点数或者是整数和浮点数的混合。当把int型操作数和float型操作数混合在一起时,运算结果是float型的。因此,9 + 2.5f的值为11.5,而6.7f / 2的值为3.35。
- /和%运算符如果右操作数是零会出现未定义的行为。
- 当运算符/和%用在负数上时,其结果根据环境有不同。在C89标准下,如果两个操作数中有一个是负数,除法的结果既可以向上取整也可以向下取整。比如-9/7的结果既可能为-1也可能为-2。因此-9%7的结果也是不定的,既可能是-2也可能是5。这样的现象叫由实现定义的行为。在C99标准下,除法的结果总是向零截取,因此i%j的值的符号和i相同。比如-9 / 7结果为-1,-9 % 7结果为-2。注意,任何标准下,/和%运算结果都有如下关系:如果a/b和a%b有意义,那么 (a/b)*b + a%b应该等于a。
6.1.2 运算符的优先级和结合性
类似于数学中先算乘除后算加减,C语言规定了运算符的优先级。
算术运算符的优先级如下:
最高优先级: + - (一元运算符)
较高优先级:* % / (二元运算符)
最低优先级:+ - (二元运算符)
如果要改变默认运算符的运算顺序,可以添加()。比如i + j * k按照运算符优先级先算j * k,然后i再和结果相加。圆括号的加入可以修改运算顺序为先算加法,后算乘法:(i + j) * k
一些表明运算符优先级的例子:
i + j * k 等价于 i + (j * k )
-i * -j 等价于 (-i) * (-j)
+i + j / k 等价于 (+i) + (j / k)
如果表达式中包含多个优先级一样的运算符,那么还要确定是从左往右算还是从右往左算。这称为运算符的结合性。如果运算符是从左往右算的,那么称这种运算符是左结合性,否则是右结合的。二元算术运算符(+、 -、 *、 / 和 %)都是左结合的。所以
i - j - k 等价于 (i - j) - k
i * j / k 等价于 (i * j) / k
一元算术运算符+和-是右结合的,比如
- + i 等价于 - (+i)
下节介绍的赋值运算符=也是右结合的,比如
x = y = z = 10 等价于 x = (y = (z = 10))
运算符太多了,所以记住所有运算符的优先级和结合性可能不现实。可以在使用的时候参考手册,比如C 中的运算符优先级,也可以用圆括号强制规定运算顺序。
6.2 赋值运算符
求出表达式的值之后常常需要将其存储到变量中,以便将来使用。赋值运算符=
可以用作此目的。为了基于变量中原先的值更新变量中的值,C语言还提供了若干复合赋值运算符。
6.2.1 简单赋值
表达式v = e
的赋值效果是求出表达式e
的值,并把此值赋给v
。如下面的例子所示,e
可以是常量、变量或者更为复杂的表达式。
i = 5; // i为5
j = i; // j为5
k = 10 * i + j; // k为55
如果v
和e
的类型不同,那么赋值运算发生时还是先求出表达式e
的值,然后将该值转化为v
的类型再赋给v
。说起来比较拗口,用例子比较直观:
int i;
float f;
i = 72.6f; // i是72
f = 30; // f是30.0
这里要强调的是C语言是强类型的语言,整数72和浮