第三章 基本数据类型、运算符与输入输出函数
description
Transcript of 第三章 基本数据类型、运算符与输入输出函数
1
第三章 基本数据类型、运算符与输入输出函数
3.1 基本数据类型 3.2 常量 3.3 变量 3.4 C 语言的运算符和表达式 3.5 输入输出函数
2
3.1 基本数据类型
数据类型
基本类型
构造类型
其他类型
整型
带符号
无符号
基本整型( int )
短整型( short int )
长整型( long int )
整型( unsigned int )
短整型( unsigned short int )
长整型( unsigned long int )
字符型( char )
实型(浮点型)
单精度型( float )
双精度型( double )
长双精度型( long double )
枚举类型( enum )
数组类型
结构体类型( struct )
共用体类型( union )
指针类型
空类型( void )
3
3. 2 常量
何谓常量——程序中直接书写的数据; 例如: a=100; b=a+12;
常量类型——以字面形式区分; 例如 : 12 ( 基本整型 ) 3.5 ( 实型 ) 123L ( 长整型 ) 'A' ( 字符型 )
符号常量——用标识符代表一个常量。
4
3.2 常量3.2.1 整型常量整型常量就是整常数,可以用三种进制形式表示:1 . 十 进 制 数 : 以 非 0 数 字 开 头 的 数 。 如 12
3 , -123 等,其每个数字位可以是 0~9 。2 .八进制数:以数字 0 开头的数。如 0123 , -
0123 等,其每个数字位可以是 0~7 。3 .十六进制数:以 0x (或 0X )开头的数。如
0xffff , 0x1111 , -0x123 等,其每个数字位可以是 0 ~ 9 、 A ~ F (或 a ~ f )。
5
3. 整常量类型
int 型常数: - 32768 ~ 32767 视为 int 常数; 可赋给 int 、 long 型变量。
long 型常数: 在 - 2147483648 ~ 2147483647 之内、但超出- 32768 ~ 32767 的数及带后缀 l / L 的视为 long型常数;可赋给 long 型变量。
- 2147483648 - 32768 0 32767 2147483647
long int long
带后缀 l 或 L 的数: long
6
整型量的溢出 若一个变量无法容纳下要存入的数,这种现象称为溢出,溢出将导致数据存储错误;在运算过程中也有可能产生溢出导致运算结果错,因此程序设计中应避免产生溢出。
例: int a, b; a=65538; b=123*456; printf("a=%d, b=%d", a, b); a=2, b=-9448 ( 溢出的错误结果 ) YS
7
溢出原因:
1) a=65538;
65538=(1 0000 0000 0000 0010 )2
a: 只存入后 16 位
2) b=123*456;
123×456=56088=( 1101 1011 0001 1000 )2
b:
-9448 的补码
0000 0000 0000 0020
1101 1011 0001 1000
8
解决办法:
long a, b; a=65538; b=123*456; /* 计算结果有溢出 */ printf("a=%ld, b=%ld", a, b); a=65538, b=-9448 ( 仍有错 )
long a, b; a=65536; b=123L*456; printf("a=%ld, b=%ld", a, b); a=65536, b=56088 ( 正确 )
9
3.2 常量(续)3.2.2 实型常量实型常量在 C 语言中又称为实数或浮点数。在 C 语言中,
实数只采用十进制。它有两种表示形式:1 .十进制形式。这种形式的数由整数部分、小数点和小
数部分组成(注意必须有小数点)。如: 1.24 , 0.345 , .222 , 234.0 , 333. , 0.0 等。
2 .指数形式。这种形式由三部分组成:实数部分、字母E 或 e 和整数部分。象 123x1022 可以表示为 123E22 或123e22 。要注意,字母 E 或 e 之前必须有数字,之后的数字必须为整数。如 e3 、 2.1e3.5 、 2.7e 、 e 等都不是合法的指数形式。
10
【例】 123.0 0.123 -14.2 0.0 0. .123
【例】表示 12 亿 3 千万数学方式—— 1230000000 或 12.3×108 程序中—— 1230000000.0 ( 小数形式的实常数 ) 12.3e+8 、 1.23e9 、 123e7 ( 指数形式 )
11
指数形式说明:
12.3 e+8
指数部分 数值部分
指数部分: e 表示以 10 为底,可大 / 小写; 8 为指数值 ( 幂 ), 只能是整数; 指数符号为正可省略;
数值部分 : 可是小数或整数;
12
【例】表示电子质量 0.91×10-30
小数形式: 0.0000 ……0091
指数形式: 0.91e-30 、 0.91E-30 、 91e-32
可见:在程序中表示较大或较小数时,采用指数 形式简洁、不易书写错。注意:1) 一个数可写成多种指数形式,但存储格式一致;2) 指数部分不可单独代表常数; 如表示 108 : e+8 被编译系统理解为变量 e 加
8 ; 正确表示: 1.0e8 、 1e8
13
3.2 常量(续)3.2.3 字符常量C 语言中的字符常量是用单引号 (‘) 括起来的一
个字符。如’ A’ 、’ x’ 、’ D’ 、’ ?’ 、’3’ 、’ X’ 等都是字符常量。
C 语言中还规定有另一类字符常量,它们以 '\' 开头,被称作转义字符,意思是将反斜杠( \ )后面的字符转变成另外的意义。
14
C 特别规定的转义字符:转义形式 含 义 转义形式 含 义
\ n 回车换行 \ a 响铃
\ t 横向跳至标准列 \ \ 右斜杠字符
\ b 回退一列 \ ’ 单引号字符
\ r 回车到行首 \ ” 单引号字符
转义形式 含 义\ ddd 用字符的 8 进制 ASCII 码值代表字符;
ddd:1 ~ 3 位 ; 取值 0 ~ 376(254D); 适于所有字符。
\ xhh hh: 1 ~ 2 位 16 进制字符;取值 0 ~ FE, x 小写,字母字符可大 / 小写。适于所有字符。
15
例 : 在程序中表示下列字符
字符 A : 'A' '\101' '\x41' 字符 3: '3' '\63' '\x33' 单引号 : '\'' 空格 : '' '\40' '\x20' 回车换行 : '\n' 不可键入字符≥ : '\362' '\xf2'
例:在程序中表示字符序列 ABC 、 123 "ABC" 、 "123" 构成字符串常量
16
3.2 常量(续)3.2.4 字符串常量字 符串常 量 是 用 双 引 号 括 起 来 的 字 符 序列。
如: "string" 、 "This is my first program!" 。C 语言规定字符串的存储方式为:串中的每个字符(转义字符只能被看成一个字符)按照它们的 ASCII 码值的二进制形式存储在内存中,并在存放串中最后一个字符的位置后面再存入一个字符 '\0' ( ASCII 码值为 0 的字符),这是字符串结束的标志。
17
字符串常量
1) 表示——由一对双引号括起来的字符序列;
”How do you do.” 长度: 14 ”123.456” 长度: 7 ”a” 长度: 1
在程序中表示下列字符串:
x≥y ”x\xf2y” 长度: 3
C:\DOS ”C:\\DOS” 长度: 6
”OK!” ”\”OK!\” ” 长度: 5
18
2) 存储——双引号内每个字符占用一个字节,所有 字符按顺序连续存储,自动在最后加入字串 结束标志:空字符
例: 0010 0000 0000 0000
空字符:名为 NUL 的控制字符 其 ASCII 码值: 0 程序中表示:’ \0 ’
注意:空字符与空格字符是不同的字符。
H o w d o y o u d o . \0
19
3.2 常量(续)3.2.5 符号常量C 语言允许将程序中的常量定义为一个标
识符,称为符号常量。符号常量一般使用大写英文字母表示,以区别于一般用小写字母表示的变量。符号常量在使用前必须先定义,定义的形式是:#define 标识符 常量
20
3.3 变量
变量——用标识符标识且在程序运行过程中允许被改变的量;
C 变量命名( C 标识符)规则: 由大或小写字母、数字、下划线组成,且第一第一个字符必须是字母或下划线个字符必须是字母或下划线。
变量名长度:MS C 有效字符为 8 个,多余部分不予识别;Turbo C 隐含有效字符为 32 个,可自行调整。
21
变量命名举例:合法: sum 、 SUM 、 Average 、 toal 、 cost_1 、_1非法: for 、 num-1 、 2a 、 8L 、 ABC#
注意:1. C 变量名中字母可大小写,但有大小写之分, SUM 、 sum 、 Sum 被视为不同的变量。
2. 有效字符相同的变量名被视为是同一个变量; 如 MS C 中 student_name 与 student_number 。
3. 在实际应用中命名应尽量见名知义。
4. C 中变量必须先定义后引用。
22
与变量有关的概念:
1) 变量三要素:变量名、变量地址、变量值
2) 变量的地址 ( 变量的指针 )
给变量分配的存储单元第一个字节的地址;
例如: int n, m; n=10; m=25;
┇
┇
n 的地址→ 202
m 的地址→ 20410
25
23
3) 变量被赋值的物理意义是向它的存储单元存数;
4) 变量可多次被赋值,新值将覆盖旧值; 例如: n=10; /* 赋值:破坏性的 */ n=45;
5) 变量被引用的物理意义是从它的存储单元中读数; 例如: n=10; m=n+2; /* 引用:非破坏性的 */
6) 两变量内容的交换可借助另一个变量或利用运算 关系实现。
24
510
例如:实现两个变量内容的交换
方法 1 :利用中间变量实现
int a=5, b=10, t; t=a; a=b; b=t;
方法 2 : a=a+b; /*5+10=15a*/ b=a-b; /*15-10=5 b*/ a=a-b; /*15-5=10a*/
10
a
t
b
5
5
25
3.3 变量 (续)3.3.2 整型变量整型变量可分为:基本型、短整型、长整
型和无符号型。无符号型又分为无符号整型、无符号短整型和无符号长整型。
26
整型变量
分类——分为六类类型名称 类型标识符 性质
存储格式
基本整型 int 有符号 补码、高位符号位短整型 short int " "
长整型 long int " "
无符号整型 unsigned int 无符号 全部作为数据位
无符号短整型 unsigned short " "
无符号长整型 unsigned long " "
27
在 Turbo C 中:类型标识符 存储
位表示范围
int 16 bit
- 215 ~ (215 - 1)即- 32768 ~ 32767
short int "
long int或: long
32 bit
- 231 ~ (231 - 1)即- 2147483648 ~ 2147483647
unsigned int 16 bit
0 ~ (216 - 1)即 0 ~ 65535
unsigned short
"
unsigned long
32 bit
0 ~ (232 - 1)即 0 ~ 4294967295
28
3.3 变量 (续)3.3.3 实型变量C 实型变量分单精度( float 型)和双精度
( double 型)两类。
29
实型变量——分为两类;
类型名称 标识符 存储位数
存储格式
数值范围 有效位数
单精度实型 float 32 bit 浮点 ±(10 - 38 ~1038)
7 位
双精度实型 double
64 bit 浮点 ±(10 - 308 ~10308)
15位
30
实型量的舍入误差例: float a, b; a=123456.789e5; /* 赋值产生误差 */ b=a+20; /* 引用误差的 a*/ printf("%f", b); 12345678848.000000 ( 前 7 位有效 )
理论值应为:12345678900.0+20=12345678920.0要精确存储 12345678900.0 需 37bit 尾数;
解决办法: double a, b;
31
3.3 变量 (续)3.3.4 字符型变量字符型变量用来存放单个字符,定义形式
如下:char c1, c2 ;可对 c1 、 c2 赋值, c1='a' ; c2='b' ;注意
不能将字符串常量赋给一个字符变量。
32
字符变量的存储及引用
例: char c1, c2 ; c1=’A’ ; c2=c1;
存储 :
c1:
若: c1 按字符解读——字符 A c1 按整数解读—— +65
0 1 0 0 0 0 0 1
33
3.4.1 算术运算符和算术表达式:
1) 基本算术运算符:
+ 加 / 取正 (双目运算符 / 单目运算符)
- 减 / 取负 (双目运算符 / 单目运算符)
* 乘 (双目运算符)
/ 除 (双目运算符)
% 整除取余 (双目运算符)
3.4 C 语言的运算符和表达式
34
注意:
1) + 、 - 为复用运算符;如: int a, b, c; a=5; b=a-3; /* 减:两个运算目标 */ c=-a; /* 取负:一个运算目标 */
2) 两整数相除结果仍为整数如: 5/2 2 -5/3 -1 1/2 0
要依实际应用情况加以利用或避免。
35
3) 求余运算要求两运算元素均为整型,余数仍 为整型;如: int a, b; a=11%3; /*2 a*/ b=5%a; /*1 b*/
若有 : a=11.0%3; 编译时将视为语法错。
36
2) 算术表达式:
C 表达式——由运算符、括号将运算元素连接起来 的有值的式子。
算术表达式—— 由算术运算符、括号将数值型的运算元素连接起来,其值为数值量的式子。
其中:运算元素可为常量、变量、函数调用等。
如: 28+a sin(1.0)*10+y
37
注意:
1) 为保证表达式运算关系的正确性,需加入必要的括号,并注意括号的层次及配对关系;
2) 乘号不得省略;
3) 应避免整型量相除可能带来的不良影响;
4) 函数调用是以函数的返回值来参与运算的。
38
自增、自减运算符
自增 1 : ++
自减 1 :– –
含义: ++i 前置自增;先自加 1 ,后引用; i++ 后置自增;先引用,后自加 1 ; – –i 前置自减;先自减 1 ,后引用; i– – 后置自减;先引用,后自减 1 ;
意义:可提高执行效率。
优先级 2 级、单目、自右而左
39
注意:1) 只能对变量进行自增、自减运算;
2) ++ 、 -- 、取负同为二级,结合性:自右而左;如: i=3; j= -i++; /* -3j , i: 4 */
3) 自加 / 减作为函数参数时,注意参数求值顺序;如: i=3; printf("%d,%d", i, i++); 4, 3 3, 3
输出顺序
Turbo C 求值顺序
Unix C 求值顺序
40
3.4 C 语言的运算符和表达式 (续)
算术运算符和算术表达式 注意以下几点:⑴ 两个整数相除结果为整数,如 5/3 的结果为 1 。
如果参加运算的两个数中有一个数为实数,则结果是 double 型。
⑵ 模运算符 % ,又称求余运算符,要求 % 两侧均为整型数据,如 7%4 的值为 3 ;而且余数的值符号与被除数一致,如- 7% - 4 的值为- 3 。
⑶ 运算符“ + +” 是操作数加 1 ,而“--”是操作数减 1 ,只适用于变量,不能用于常量或表达式。
413.4 C 语言的运算符和表达式 (续)
3.4.2 赋值运算符和赋值表达式 一、基本赋值运算符 二、复合赋值运算符
42
赋值运算符和赋值表达式
1. 赋值运算符
= 优先级 14 级、双目、自右而左;
2. 赋值表达式
一般形式:变量 = 表达式
其中:表达式——可是 C 任何形式的表达式,包括算术、 条件、逗号、赋值等表达式;特殊形式:单独的常量、变量、函数调用。
43
例: b=20
c=sin(1.0)
d=pow(2, b)/2
e=a>b
a=(b=5)
a=b=c=d=0
c=b=a*2;
a=(b=10)/(c=2)
44
3. 赋值运算时的类型转换
被赋值变量的类型与表达式值的类型一致,直接赋值;不一致系统自动以被赋值变量的类型为准进行转换,然后赋值。
例: int i=10, j; float f; double d; i=i-5; /* 5i */ j=i+3.56; /*8 j */ f=23; /* 单精度 23.0 f */ d=j+f; /* 双精度 31.0 d */
45
注意:赋值时的自动类型转换所造成的误差
例: main( ) { float x, y ; /*double x, y;*/ x=123.456781234; y=x+0.111111111; printf(”X=%f,Y=%f\n”, x,y); } X=123.456779, y=123.567894
x 、 y 改为双精度的结果: x=123.45678123400000,y=123.56789234500000
46
复合赋值运算符
在赋值运算符前加上其它双目运算符构成;
算术复合赋值运算符:
+ = 和赋值 - = 差赋值 * = 积赋值 优先级 14 级、自右而左 / = 商赋值 %= 模赋值
意义:提高编译效率、目标代码的质量。
47
例: a=a+3 a+=3
x=x%3 x%=3
x=x*(y+8) x*=y+8
a=a*b-3 ≠ a*=b-3 a=a*(b-3)
注意:复合赋值运算符针对右边整个表达式。
例: a=6; a+=a*=a-1; /*60 a*/
48
3.4.3 关系运算符和关系表达式
1. 关系运算符 ( 比较运算符 )
六个: < 小于
<= 小于或等于
> 大于
>= 大于或等于
== 等于
!= 不等于
6 级、双目、自左而右
7 级、双目、自左而右
49
2. 关系表达式
一般形式: < 表达式 1> < 关系运算符 > < 表达式2 >
表达式 1 、 2 的形式:算术、赋值、逗号、关系等任
何 C 合法的表达式。
关系表达式的值:逻辑值真、假
真——对应关系式成立,用整型量 1 代表; 假——对应关系式不成立,用整型量 0 代表;
关系表达式的位置: C 任何允许使用表达式的位置。
50
如: if (a<0) a=-a; 控制语句表示条件的位置 printf("%d", a>10); 作为函数的参数 k=m!=1 赋值表达式的右边 c=c+(g>=60) 表达式的一个运算元素
举例:说明下列关系式的含义1) i<=52) a+b>sqrt(c)3) a%2==04) (c=getchar( ))=='#' 区分: c=getchar( )=='#'
51
举例:写出下列表达式的值若有定义: int a=3, b=2, c=1; char ch1='a';
1) b+c!=a
2) ch1<'b'
3) a%2==0
4) (a>b)>(b<c)
5) a>b>b<1
6) a>b==c
7) f=a>b>c
0 1 0
1
1
1 0
52
3.4.4 逻辑运算符和逻辑表达式
1. 逻辑运算符
三个:
! 逻辑非—— 2 级、单目、自右而左;
&& 逻辑与—— 11 级、双目、自左而右;
|| 逻辑或—— 12 级、双目、自左而右;
53
2. 逻辑表达式一般形式: 双目: < 表达式 1> < 逻辑运算符 > < 表达式 2 > 单目: ! 表达式 1
表达式 1 、 2 :任何 C 合法的表达式。
逻辑表达式的值:逻辑值真、假 真——条件成立,用整型量 1 代表; 假——条件不成立,用整型量 0 代表;
逻辑运算对象: 0 被视为逻辑量“假”; 非 0 被视为逻辑量“真”。
54
逻辑运算真值表:
a b !a !b a&&b
a||b
1 1 0 0 1 1
1 0 0 1 0 1
0 1 1 0 0 1
0 0 1 1 0 0
55
例:将所给条件写成 C 的逻辑表达式
1) 1≤a ≤8 并且 1 ≤b ≤10
2) a 和 b 都是正的或都是负的 (a 、 b 符号相同 )
3) a 和 b 之一为 0 ,但不能都为 0
4) a 能被 5 或 7 整除
(a>=1&&a<=8)&&(b>=1&&b<=10)
(a>0&&b>0)||(a<0&&b<0) 或: (a*b)>0
(a*b==0)&&(a+b!=0)
(a%5==0)||(a%7==0)
56
注意:
C 在逻辑表达式求解时,并不一定是所有的运算都被执行,当刚开始求解或求解的中途就可以确定整个逻辑表达式的值时,其余的运算将不再进行。
例: a&&b&&c
例: a||b||c
例: a=1, b=2, c=3, d=4, m=n=1; (m=a>b) && (n=c>d)
57
3.4.5 条件运算符和条件表达式
条件运算符 : ? : 13 级、三目、自右而左
条件表达式一般形式 : < 表达式 1> ? < 表达式 2> : < 表达式 3>
其中:各个表达式可以是任何形式的表达式。
求解过程:先求解 e1 ,并对其值进行逻辑判断,为
真则继续求解 e2 ,且 e2 的值作为整个条件表达式的
值;若 e1 为假,则求解 e3 ,且 e3 的值为整个条件表
达式的值。
58
3.4 C 语言的运算符和表达式 (续) 3.4.5 条件运算符和条件表达式
表达式 1
条件表达式取表达式 2 的值
真(非 0 ) 假( 0 )
图 3-2 条件表达式执行过程
条件表达式取表达式 3 的值
59
例: ch=(ch>=’A’&&ch<=’Z’) ? ch+32 : ch ;
例: printf(”%c”, a%5==0 ? ’\n’ : ’ ’ );
例:分段函数 y=
y=x<0 ? –1 : (x==0 ? 0 : 1) ;
-1 x<00 x=01 x>0
60
使用说明:
表达式 2 、 3 值的类型可不同,此时整个条件式值的类型与两者中较高者一致。
例: float x, y; int a=2; scanf(”%f”, &x); y=x>40 ? a : a*0.9
分支条件成立条件表达式值为 2.0 , 条件不成立条件表达式值为 1.8 。
61
3.4 C 语言的运算符和表达式 (续) 3.4.6 逗号运算符和逗号表达式 逗号除了可以作为分隔符使用之外,也可以用
逗号将若干个表达式分开便构成了逗号表达式。其一般形式为:
表达式 1 ,表达式,……,表达式 n 逗号表达式的运算次序为:先求解表达式 1 的
值,再求解表达式 2 的值,最后求解表达式 n的值。逗号表达式的值为表达式 n 的值。
62
例: a=3*5, a*4
例:两个表达式的比较
x=(a=3, 6*3) 18x, a:3 x=a=3, 6*a x:3, 表达式的值为 18
例: a=5, b=3, c=a*b
例:for 循环语句格式: for(e1; e2; e3) 内嵌语句;
for(i=0, j=10; i<10; i++, j++) ~
63
3.4 C 语言的运算符和表达式 (续)3.4.7 指针运算符1 .取地址运算符 & (一元运算符)2 .取值运算符 * (一元运算符)
64
3.4 C 语言的运算符和表达式 (续)3.4.8 sizeof 运算符1 .用于数据类型使用形式: sizeof ( type )数据类型必须用括号括住。如 sizeof ( int )。2 .用于变量 使用形式: sizeof ( var_name )或 sizeof var
_name 变量名可以不用括号括住,但带括号的用法更普
遍。
65
例: sizeof (int) 结果: 2 a=sizeof (double) 8 sizeof (sum) sum 变量的类型长 sizeof (40+25) 2 sizeof(40.0+25) 8 sizeof(123) 2 sizeof(123L) 4 sizeof(123*456) 2
例: char c1; int l1, l2; l1=sizeof (c1); l2=sizeof (”Hello!”) - 1;
66
3.4 C 语言的运算符和表达式 (续) 3.4.9 不同类型数据之间的转换
1 .自动类型转换 2 .强制类型转换
强制类型转换的一般形式为:(类型标识符)(表达式)如 (int)(x+y) 是将 x+y 的结果强制转换成 int 型。
又如 (float)x/y 是将 x 强制转换成 float 型后,再进行运算。
注意:经强制类型转换后,得到的是一个所需类型的中间值,原来变量的类型并没发生变化。
67
3.4 C 语言的运算符和表达式 (续) 3.4.10 C 运算符优先级和结合性 附录 III
68
3.5 输入输出函数 所谓输入输出是以计算机为主机为主体而言的。
从计算机向外部输出设备(如显示屏、打印机、磁盘等)输出数据称为“输出”;从输入设备(如键盘、磁盘、光盘、扫描仪等)向计算机输入数据称为“输入”。
C 语言的输入输出功能是由系统提供的库函数实现的。 C 语言本身并没有输入输出语句。
69
数据输入输出的概念及在 C 语言中的实现
编辑
编译
连接
运行
myprg.c
myprg.obj
库函数 obj 代码
myprg.exe
myprg.c
myprg.obj
库函数 obj 代码
myprg.exe
函数库 ( 磁盘文件 ) : 库函数的 obj 代码库函数的 obj 代码
包括:数学库 标准 I/O 库 图形库 等;
磁盘
70
字符数据的输入输出
1. putchar 字符输出函数
调用格式: putchar( 参数 )
参数形式:字符常量 / 变量、整型常量 / 变量;
功能:向系统隐含输出设备 ( 显示器 ) 输出一个字符。
要求:使用文件包含预编译命令 # include <stdio.h> 或: # include ”stdio.h”
71
2. getchar 字符输入函数
调用格式: getchar( )
功能:从系统隐含的输入设备 ( 键盘 ) 输入一个字符。
说明:无参,返回值为输入字符的 ASIIC 码; 是带输入输出缓冲区和回显的函数;
要求:使用文件包含预编译命令 # include <stdio.h>
72
例 1 :输入一个字符并输出 #include ”stdio.h” main( ) { char c; c=getchar( ); putchar(c); putchar(’#’); putchar(’\n’); }
a↙ 输入 a# 输出 _
YS
73
使用说明:1) 利用 getchar 函数可达到暂停效果 ;
例 2 : #include ”stdio.h” main( ) { printf (”15*4=%d\n”, 15*4); printf (”Press Enter key to continue…”); getchar( ); /* 不引用返回值 */ } 15*4=60 输出 Press Enter key to continue… _
YS
74
2) getchar 总是先从缓冲区读字符 , 只有缓冲区空 才会暂停等待新的输入。 例 3: #include ”stdio.h” main( ) { char c1, c2, c3; c1=getchar( ); c2=getchar( ); c3=getchar( ); printf (”%d,%d,%d”, c1, c2, c3); } abcde↙ a↙ 97,98,99 bcd ↙ 97,10,98
YS
75
格式输入与格式输出
1. printf 格式输出函数
调用格式: printf ( 格式控制字符串 [ ,输出项列表 ])
功能:在标准输出设备上,按指定格式对应输出各 个输出项。
参数: 格式控制字符串中可包含格式说明、直接 字符、控制字符; 输出项列出了要输出的对象 ( 可以没有 ) , 多项之间逗号分隔; 形式:常量、变量、表达式、函数调用等。
76
格式说明在个数、顺序、类型上应与输出项对应。
例 : #include ”stdio.h” main( ) { float f=123.456; int a=25, b=5; printf (”\t%d+%d=%d\n”, a, b, a+b); printf (”\t%d,%f\n”, 66, sqrt((float)a) ); }
25+5=30 66,5.000000
YS
77
函数 printf 能够实现如下输出格式化功能:
1) 指定任何类型数据输出的域宽;
2) 指定输出在域宽内左对齐或右对齐;
3) 插入要输出的直接字符;
4) 以 8 进制或 16 进制输出整型量的存储镜像;
5) 指定实型数以小数或指数形式输出;
6) 指定实型数的输出小数位数;
7) 通过控制字符 \t 、 \n 、 \b 等定位输出列。
78
printf 函数格式说明的一般形式:
% [ 附加格式说明 ] 格式字符 d 、 o 、 x 、 u 、 c 、 s 、 f 、e 、 g
l 用于长整型 m n - 指明左对齐方式,隐含右对齐。
正整常数,指明输出所占列宽
79
一、整型量的格式说明
适用于整型的常量、变量、表达式、函数。
1) 按数据的实宽输出
说明: 8 进制、 16 进制按存储镜像输出。
输出形式输出对象 10 进制 8 进制 16 进制
int 型 %d %o %x
long 型 %ld %lo %lx
80
2) 指定输出列宽和对齐方式
说明:
若 m < 输出数据的实长, m失效,按实长输出。
以八、十六进制输出时,将整数的符号位也视作 数据位,即不可能输出负的八、十六进制数。
输出对象 格式说明 总列宽 对齐方式 输出形式
int 型%md m列 右对齐、左补空 十进制% - mx m 列 左对齐、右补空 十六进制
long 型 %mld m 列 右对齐、左补空 十进制
81
例: main( ) { int a=-15, b=12345; long x=987654321; printf (”\n%d,%8d,%ld”, a, b, x); printf (”\n%-6d,%4d,$%12ld”, a, b, x); printf (”\n%8x%8o%12lX”, a, a, x); }
-15,12345,987654321 -15,12345,$987654321 fff11777613ADE68B1
YS
82
二、无符号整型量格式说明
1) 按数据的实宽输出
说明: 8 进制、 16 进制按存储形式输出。
2) 指定列宽和对齐方式(含义同上)
输出形式输出对象 10 进制 8 进制 16 进制unsigned int 型 %u %o %x
unsigned long型
%lu %lo %lx
83
例:
main( ) { unsigned int a=65535 ; /* a : FFFFH */ int i=-2; /*i: FFFEH*/ printf (”%8X,% - 8u,%d,%u\n”, a, a, a, i); }
FFFF,65535,-1,65534
说明: %d 将无符号整型量按补码格式解读; %u 将整型量按无符号格式解读。
84
三、字符量格式说明
例如: main( ) { char ch1= ’a’; int i = 98; printf (”%c,%5c,%c”, ch1, i, 99 ) ; } a, b, c
输出对象 格式说明 输出形式char 型 %c 字符int 、 long 型 (0 ~ 254)
%c 字符
85
四、字符串格式说明
1) 按实长输出字符串
2) 指定宽度和对齐方式
%ms 、 % - ms
输出对象 格式说明 输出形式字符串常量 %s 字符串字符数组名 %s 字符串
86
3) 截取字符串中的部分字符输出
%m.ns—— 按m列宽输出前 n 个字符,右对齐 ;
% - m.ns—— 按m列宽输出前 n 个字符,左对齐 ;
%.ns—— 截取前 n 个字符并按截取宽度 n 输出。
例: main( ) { printf (”%s,%7.2s,%-5.3sEND”, ”CHINA”, ”CHINA”, ”CHINA”); }
CHINA, CH,CHIEND
87
五、实型量格式说明
适用于实型的常量、变量、表达式、函数。
1) 按系统隐含的宽度输出 (TC 环境 )
%g :自学
输出对象 格式说明 输出形式 有效位数
float 型 /double型
%f小数:整数部分全部输出,小数输出 6 位。
前 7 位 /前 16 位
%e标准指数:数字部分小数点前必有一位且只能有一位非零数字。
数字部分小数 5 位 , 指数部分 4-5位。
88
2) 指定宽度和对齐方式
%m .nf ——m :总列宽, n :小数位数,自动四 舍五入,右对齐。
%m .ne ——m :总列宽, n :数字部分的小数位 数 ( 包括小数点 ) ,自动四舍五入。
对齐方式:与上述方法和含义相同。
89
例: main( ) { float f1, f2 ; f1=123.456; f2=123.45678; printf(”%f,%-12f,%10.2f\n%.2f,%-10.2f\n”, f1, f1, f1, f1, f1 ); printf(”%e,%e,%15.8e\n” , f1 , f2 , f2 ); }
123.456001,123.456001, 123.46 123.46,123.46 1.23456e+02,1.23457e+02,1.2345678e+02
90
例: main( ) { double d1, d2 ;
d1=2222222222222.222222222; /* 13 : 9*/
d2=123.4567e128;
printf (” %f,%e\n”, d1, d2);
}
2222222222222.222170,1.23457e+130
91
使用格式输出函数 printf 的说明:
1) 格式说明在个数上、顺序上、类型上必须与输出 项对应一致,否则,编译时不做匹配性检查,编 译可通过,但输出结果错。
2) 格式字符 x 、 e 可小写或大写 %X :十六进制字母字符大写,如 3AF ; %E : 1.23457E+130
其余格式字符 d 、 o 、 u 、 c 、 s 、 f 只能小写。
3) 串中直接字符 \ 、 % 、” 的表示: \\ %% \”
92
2. scanf 格式输入函数
调用格式: scanf( 格式控制字符串,地址项表 )
功能:按格式控制字符串中指定的格式,从键盘输 入常数,并存入对应变量的地址中。
参数:格式控制字符串中可包含格式说明、直接 字符;注意:不要使用控制字符;
地址项是要获得数据的变量地址,多个输 入项间逗号分隔;
变量地址: & 变量名 ( 地址运算符 & : 2 级、单目 )
93
例: main( ) { int a, b; long m, n; printf(”Enter a, b:”); scanf(”%d,%d”, &a, &b); printf(”a+b=%d\n”, a+b); printf(”Enter m n:”); scanf(”%ld%ld”, &m, &n); printf(”m*n=%ld\n”, m*n); }
Enter a, b:12, 6↙ a+b=18 Enter m n:500 900 ↙ m*n=450000
94
格式输入函数 scanf 的格式说明:
%[ 附加格式说明 ] 格式符
m 正整数,指定输入数据的宽度;
* 抑制符,跳过某输入项或指定列。
95
输入项变量类型
格式说明 输 入 数 据 的 形式
int 型
%d
%o
%x
%c
十进制整常数
八进制整常数 ( 不需以 0 开头 )
十六进制整常数 ( 不需以 0x 开头 )
一个可键入字符 ( 不需加单引号 )
char 型%c
%d
一个可键入字符 ( 不需加单引号 )
0 ~ 255 整常数
96
输入项变量类型
格式说明 输 入 数 据 的 形式
long 型%ld%lo%lx
十进制整常数八进制整常数十六进制整常数
float 型%f%e
小数形式实常数或整常数指数形式实常数
double 型%lf%le
小数形式实常数或整常数指数形式实常数
97
输入项变量类型 格式说明 输 入 数 据 的 形式
字符数组名 %s 字符串 ( 不需加双引号)
unsigned 型%u%o %x
十进制正整常数八进制正整常数十六进制正整常数
unsigned long
型
%lu%lo %lx
十进制正整常数八进制正整常数十六进制正整常数
98
scanf 的使用说明 :
1) 输入的常数、格式说明、输入变量三者在个数 上、 类型上、顺序上必须对应一致;特例:对实型变量可输入整数形式。如: float x, y; scanf("%f%f", &x, &y); 1.23 52↙
2) 当格式说明之间无其它字符,系统隐含要求以一 个或多个空格作为输入数据间的分隔;如: scanf (”%d%d%d”, &a, &b, &c); 3 4 5↙
99
3) 可用直接字符来指定输入数据的分隔符,而在 输入时必须与指定的一致,否则获值错乱 ;
如: scanf (”%d,%d,%d” , &a, &b, &c ); 3 , 4 , 5↙
4) 格式串中指定的所有直接字符,必须按顺序和对 应位置输入它们; 如: scanf (”a=%d,b=%d,c=%d”, &a, &b, &c ); a=3 , b=4 , c=5↙
注意:输入是在运行过程中进行的,若输入时违背了以上规则,变量获值将发生混乱,并导致结果错。
100
例: main( ) { int a, b, c; long l1, l2; printf("Enter a,b,c:"); scanf("%d,%d,%d", &a, &b, &c); printf("\ta=%d,b=%d,c=%d\n", a, b, c); printf("Enter l1, l2:"); scanf("%d,%d", &l1, &l2); /* 应为 %ld*/ printf("l1=%d,l1=%d\n", l1, l2); } Enter a,b,c: 123↙ ( 分隔符不一致 ) ┇
YS
101
5) scanf 是带输入缓冲区的函数,输入时以回车符 提交数据到缓冲区, scanf 直接在缓冲区读取。
若已输入数据个数少于要求个数,还会出现等待;如: scanf(”%d%d%d”, &a, &b, &c); 3 ↙ 4 ↙ 5 ↙
而多于要求个数的输入仍保留在缓冲区不采纳;如: scanf(”%d%d%d”, &a, &b, &c); 3 4 5 6 7↙
102
6) 用 %c 格式时,每个输入的字符都是有效的。
如: scanf(”%c%c%c”, &c1, &c2, &c3);
abc ↙ 结果: a→c1, b→c2, c→c3
a b c ↙ a→c1, 空格→ c2, b→c3
’a’ ’b’ ’c’ ↙ ’→c1, a→c2, ’→c3
103
7) 按指定列宽截取数据通常针对一个数字串;
如: scanf(”%3d%3d%4d”, &qh, &jh, &xh);
0298487402↙ 结果: 29→qh 848→jh 7402→xh
6) 使用抑制符 '*' 可以跳过 ( 废弃 ) 一个数据项
如: scanf(”%3d%*3d%4d”, &qh, &xh);
0298487402↙ 结果: 29→qh 7402→xh
104
8) scanf 中 %f 格式不能指定精度: %7.2f 是错误的。
9) scanf 格式控制串中若包含控制字符将造成麻烦
如: scanf(”%d,%d\n”, &a, &b); 4,5↙ _ 将继续等待
10) scanf 函数返回成功获值的个数如: n= scanf(”%d,%d,%d”, &a, &b, &c); 3,4,5↙ 3 n
3 4 5 ↙ 1 n
105
几点忠告 不要拘泥于细节 不要死记硬背 在使用中慢慢掌握
106
本 章 结 束