C语言程序设计
2002 年第二章 基本数据类型和运算
2.3.7 赋值运算赋值运算符 ( 11个 ):
简单赋值运算符,=
复合赋值运算符,+= -= *= /= %=
&= |= ^= <<= >>=
优先级,仅高于逗号运算符,
赋值表达式的形式,
e1=e2 或 e1 op=e2
操作数,e1必须为左值表达式。 e1和 e2可为不同的基本类型。
例,a=c+d s[3]=10
而 a*b=c 是错误的。
类型转换:
计算 e2时遵循一般表达式的规则。
计算 e1时不执行任何类型转换。 (不需要整数提升)
赋值时候将 e2结果类型转换为 e1的类型( 赋值转换 )。
运算结果,赋值后的 e1的值和类型。
简单赋值运算符,
例,int x; char ch; short c1,c2;
x=100 值为 100,类型为 int (无类型转换)
x=123.6 值为 123,类型为 int ( double?int)
x=?a? 值为 97,类型为 int (整数提升 char?int)
x=?a?<?b? 值为 1,类型为 int (整数提升、无赋值转换)
ch=100 值为 100,类型为 char ( int?char)
printf(“%d”,ch=128); 的输出为- 128
c1=x 值由 x决定,类型为 short ( int?short)
c1=c2=1 值为 1,类型为 short ( int?short)
c1

c2

表达式的值
1
c1

c2
1
c1
1
c2
1


复合赋值运算符,
int i,j;
i+=1; 与 i=i+1(及 ++ i)等价,与 i++不等价 ;
i<<=j 与 i=i<<j 等价 ;
i/=j+2 与 i= i/(j+2) 等价 ;
i%=j*2 与 i= i%(j*2) 等价 ;
注意,复合赋值表达式与其展开式不一定等价:
int i=0; int s[10];
s[0]=10;
s[i++]+=1; 与 s[i++]= s[i++] +1 不等价 ;
2.3.8 条件运算问号运算符,(?,) 唯一的三目运算符。
问号表达式,e1? e2,e3
e1 必须为基本类型或指针,可求出 0或非 0值。
e2和 e3为基本类型时,可分别为不同基本类型。
e2和 e3为结构、联合类型时,必须为相同类型。。。。
e1
计算 e2
以 e2的值为结果计算 e2
以 e2的值为结果运算符的功能:
运算结果,根据 e1决定取 e2或 e3的值作为表达式式的值。
当 e2和 e3的类型不同时,则转换成同类型。
运算结果只有一种类型,即转换后的类型非 0 0
例 1,int i=0; unsigned j=1;
i? i++,i+j 结果为 1,类型为 unsigned,i的值未变。
i+1? i++,i+j 结果为 0,类型为 unsigned,i的值为 1。
例 2,求变量 a,b中较大的一个。
a>b? a,b
例 3:若字符 ch为小写字母,改成大写字母,否则不变。
ch=(ch>=?a? && ch<=?z?)? (ch-?a?+?A?),ch
ch=(ch>=?a? && ch<=?z?)? (ch-32),ch
例 4:结合性,从右至左,优先级别仅高于赋值和逗号。
(a>0)? 1,((a<0)? –1,0)
(a>0)? 1,(a<0)? –1,0
a>0? 1,a<0? –1,0
等价
2.3.9 顺序求值运算逗号运算符:,
逗号表达式,e1,e2 (或 e1,e2,。。。。,en)
操作数类型,基本类型和指针类型。
运算符功能,先 e1再 e2,e1和 e2间无任何运算,无任何直接联系,但 e1的运算可能产生副作用,影响
e2的计算结果。 无类型转换。
运算结果,取决于最后一表达式。
例 1,1+2,2+3,3+4.0 结果 7.0,类型为 double;
例 2,int a=10,b=20,c;
c=a,a=b,b=c; /*实现 a,b的值互换 */
例 3,int m=0,n=1;
m++ + m++,++n+ ++n,m+++n,m+n
表达式的值取决于最后的 m+n,结果为 6。
2.4 类型转换
C语言的四种转换
① 算术转换 a+b
② 赋值转换 a=b
③ 强制类型转换
④ 函数调用转换 (第五章)
2.4.1 类型转换的规则
1。算术转换
① 无论双目或单目运算符,有 char,short类型时需要 整数提升 。
(char/short)
整数提升
int?unsigned?long?unsigned long?float?double?long double
| 低精度类型 高精度类型 |
② 对双目运算符,按上图自动地进行 隐含转换 ;
12+77.5 结果 89.5 类型为 double (int?double)
,整数提升时,若 int不能表示原数据的值,则需提升到
unsigned。
例,unsigned short a; int b;
a+b 16位机的表达式类型为 unsigned int
32位机的表达式类型为 int
,类型转换后,若新类型不能表示原数据的值,则需转换到
unsigned (long)。
例,unsigned int a; long b。
a+b 16位机,2字节的 unsigned int a转换成 4字节 long a;
表达式类型为 long
32位机:首先,4字节的 unsigned int a( 0 ~ 42亿)转换成
4字节 long a ( -21~ 21亿) ; 再 long a 转换成
unsigned long a,最后 long b 转换成 unsigned long b.
表达式类型为 unsigned long
2,赋值转换表达式的结果和类型取决与左值表达式。
可理解为隐含的强制类型转换
3,强制类型转换类型强制符,(类型名)
表达式形式,(类型名)操作数操作数类型,基本类型或指针类型例,int a; float b;
a+x 结果类型为 float
a+(int)x 结果类型为 int
b%(int)b
2.4.2 类型转换方法
整数与整数之间的转换
浮点数与浮点数之间的转换
浮点数与整数之间的转换
1。 整数与整数之间的转换长变短,保留低位,去掉高位;
例,int a=257,b=511 ; char ch;
ch=a; ch的值为 1 257=00000001 00000001
(char)b; 值为 -1 511=00000001 11111111
短变长,高位用 0或符号位扩展;
例,int i=-1; unsigned j=0xffff;
(long) i 11111111 11111111 11111111 11111111
(long) j 00000000 00000000 11111111 11111111
同长度,有符号到无符号时最高为失去符号功能;
无符号到有符号时最高变成符号位。
例,int a=-1; unsigned b;
b=a; b的值为 65535
(int) 65535u 结果为 -1
i的符号位例,-1L<1UL 结果为 0(关系不成立)
(1) 按隐含转换规则 long整数 –1L,
11111111 11111111 11111111 11111111
自动转换成 unsigned long 0xffffffff (4294967295UL),
11111111 11111111 11111111 11111111
(2) 比较 4294967295UL<1UL 结果为 0
2,浮点数与浮点数之间的转换
(1) 高精度向低精度转换超出低精度的表示范围时,产生溢出,结果不确定
(1) 低精度向高精度转换时 值不变。
3,浮点数与整数之间的转换
( 1)浮点数转换成整数
首先,浮点数转换 long,去掉小数部分,超出 long整数的表示范围时,产生溢出,结果不确定;
将 long整数转换成指定类型。
( 1)整数转换成浮点数首先,整数转换成 long整数,再将 long整数转换成指定类型浮点数。
2.5 枚举类型枚举类型是一个整数常量的集合。每个整数常量有一个有意义的标识符。
2.5.1 枚举类型定义格式:
enum [枚举名 ] {标识符 1[=常量表达式 ],。。。,标识符 n[=常量表达式 n]}
例,enum bool {NO,YES};enum bool {NO=0,YES=1};
{}中的部分为 枚举符表,定义了 枚举常量 。
枚举常量 的值取决于常量表达式作为指定值。
缺省常量表达式时依此为本 0,1,2、。。。。
如部分标识符有指定值,其后所有未指定值的标识符按前一标识符的值加 1。
枚举区分符(类型名)
例,enum weekday{SUN,MON,TUE,WED,THU,FRI,SAT};
等价于
enum weekday{MON=1,TUE,WED,THU,FRI,SAT,SUN=0};
注意:
1) 不同的枚举标识符可以有相同的值。
enum status(LOSS=-1,BYE,TIE=0,WIN};
2) 相同作用域的枚举标识符不能重名。枚举相当于常量定义。
main() {
enum weekday{SUN,MON,TUE,WED,THU,FRI,SAT};
enum workday{MON=1,TUE,WED,THU,FRI};
int SUN; }
2.5.2 枚举变量的定义
( 1) 定义枚举类型 时,定义枚举变量;
enum weekday{SUN,MON,TUE,WED,THU,FRI,SAT} day1,day2;
( 2) 先定义枚举类型,后定义枚举变量;
enum weekday{SUN,MON,TUE,WED,THU,FRI,SAT}
enum weekday day1,day2;
( 3) 定义匿名枚举类型
enum {SUN,MON,TUE,WED,THU,FRI,SAT} day1,day2;
枚举变量的使用
( 1)与整数的用法一致,但需要注意值域范围;
( 2)输入与赋值
enum boolean {NO,YES} b1,b2;
b1=0; b1=NO;
scanf(“%d”,&b2); /*只能输入 1,不能输入 YES*/
( 3)输出
printf(“%d”,b1); /*输出为 0,不是 NO*/
if (b1==NO) printf(“NO”):
家庭作业:
P52
(3) (4)
(6) ~ (8)
(10) ~( 13)