当前位置: 首页 > >

三章运算符和表达式-PPT精品文档_图文

发布时间:

第三章 运算符和表达式

教 材:

C程序设计导论

主讲:谭成予

nadinetan163

武汉大学计算机学院

本讲重点
C运算符分类 运算符运算规则 优先级别和结合性

运算符及表达式简介
表达式:由动词(运算符和函数调用)和名词(变量和常量)组成的
一个完整的句子,说明了动词是如何运用到名词上产生一个结果。

运算符:完成特定运算功能的符号。

C语言运算符的类型:
算术运算符 关系运算符 条件运算符 逗号运算符

赋值运算符 逻辑运算符 位运算符 其他运算符

运算符的优先级与结合性

本讲重点
C运算符分类
运算符运算规则 算术运算符
优先级别和结合性

算术运算符
+ - * / %(求余) + +(自增) - -(自减)
使用要点:
1)两个整型数相除,其结果为整型;
如:10/3=3 -5/3=-1 (负数采用“向零取整”)
2)%运算符的两个操作数必须是整型;
如:7%4=3 特别情况:
0%5=0;5%0=5; -7%4=-3;-7%-4=-3; 7%-4=3。 即: %运算的符号只取决于第一个运算数的符号。

算术运算符
双目运算符:如 +、-、*、/和%; 单目运算符:如 “+”和“-”还可分别作为取正值、负值运算符。 单目运算符“+”和“-”优先级别高于双目运算符+、-、*、/和%; 双目运算符的优先级别:先乘除(*、/或%),后加减(+或-)

算术运算符

/*L3-1.C:算术运算符示例*/

#include <stdio.h>

int main(void)

{ short int x,a=3;

float y;

x=20+25/5*2; printf(“x=%d\n”,x);

x=25/2*2;

printf(“x=%d\n”,x);

x=-a+4*5-6; printf(“x=%d\n”,x);

x=a+4%5-6; printf(“x=%d\n”,x);

x=-3/4%-6/5; printf(“x=%d\n”,x);

x=(7+6)%5/2; printf(“x=%d\n”,x);

y=25.0/2.0*2.0; printf(“y=%.4f\n”,y);

return 0;

}

x=30 x=24 x=11 x=1 x=0 x=1 y=25.0000

自增、自减运算符
+ + 自增运算符,表示加1运算 - - 自减运算符,表示减1运算
前缀形式:在计算时先改变变量的值,再参与其它运算.
+ +i - -i
例:若 i=1, 则 k=+ +i +2 运行后 i=2、k=4
后缀形式:在计算时先参与其它运算,再改变变量的值.
i+ + i- 例:若 i=1, 而 k=i+ + +2 运行后 i=2、k=3

自增、自减运算符
? + +与- -运算符的使用规则: –+ +与- -运算只能用于有左值的表达式,而不能用于常量 或一般的表达式。 如:5+ +或(a+b)+ +为不合法的。
? ++与--运算符的的结合性为右结合性。

自增、自减运算符
/*L3-2.C:自增、自减运算符举例*/ #include <stdio.h> int main() {
short int a,b,c; a=9; b=++a; printf(“(1)a=%d***b=%d\n”,a,b); a=9; b=a++; printf(“(2)a=%d***b=%d\n”,a,b); return 0; }
(1)a=10***b=10
(2)a=10***b=9

正确使用自增、自减运算符
对i+ + +j 表达式的处理:采用“自左至右”的原则 即: i+ + +j 与(i+ +)+j 等价
而不是与i+(+ +j )等价

正确使用自增、自减运算符
1. 对于代码int i = 3; i = i++; 不同编译器给出不同的结果, 有 的为3, 有的为4, 哪个是正确的?
2. 为什么这样的代码: a[i] = i++; 不能工作?
1. 对于代码int i = 3; i = i++; 不同编译器给出不同的结果, 有 的为3, 有的为4, 哪个是正确的?
答: 没有正确答案; 这个表达式无定义。注意, i++ 和++i 都不同 于i+1。如果你要使i 自增1, 使用i=i+1, i+=1, i++ 或++i, 而
不是任何组合.

正确使用自增、自减运算符
如: 若i=3,则表达式(i+ +)+(i+ +)+(i+ +)的结果应为 多少?
有的系统从左到右顺序完成括号中的运算,即表达式经过为 3+4+5=12。
另外一些系统(如Turbo C、MS C)则先计算表达式的值,再 自加3次i,即表达式结果为3+3+3=9。

正确使用自增、自减运算符
对printf(“%d,%d”, i,i+ +);的理解 若 i=3 ,则在Turbo C中对输出函数参数的求值顺序 采用“自右至左” 结果为:4,3(而不是3,3)
不要滥用增量运算符; 增量运算符有副作用,会改变运算分量的值 但是如果使用不当,会带来意想不到的结果.

正确使用自增、自减运算符
1. 对于代码int i = 3; i = i++; 不同编译器给出不同的结果, 有 的为3, 有的为4, 哪个是正确的?
2. 为什么这样的代码: a[i] = i++; 不能工作?
2. 为什么这样的代码: a[i] = i++; 不能工作?
答: 子表达式i++ 有一个副作用—– 它会改变i 的值—– 由于i 在
同一表达式的其它地方被引用, 这会导致无定义的结果, 无 从判断该引用(左边的a[i] 中)是旧值还是新值。

本讲重点
C运算符分类
运算符运算规则 赋值运算符
优先级别和结合性

赋值运算符
变量=表达式
含义:将“=”右边的运算对象之值赋给左边的运算对象。
如:x=1; x=x+1;
使用要点: (1)赋值运算符左边的量(称为左值)一般是变量。 (2)当“=”两边数据类型不同时,将进行数据类型的自动转换,原则是: 以“=”左边运算对象的数据类型为准。
如: int x; float y=3.5;
x=y; 则运行结果为int型

赋值表达式

求解过程:
赋值运算符按照“右结合性”顺序运算,将“=”
右边表达式的值赋值给左边的变量。

使用举例: a=b=c=3 a=5+(c=2) a=(b=4)+(c=6) a=(b=10)/(c=2) a+=a-=a*a

?表达式值为3,a,b,c值均为3 ?表达式值为7,a值为7,c为2 ?表达式值为10,a=10,b=4,c=6 ?表达式值为5,a=5,b=10,c=2 ?若a=12,(1)则a-=a*a 后,a=132,(2)a+=-132后,a=-264

赋值表达式
注意: (1)区分赋值语句和赋值表达式; (2)赋值表达式不仅可以出现在赋值语句中,也可以出现在 其它语句中。 (3)赋值运算符的优先级别今比逗号运算符级别高,低于其 他运算符。 (4)赋值表达式的值等于右边表达式的值。

赋值运算时不同类型数据间的自动转换
1、实型数据赋值给整型数据时,舍弃小数部分;
即:int=float的结果为int型。 如:float a;
int s; a=12.34; s=a; 这时s的值为12。
2、将整型数据赋值给实型变量时,数值不变,但数据是浮点形式的;
即float=int的结果为float型。 如:int s;
float a; s=12; a=s; 这时a的值为12.00000。

赋值运算时不同类型数据间的自动转换

3、当字符数据赋值给整型变量时,则将字符数据放到整型变量的低8位中,
高8位数根据的存放数据有两种情况:

即: int=char
– 当char为无符号或unsigned char时,高8位应补0;

如:unsigned char c; int x;

11111110

c=‘\376’;

(八进制数376)

x=c; 则x的值为254。

00000000 11111110

– 当char为有符号数据时,高8位需进行“符号位扩展”,即高8位 将依据符号位的值来决定是补0或补1;

如:char c; int x;

11111110

c=‘\376’;

(八进制数376)

x=c; 则x的值为-2。

11111111 11111110

赋值运算时不同类型数据间的自动转换

4、将带符号的整型数据赋值给长整型数据时,要进行符号扩展。如果int
型数据为正值,则long int 型数据的高16位补0;如果int型数据为负 值,则long int 型数据的高16位补1,以保持其原有数据不变。

5、将 long int 型数据赋值给int型数据时,只将long int 型数据的低16 位原封不动的送到int 型变量中去(截断)。

6、将unsigned int型数据赋值给long int型数据时,不存在符号扩展问 题,只需将高位补0;将unsigned int型数据赋值给 int型数据时,有 可能出现错误数据。

如: int a; unsigned b=65535;

1111 1111 1111 1111

a=b;

printf(“%d\n”,a); 此时a的值为-1。

1111 1111 1111 1111

复合赋值运算符
在赋值运算符“=”之前加上其它运算符构成的运算符。
表达式1 运算符=表达式2 等价于:表达式1=表达式1 运算符 (表达式2)
a+=3 等价于 a=a+3
–x*=3 等价于 x=x*3 –x%=3 等价于 x=x%3 –x/=y+3 等价于 x=x/(y+3)
使用要点
–凡是二元(二目)运算符,都可以与“=”组合成复合赋值符 如:+=,-=,*=,/=,%=,<<=,>>=,&=,^=,|=等。
–使用复合赋值符的目的:简化程序;提高编译效率。

本讲重点
C运算符分类
运算符运算规则 关系运算符
优先级别和结合性

关系运算符

? 关系运算符用于判断各个运算对象之间的相互关系

? 符号类型:<、>、<=、>=、==、!=

? 优先级:

– <、>、<=、>=的优先级相同,而= =、!=优先级相同,且前者高于 后者;

– 关系运算符的优先级低于算术运算符,高于赋值运算符。

? 例:

– c>a+b 等价于 c>(a+b)

算术运算符



– a>b!=c 等价于 (a>b)!=c

– a= =b<c 等价于 a= =(b<c)

– a=b>c 等价于 a=(b>c)

关系运算符



关系表达式
用关系运算符将两个表达式连接起来的式子(连接的 表达式可以是算术表达式也可以是关系表达式、逻 辑表达式、赋值表达式、字符表达式) 例如:a>b、 a+b>c-d、(a=3)>(b=5)、’a’<‘b’、
(a>b)>(b<c)等

关系表达式
? 关系表达式的值为一个逻辑值,即只有“真”和“假”两种 状态.
? C语言中没有逻辑型数据,借用数值表示。C语言规定,对 于关系表达式的结果分别用1、0表示“真”、“假”。 关 系表达式条件成立(值为真),则表达式的值为真(1), 否则为假(0)。
例如:(1)已知a=12,b=20;则表达式a>b的值为“0”; 而a<b的值为“1”.
(2)若a=1,b=3,c=0;则表达式a+b>c的值为“1”; 表达式c=a>b的值为“0”; 表达式a!=b+c的值为“1”。
? C语言识别表达式是否成立的方法是:所有值为“0”的表达 式表示“假”,所有值为“非零” 的表达式都表示“真”。

关系表达式

/*L3-3.C:*/

#include <stdio.h>

int main(void)

{

int a,b,c;

a=b=c=10;

a=1,b=10,c=10 a=1,b=20,c=11 a=0,b=20,c=11

a=b== c;

printf(“a=%d,b=%d,c=%d\n”,a,b,c);

a==(b=c++*2);

printf(“a=%d,b=%d,c=%d\n”,a,b,c);

a=b>c>=100;

printf(“a=%d,b=%d,c=%d\n”,a,b,c);

return 0;

}

本讲重点
C运算符分类
运算符运算规则 逻辑运算符
优先级别和结合性

逻辑运算符

1、含义:逻辑运算符用于完成逻辑(布尔)运算。

2、符号类型:&&(逻辑与)、||(逻辑或)、!(逻辑非)

3、优先级:!优先级别高于&&和||,而&&又高于||。

4、使用要点

在C语言中,没有逻辑型的数据,以“1”代表“真”,以“0”代表

“假”。

逻辑运算真值表

逻辑运算规则:

ab

&& 参与运算的表达式同时为真,1 1

则&&运算的结果为真;

10

|| 参与运算的表达式其中之一

01

为真,则||运算的结果为真; 0 0

a&&b 1 0 0 0

a| |b 1 1 1 0

! 为单目运算符,取运算对象的相反值。

逻辑运算——短路原则
a && b 当a为0时,可提前计算表达式结果为0,因此不在 计算b。

例如,设变量int m,n,a,b的值均为0,则执行表达式 (m=a>=b)||(n=a>=b)后,m, n 的值分别为( ( )。

)和

a || b 当a为1时,可提前计算表达式结果为0,因此不在计
算b。

逻辑运算符

/*L3-4.C: 判断一年是否是闰年*/

/*分析:如果年号能被4整除而不能被100整除,或者能被400整除就是闰年;

否则就是平年。*/

Input your year:

#include <stdio.h>
1944
int main(void)

{

int year,leap;

1944 is a leap year.

printf(“Input your year:\n”);

scanf(“%d”,&year);

leap=year%4==0&&year%100!=0||year%400==0;

if (leap)

printf(“%d is a leap year.\n”,year);

else

printf(“%d is not a leap year.\n”,year);

return 0;

}

本讲重点
C运算符分类
运算符运算规则 条件运算符
优先级别和结合性

条件运算符
表达式1?表达式2:表达式3
条件运算符的执行顺序 先求表达式1,若为真则求解表达式2,整个表达式的值为表达式2的值;若 表达式1的值为假则求解表达式3,整个表达式的值为表达式3的值.
条件运算符的优先级别高于赋值运算符,但低于其他运算符。
条件表达式中表达式1的类型可以与表达式2和表达式3的类型不一致.表达式 2与表达式3的类型也可以不一致.

条件运算符
/*L3-5.c: 条件运算符范例*/ #include <stdio.h> int main(void) { float x=1.0;
int a=2,b=3; x=(a>b)?a:b; printf(“%.4f”,x); return 0; }
3.0000
条件表达式(a>b)?a:b的值为整型数据,但x为实型数据,所以输出为实型数据.

条件运算符

/*L3-6.C:*/

#include <stdio.h>

(1)2

int main(void) { int a,b,c;
a=b=c=1; a+=b;

(2)3 CC a=2,b=2,c=4

b+=c;

c+=a;

printf(“(1)%d\n”,a>b?a:b);

printf(“(2)%d\n”,a>c?a--:c++);

(a>=b>=c)?printf(“AA”):printf(“CC”);

printf(“\na=%d,b=%d,c=%d\n”,a,b,c);

return 0;

}

条件运算符

例3.7:计算下面的函数 sign(x)=

1 x>0 0 x=0 –1 x<0

#include <stdio.h> int main(void) { float x;
scanf(“%f”,&x); printf(“sign(%f) is %d”,x,x > 0 ? 1 : ( x = = 0 ? 0 : –1)); return 0; }

本讲重点
C运算符分类
运算符运算规则 位运算符
优先级别和结合性

位运算符-位逻辑运算符
1 组成:&(按位与) |(按位或) ~(按位反) ^(按位异或)
2 运算规则:位逻辑运算是按二进制一位一位进行运算,相邻位之间没有进位和借位等问题。 &、|和~运算符的运算规则与逻辑运算符的规则类似。
^(按位异或)可看作按位加,不产生进位。
&|^ 00000 0101 1 1001 1 1 1 1 10
3 优先级别:~优先级别最高,其余3个优先级别依次为 & 高于 ^ 高于 |
但3个都高于逻辑运算符,低于关系运算符。

位运算符-位逻辑运算符

例:如果m为0x137f,n为0xf731,则m和n在16位计算机内的二进制表示形式如下:

m

0001 0011 0111 1111

n

1111 0111 0011 0001

___________________________________________________________

4 与逻m&辑n=运算符区别0:0 0 1 0 0 1 1 0 0 1 1 0 0 0 1=0x1331 位m逻|n辑= 运算符是针1 对1 二1 进1 制0位1,1而1逻辑0 运1 算1 符1 是1针1对1整1个=0表xf达77式f 。 位m逻^n辑= 表达式计算1 出1 来1 的0 结0果1有0具0体数0 值1 ,0 而0 逻1辑1表1达0式=0结xe果44只e 有“真”和 “~假m=”两个取值。1 1 1 0 1 1 0 0 1 0 0 0 0 0 0 0=0xec80
如果位是逻32辑位运机算,符~m&的、结|和果^是的不两同个的运,算请分同量学是们可考以虑交应换当的是,多但少逻?辑运算符&&和||的 运算分量是不能交换的。
例: 4&6 结果为 4 4&&6 结果为 1 4|6 结果为 6 4||6 结果为 1 4&8 结果为 0 4&&8 结果为 1 4|8 结果为 12 4||8 结果为 1

位运算符-位逻辑运算符

^

使特定位翻转

例如, 假设变量a的取值为0x7a,则表达式a^017的结果的低4位和变

量a的低4位正好相反。

017

0000 0000 0000 1111

a

0000 0000 0111 1010

__________________________________________________

a^017= 0 0 0 0 0 0 0 0 0 1 1 1 0 1 0 1

与0异或,结果保持原值不变 使用下面3个语句可交换两个变量取值

a=a^b; b=b^a; a=a^b;

b^a=b^(a^b)=b^a^b=a^b^b=a a^b=a^b^a=a^a^b=b

位运算符-位逻辑运算符
? 5、 位逻辑运算符特殊用法: –& 取某个数的指定位(保留指定位) 例如, 0377表示成二进制为 0 000 000 011 111 111 那么表达式a&0377 结果为变量a的低8位。(也可看成a 的高8位清0)。 指定位清0 –| 将某个数指定位置1 例如,017表示成二进制为 0 000 000 000 001 111 那么表达式a|017结果为变量a的低4位置1,其余为不变。

位运算符-位逻辑运算符

例,将int型变量a的最低位清0 在16位机器中,可用表达式 a&0177776 在32位机器中,要用表达式 a&037777777776 可见采用以上做法可移植性差,采用~运算符进行改进,可 采用以下表达式
a&~1
理由: ~1在16位机中结果为1111 1111 1111 1110=0177776 ~1在32位机中结果为1111 1111 1111 1111 1111 1111 1111
1110= 037777777776

类似表达式如

a&~077

结果为将变量a的低6位清0

位运算符-移位运算符

1 组成:〈〈 左移

〉〉右移

要求参与运算的两个运算分量是整型数据

2 使用形式:
表达式1<<表达式2

表达式1>>表达式2

3 运算规则:

<<
将“表达式1”的值(二进制形式)向左移动“表达式2”取值所表示的
位数。移出去的高位被舍弃,而右边低位补0。

例如,a=10,表示成二进制数为00001010,那么

a

00001010

a<<2的结果为 0 0 1 0 1 0 0 0 = 40

如果移位后的数据没有产生数据溢出,则左移n位相当与被移对象乘 以2n。

位运算符-移位运算符

>>运算规则:

将“表达式1”的值(二进制形式)向右移动“表达式2”取值所表示的

位数。移出去的低位被舍弃。

例如,a=10,表示成二进制数为00001010,那么

a

00001010

a>>2的结果为 0 0 0 0 0 0 1 0 = 2

右移一位表示除以2,右移n位相当于被移对象除以2n.

? 在右移时,要注意的是对于无符号数,右移后左边高位补0。这种 移位方式称为“逻辑移位”。

? 对于有符号数,如果移位对象是正数,左边高位补0;如果移位对 象是负数,则左边高位补1(即与补符号位相同的数),这种移位方式 称为“算术移位”。

? 注意,有些系统采用逻辑移位方式,而另外一些系统采用算术移位 方式。Turbo C采用算术移位。

位运算符-移位运算符

3 运算规则:

例如,a=0113755,则

a

1 001 011

如果系统采用逻辑移位,则

a>>1的结果为 0 1 0 0 1 0 1

如果系统采用算术移位,则

a>>1的结果为 1 1 0 0 1 0 1

111 101 101 111 110 110 111 110 110

请同学们在使用右移运算符时注意留意你所使用的系统处理的方法。

?优先级别: 移位运算符的优先级别低于算术运算符,高于关系运算符。

本讲重点
C运算符分类
运算符运算规则 逗号运算符
优先级别和结合性

逗号运算符
表达式1,表达式2 表达式1,表达式2,表达式3,………,表达式n
?含义:用于分隔各个表达式,最后一个表达式的值代表整个表达式的值
?如:a=1,a+2 ? a=3,a+3,a+10,a=a+20,a+1

从左至右依次计算各个表达式的的值,最后一个表达式的值即

为整个表达式的值。

例:1)a=3*5,a*4

结果为60

2)(a=3*5,a*4),a+5 结果为20

?

“顺序求值运算符”

逗号运算符
?使用要点 优先级在所有运算符中为最低。
如: x=(a=3,6*a) 结果为 x=18 x=a=3,6*a 结果为 18 (x=3)
并非任何地方出现的“,”都是作为运算符使用的。
如: printf(“%d,%d,%d”,a,b,c); 即函数参数间的“,”只作为分隔符。

本讲重点
C运算符分类
运算符运算规则 其他运算符
优先级别和结合性

其他运算符
1 & 取地址运算符(单目) * 间接访问运算符(单目) 例如 int a,*p; p=&a; 把变量a在内存单元中的地址赋给指针变量p。 例如, scanf(“%d”,&a);
2 强制类型运算符 使用形式 (类型名)表达式 例如,假设变量a为int类型,表达式(double)a 的结果为double 类型的。(注 意并没有改变变量a的类型)

其他运算符

3 sizeof() 用于计算变量或者某种类型的数据在计算机内部表示所占用的字节数。 例如,

sizeof(int) 在字长16位的机器中,该表达式结果为2。在字长为32位的机器中,该 表达式的结果为4。

4 基本运算符

5

( ) 括号

6

[ ] 下标运算符

7

-> 指向运算符

8

. 成员运算符

9

以上4个运算符优先级别是所有运算符中最高的。

本讲重点
C运算符分类 运算符运算规则 优先级别和结合性

各种运算符的结合性
单目运算符、条件运算符、赋值运算符的结合性是 从右到左。其余运算符的结合性均为从左到右。

各种运算符的优先级

基本运算符



单目运算符

算术运算符(先乘除,后加减)

移位运算符

关系运算符

逻辑运算符(!除外)

条件运算符

赋值运算符



逗号运算符

THE END

更多精品资源请访问
docin/sanshengshiyuan doc88/sanshenglu




友情链接: