12
||
逻辑或
2
双目运算符
自左至右
(x>1)&&(y<3)
13
?
:
条件
3
三目运算符
自右至左
x=a>b?
a:
b
14
=
+=-=
*=/=
%=&=
^=|=
>>=<<=
赋值
(复合赋值)
2
双目运算符
自右至左
a=a+b
a+=b(同a=a+b)
a*=b+c(同a=a*(b+c))
a&=b(同a=a&b)
其余复合运算符类似
15
,
逗号
2
双目运算符
自左至右
a=1,b=2,c=12
本章将详细讨论C语言的算术运算符、赋值运算符、强制类型转换运算符、逗号运算符、关系运算符、逻辑运算符。
其余的运算符将在后续章节中逐步介绍。
2.关于运算符的几点说明
(1)C语言的运算符按其性质分类有15类;按运算符所要求操作数的个数分类,又可以分为单目运算符、双目运算符和三目运算符。
例如:
“++”为单目运算符,“*”、“/”为双目运算符,“?
:
”为三目运算符。
(2)优先级别。
一个表达式中可以有多个运算符,这时首先按运算符的优先级别进行运算,C语言运算符的优先级别与数学运算中的意义相同,它决定了一个表达式的运算顺序。
如果一个操作数两侧有两个不同优先级别的运算符,则先执行优先级别高的运算。
如4-9*7,在9的两侧分别为-、*,根据C运算符的运算级别,则先*后-。
(3)结合性。
如果一个操作数的两侧有两个优先级别相同的运算符,则按结合方向顺序进行处理。
C语言运算符的结合性分为:
①左结合性。
如果一个运算符对其操作数自左至右执行规定的运算,则称该运算符是左结合的。
运算符+、-、*、/、%、&&、||等都是左结合性的运算符。
例如:
5*8/3
8两侧的运算符分别为*、/,它们的优先级相同,根据“自左至右”方向的结合原则先*后/,即8先和其左边的运算符结合(5*8),再与其右边的运算符结合(40/3)。
②右结合性。
如果一个运算符对其操作数自右向左执行规定的运算,则称该运算符是右结合的。
运算符=、!
、++、--等都是右结合性的运算符。
例如:
a=b=c=8
b两侧都是赋值运算符“=”(即优先级相同),根据“自右至左”方向的结合原则,它先与其右侧的赋值运算符结合,即a=(b=c=8)。
由于赋值运算符“=”是一个双目运算符,因此b右侧赋值运算符的右边要求有一个操作数,这里是“c=8”,那么是把c的值直接赋给b呢?
还是先进行“c=8”运算呢?
由于c两侧的运算符级别相同且是“右结合性”,因此c应先与其右的赋值运算符结合,故表达式相当于a=(b=(c=8))。
关于“结合性”的概念是其他高级语言没有的,是C语言的特点之一。
(4)在使用C语言的运算符时,应注意运算符对操作数类型的要求。
如+、-、*、/的运算对象可以是整型或实型数据,而运算符%(求余运算符)要求参加运算的两个操作数都必须是整型数据。
(5)一个运算符两侧的操作数类型可以不同,C编译会自动进行类型转换,使二者具有同一种类型,然后进行运算。
(6)C语言的运算符较多,又有其优先级和结合性,初学者要特别仔细,善于归纳。
3.1.2C表达式简介
用运算符将常量、变量、函数等(称为操作数)连接起来的符合C语言规定的式子称为C语言表达式。
作为表达式的特例,一个单独的变量或常量也可以称为一个表达式。
下面是几个表达式的例子:
a+b-c*3+d/ea>>8y=a+b||ca+=a+b
C语言中所有的运算都是用表达式表示的,清楚地了解表达式的求值顺序是正确书写表达式的关键。
表达式的求值顺序取决于表达式中参与运算的运算符的优先级、结合性和语言的具体实现。
例如,表达式:
a+b*c
因“+”的优先级低于“*”,所以运算顺序为先计算b*c的值,然后再与a相加。
再如,表达式:
-n++
由于运算符“-”(负号运算符)和“++”的优先级相同,结合性均为右结合的,所以求解该表达式的顺序为:
先进行n++运算,然后再对运算结果求负。
即相当于:
-(n++)。
3.2算术运算符和算术表达式
算术运算是我们日常生活中使用最为常见的一种运算。
C语言不仅提供了基本算术运算符,如加、减、乘、除和求余等,还提供了增量、减量运算符。
3.2.1基本算术运算符和算术表达式
1.基本算术运算符
C语言中的基本算术运算符包括单目算术运算符:
-(负号)
和双目算术运算符:
+(加)-(减)*(乘)/(除)%(模除)
单目运算符“-”又叫做一元减运算符,其作用与数学中的负号相同,即取操作数的负值。
双目算术运算符+、-与数学中的加、减的作用相同,而*、/则分别对应数学中的乘、除。
例如,3+5,6-4,3*a,b/c等。
双目运算符%叫做模运算符或称为求余运算符,其作用是取被除数的模,即被除数除以除数后的余数。
例如,13%5的结果为3,3%5的结果也为3,而-13%5的结果为-3。
单目算术运算符“-”结合方向为“自右至左”,其优先级别高于双目算术运算符,双目算术运算符的*、/、%的优先级别相同,运算符+、-的优先级别相同,但前者的优先级别高于后者。
双目算术运算符的结合方向为“自左至右”。
需要说明的是:
(1)运算符“%”要求它的两个操作数都是整型数据。
(2)其他运算符可以是任何基本数据类型。
(3)若运算符“/”的两个操作数都为整数,则运算结果即商也为整数,小数部分被自然舍弃了。
例如:
13/5的运算结果为2,5/13的运算结果为0。
参加运算的两个数只要有一个为实型,则结果是实型。
2.算术表达式
用算术运算符和括号将运算对象(也称操作数)连接起来的、符合C语言语法规则的式子称为C算术表达式。
运算对象包括常量、变量、函数等。
例如,下面是一个合法的C算术表达式:
a*b/c-1.5+'a'
C语言规定了运算符的优先级和结合性。
在写C表达式时一定要注意运算符的优先次序和结合方向,C表达式求值时,先按优先级别高低次序执行。
如果在一个运算对象两侧的运算符的优先级别相同,则按规定的“结合方向”处理。
如:
a-b+c*d
该表达式的运算顺序为:
(1)由于b两侧的运算符的优先级别相同,则按“自左至右”结合方向进行,因此b先与减号结合,执行(a-b)运算;
(2)由于c两侧运算符的优先级不同,*高于+,因此c先与*结合,执行(c*d)运算;
(3)最后执行(a-b)+(c*d)运算。
3.2.2增量减量运算符
C语言提供了两个使变量的值增1、减1的运算符:
++(增量)--(减量)
它们都是单目运算符,其运算结果是将操作数的值加1、减1。
例如:
设变量i的值为5,则++i后i的值将变为6,即表达式++i相当于赋值表达式i=i+1。
又如--i相当于赋值表达式i=i-1。
由于增量、减量运算符本身就隐含有赋值操作,所以它们的操作数必须是一个变量。
例如:
5++或(a+b)++都是不合法的。
但是,与其他单目运算符不同的是,这两个单目运算符的操作数既可以放在运算符的前面,又可以放在运算符的后边。
如:
++i(前置增量)i++(后置增量)
--i(前置减量)i--(后置减量)
作为一个单独的表达式时,运算符前置和后置是没有什么区别的,但在一个还包含有其他运算的表达式中,运算符前置和后置却会产生不同的效果。
在一个包含有其他运算的表达式中,增量或减量运算符的前置意味着先对其操作数进行相应的增量或减量,然后再进行其他的运算;而后置增量或后置减量运算符先对其操作数进行其他运算,然后对操作数进行相应的增量或减量运算。
例3.1测试表达式中前置、后置增量运算符的运算顺序。
#include
voidmain(){
inti=5,j,k;
j=++i;
printf("i=%d,j=%d",i,j);
k=i++;
printf("i=%d,k=%d\n",i,k);
}
运算结果为:
i=6,j=6,i=7,k=6
表达式使用中应注意的问题:
(1)++和--的结合方向是“自右至左”,即右结合性。
如果有-i++,i的左边是负号运算符,右边是增量运算符。
因负号运算符与增量运算符同优先级,而它们的结合方向为“自右至左”,故先进行“i++”运算,再进行负号运算,即它相当于-(i++)。
例如,如果i的值为3,对于printf("%d",-i++);语句,则先取出i的值使用,输出-i的值-3,然后使i增值为4。
另外,假若按左结合性,则上式相当于(-i)++,而(-i)++是不合法的。
(2)增量、减量运算符常用于循环语句中,使循环变量自动加1或减1。
也用于指针变量,使