7表达式
运算符的优先级和结合性有明确的规定 除少数情况外,表达式的求值次序没有多余,甚至某些有副作用的子表达式也没有第一 也就是说,除非运算符的定义保证了其操作数按某一特定顺序求值,否则具体的实现可以自由的选择任一求值次序,甚至可以改变求值次序 但是,每个运算符将其操作数生成的值结合起来的方式与表达式的语法分析方式是兼容的 C语言没有定义表达式求值过程中的溢出、除法检查和其他异常的处理 大多数现有C语言的实现在进行带符号的整型表达式的求值以及赋值时忽略溢出异常,有时候可以用非标准库函数进行调整
7.1 指针生成
对应某类型T,如果某表达式或子表达式的类型为“T类型的数组”
则此表达式的值是指向数组中第一个对象的指针,并且此表达式的类型将被转换为“指向T类型的指针” 如果表达式是一元运算符&或sizeof,则不会进行转换。 类似地,除非表达式被用作&运算符的操作数,否则类型为“返回T类型值的函数”的表达式将被转换为“指向返回T类型的值的函数的指针”类型
7.2 初等表达式
初等表达式包括标识符 常量 字符串或带括号的表达式
7.3 后缀表达式
后缀表达式中的运算符遵循从左到右的结合规则 后缀表达式 初等表达式 [] (参数列表) . 成员 ->成员 ++ -- 数组引用 函数调用 结构引用 后缀自增自减
7.4 一元运算符
带一元运算符的表达式遵循从右到左的结合性 后缀表达式 ++表达式 --表达式 强制类型转换 sizeof 一元表达式 sizeof (类型名) 一元运算符: & * + - ! 前缀自增运算符自减运算符 地址运算符& 间接寻址运算符 * 一元加运算符 一元减运算符 二进制反码运算符~ 逻辑非运算符! sizeof运算符 sizeof运算符计算存储与其操作数同类型的对象所需的字节数 操作数可以为一个未求值的表达式 也可以为一个用括号扩起来的类型名 将sizeof用于char时,结果为1 用于数组时,其值为数组中字节的总数 用于结构和联合时,结果为对象的字节数 包括对象中包含的数组所需的任何填充空间 此运算符不能用于函数类型和不完整类型的操作数,也不能用于位字段 结构是一个无符号整型常量 size_t
7.5 强制类型转换
(类型名)类型转换表达式
7.6乘法类运算符
乘法运算符* / 和%遵循左到右的结合性
7.7加法类运算符
7.8移位运算符
移位类运算符<<和>>遵循从左到右的结合性 每个运算符的个操作数必须为整型,并且遵循整型提升原则 结果的类型是提升后的左操作数的类型 如果右操作数为负值 或者大于等于左操作数的类型的位数,则结果没有定义
7.9关系运算符
关系运算遵循从左到右的结合性,但这个规则没有什么用 a<b<c 在语法上分析将被解析为 (a<b)<c ,并且a<b的结果只能为0或1 关系表达式的结果为假时值为0 结果为真时 值为1
7.10 相等类运算符
相等运算符与关系运算符具有相同的规则,但这类运算符还允许执行: 指针可以和0的常量整型表达式或指向void的指针解析比较