C语言的语法基础

2.3 运算符与表达式

 

C语言有很丰富的运算符,总结如下:

1.算术运算符: + (加), –(减), *(乘), /(除),  %(求余)

2.关系运算符: >(大于), <(小于), <=(小于等于),

>=(大于等于), ==(等于), !=(不等)

3.逻辑运算符: !(逻辑非),  &&(逻辑与),  (逻辑或)

4.位运算符:   ~(按位取反), &(位与),    |(位或),

∧ (异或),    <<(左移),   >>(右移)

5.条件运算符: ?  :

6.指向结构体成员运算符:     ->

7.结构体成员运算符(分量运算符): .

8.自增1,自减1运算符:    ++  , --

9.类型转换运算符:          (类型)

10.指针,取地址运算符:  *(指针运算符), &(取地址运算符)

11.下标运算符:          [ ]

12.赋值运算符:          =, *=,+=,-=,/=,%=,>>=,<<=,&=,∧=,|=

13.逗号运算符:          ,

14.长度运算符:          sizeof( )

15.负号运算符:          -

16.括号运算符:          ( )

本章只介绍算术运算符、增1与减1运算符、关系、逻辑及条件运算符、位运算符、赋值运算符、类型转换运算符、逗号运算符和长度运算符。

 

2.3.1算术运算

  1.算术运算符

C语言的算术运算符有以下5种:

+  ( 双目运算两数相加,如5+6,单目运算取正值,如 +15 )

-  ( 双目运算两数相减,如5-6,单目运算取负值,如 -19 )

*  ( 双目运算符,两数相乘, 如 5*6 )

/  ( 双目运算符,两数相除, 如 15/6 )

%   ( 双目运算符,取模或求余数,两个数必须都是整数,如 15%6 值为3)

所谓单目运算符是指对一个运算对象进行操作。例如: -19。双目运算符是对两个运算对象进行操作,这两个运算对象分别放在操作符的左边和右边。如:5+6。

2.算术运算符的优先级和结合方向

计算机语言中的运算符与数学中的运算符类似,都有优先级和结合方向。C语言的算术运算符的优先级如下(同一行上的运算符,优先级相同):

(  )      圆括号            高

+、-    单目运算符,取正、取负

*、/、%   双目运算符,乘、除、取模

+、-      双目运算符,加、减       低

上面所有双目算术运算符的结合方向都是“从左到右”,而单目运算符取正“+”和取负“-”的结合方向是“从右到左”。

    3.算术运算表达式

C语言的算术表达式是由算术运算符把运算对象连接起来,构成合法的式子。运算对象包括常量、变量和函数。算术表达式的值为整数或实数。如 3*x+1.0/y-10*sqrt(x) 。

在对算术表达式进行运算时,应注意以下几点:

(1) 算术表达式中可以使用多层圆括号,左、右括号必须配对。运算时先计算出内层括号表达式的值,由内向外计算表达式的值。

(2) 取模运算符%两侧的运算对象必须是整数,运算结果是两数相除后所得的余数。在多数机器上,取模后值的符号与运算符左侧运算对象的符号相同。例如:5%3值为2,-5%3 值为-2,5%(-3) 值为 2; 实数不能参与取模运算,如5%1.5是非法的算术表达式。

(3) 整数除:两个整数相除后值等于商的整数部分(小数部分没有四舍五入), 例如 1/2  为整数除,其值为0。

(4)实数除:两个相除的数中至少有一个是实数,相除后的值等于(商本身)实数,如 1.0/2 (或 1/2.0 或 1.0/2.0) 均为实数除,值都是0.5。

例如表达式(-16/3*2+1)%6的值是 -3,先计算圆括号内的值,单目运算符“-”优先级高于其它双目运算符,先计算整数除–16/3值为 –5, 然后-5*2+1值为 –9, 最后-9%6值为-3。

    4.各类数值型数据的混合运算

在C语言中允许整型、实型、字符型数据进行混合运算。例如

1.23+'A'+456%'B'

是合法的C表达式。不同类型的数值型数据进行混合运算时,先要把低数据类型向高数据类型转换,成为同一类型后才进行运算。转换的规则如下图2.6:

高      long double

double  ←  float

long

unsigned

低        int  ←  char,short

           图2.6  不同类型的数值型数据进行混合运算时类型的转换规则

图中向左的横向箭头表示必须进行的转换,如两个float型的数据相加,也要先把这两个float数据转换成double型数据,然后再进行运算,以提高精度。向上的纵向箭头表示不同类型数据混合运算时,先要进行的数据类型转换。例如表达式123.456+543-'A' ,运算时先把整型数据543转换成double型数据后,与123.456相加值为666.456(double型数据),然后把字符'A'转换成65.0(double型数据)再进行相减运算,最后结果为601.456(double型数据)。

 

2.3.2增1与减1运算

 

增1运算符“++”使运算对象的值增1, 而减1运算符“--”则使运算对象的值减1。它们都是单目运算符,其运算对象必须是变量,不能是常量和表达式。例如语句i++;相当于语句i=i+1;又如语句i--;相当于语句i=i-1;

增1与减1运算符可以作前缀运算符,这时是先使运算对象值增1或减1之后,再使用运算对象。例如 i=1;j=++i;则变量i的值先增1变成2,然后把i的值赋给变量j,j的值为2。同样的若有语句 i=1;j=--i;执行后i的值为0,j的值为0。

增1与减1运算符也可以作后缀运算符,这时是先使用运算对象,再使运算对象值增1或减1。例如 i=1;j=i++;则先把i的值赋给变量j,j的值为1,然后变量i的值再增1变成2。同样的若有语句 i=1;j=i--;执行后i的值为0,j的值为1。

增1与减1运算符如果仅仅只进行自加、自减运算,没有使用运算对象的值,作前缀运算符与作后缀运算符运算结果一样。如语句 i--;与语句 --i;效果一样,都等同于语句i=i-1;

“++” 和 “--”运算符的结合方向是“从右到左”。例如 i=1; j=-i++;由于取负运算符“-”和增1运算符“++”的优先级相同,结合方向是“从右到左”,即相当于-(i++),又由于是后缀运算符,则先取出i的值使用,把-i的值赋值给j, 变量j的值为-1,然后使i的值增1变成2。

应尽量避免在一个表达式中多次用“++” 和 “--” 运算符,这样写出的表达式可读性差,不同的编译系统也可能给出不同的运算结果。例如 i=1;j=++i+i++;k=i++*++i;可使用临时变量过渡一下,分解成多条语句来完成类似的功能。例如上面三条语句可以改成如下五条语句:

i=1;

t=++i;       /* 执行后,i值为2, t值为2。 */

j=t+i++;            /* 执行后,j值为4, i值为3。 */

t=++i;         /* 执行后,i值为4, t值为4。 */

k=(i++)*t;    /* 执行后,k值为16,i值为5。 */

变量t作为临时变量,把“++”运算符只写在一个表达式中,这样程序可读性好,不同的编译系统给出的运算结果都相同。以上程序段运行后,变量i,j,k的值分别是5,4 ,16。

 

 

Tags:

发表评论