操作符

算数操作符

C 提供了所有常用的算数操作符 :

+ - * / %

除了 % 操作符, 其余几个操作符都适用于浮点型和整型.

/ 的两边都是整数时执行整除运算.

移位操作符

移位操作只是简单的把一个值的位向左或向右移动.

在左移位中, 值最左边的几位被丢弃, 右边多出来的几个位由0不起.

右移位存在一个左移位不曾面临的问题: 从左边移入新位时, 可以选择两种 方案:

  1. 逻辑移位, 左边移入的位用0 填充
  2. 算数移位, 左边移入的为有原先改值的符号位决定, 符号位 1 则移入位均为1, 符号位为0, 则移入位均为0, 这样能够保持原数的正负形式不变.

左移位操作符为 <<, 右移位操作符为 >>, 左操作数的值将移动右操作数 指定的位数. 两个操作都必须是整型.

标准说明 无符号的右移位操作都是逻辑移位, 而有符号的取决于编译器.

下面程序使用右移位操作符计算一个值中值为 1 的位的个数. 使用 % 操作符判断左右边的一位是否非零

#include <stdio.h>

int
count_one_bits(unsigned value)
{
    int ones;
    /*
     * 当这个值还有一些值为 1 的位时
     */
    for (ones = 0; value != 0; value = value>>1)
        /* 如果最低位值为1, 计数曾 ; */
        if (value % 2 != 0)
            ones = ones + 1;
    return ones;
}

位操作符

位操作符对他们的操作数各个位执行 AND, OR 和 XOR(异或)等逻辑操作.

  1. 当两个位进行 AND 操作时, 如果两个位都是1, 结果为1, 否则为 0
  2. 当两个位进行 OR 操作时, 两个位其中为 1, 结果为 1, 否则为 0
  3. 当两个位进行 XOR 操作时, 如果两个位不同, 结果为 1, 否则为 0

位操作符有:

& | ^

分别是 AND, OR 和 XOR 操作.

赋值

赋值操作符用一个等号表示.

单目操作符

C 具有一些单目操作符, 也就是只接受一个操作符的操作符:

!   ++  -   &   sizeof
~   --  +   *   (类型)
! 操作符对它操作数执行逻辑反操作: 如果操作数为真, 其结果为假, 操作数 为假, 其结果为真

~操作符对整型类型的操作数进行求补操作, 操作数中原先为 1 的位变为0, 所有原先为0的位变1

- 操作符产生负值

+ 操作符产生操作数的值

& 操作符产生操作数的地址.

* 操作符是间接访问操作数, 用于访问指针所指向的值.

sizeof 操作符判断它的操作数的长度, 以字节为单位

(类型) 操作符被称为 强制类型转换

++/-- 略

关系操作符

关系操作符用于测试操作数之间的各种关系:

> >= < <= != ==

这些操作数产生的结果都是一个整型值. 测试通过结果为 1, 否则结果是 0.

表达式结果是 0, 则为假, 结果是任何非0值, 被认为是真

逻辑操作符

逻辑操作符有 && 和 ||

&& 操作符的左操作数总是首先进行求值

条件操作符

expression1 ? expression2 : expression3

逗号操作符

逗号操作符将两个或多个表达式隔开. 这些表达式将从左向右逐个进行求值.

整个逗号表达式的值就是最后那个表达式的值.

下标引用, 函数调用和结构成员

布尔值

C 不具备显示的布尔类型, 所以使用整数来代替:

零是假, 任何其他非零值为真

左值和右值

左值(L-value) 就是能够出现在复制符号左边的东西

右值(L-value) 就是那些可以出现在赋值符号右边的东西.

表达式求值

表达式的求值顺序一部分是由它所包含的操作符的优先级和结合性决定.

表达式在求值过程中可能需要转换为其他类型

隐式类型转换

C 的整型计算总是至少以缺省整型类型精度类进行, 表达式中 字符型和 短整型操作数在使用之前被转换为普通整型, 这种转换称为 整型提升(intergral Promotion)

算数转换

下面的层次体系称为 寻常算数转换(usual arithmetic conversion)

long double
double
float
unsigned long int
long int
unsigned int
int
如果某个操作数的类型在上面这个列表中排名较低, 那么它首先将转换为 另外一个操作数的类型然后执行操作.

操作符的属性

复杂的表达式求值顺序有3个因素决定:

  1. 操作符优先级
  2. 操作符的结合性
  3. 操作符是否控制执行的顺序

结合性就是一串操作符是从左向右一次执行还是从右向左做个执行

优先级和求值顺序