You are on page 1of 86

第 2章 数据类型 、运算 符和 表

达式
白 雪 飞
baixf@ustc.edu.cn

中国科学技术大学电子科学与技术系
Dept. of Elec. Sci. & Tech., USTC
Fall, 2003
目 录
 数据类型、常量和变量的定义
 运算符的种类、优先级和结合方向

 表达式的类型和求值

 简单的 C 程序设计及基本输入输出

C语言程序设计 - 第2章 数据类型、运算符和表达式 2


C 的数据类型 (Data Types)
 基本类型
 整型、字符型、浮点型(实型)、枚举类型
 构造类型
 数组类型、结构体类型、共用体类型
 指针类型
 空类型

C语言程序设计 - 第2章 数据类型、运算符和表达式 3


数据类型、常量和变量
 C 的数据结构是以数据类型形式出现的
 由前述数据类型可以构造出更复杂的数

据结构
 C 语言的数据有常量和变量之分

 常量和变量都分别属于某一数据类型

 程序中用到的所有数据都必须指定类型

 本章仅介绍基本数据类型

C语言程序设计 - 第2章 数据类型、运算符和表达式 4


标识符 (Identifier)
 标识符
 变量名、符号常量名、函数名、类型名…
 标识符命名规范
 由字母、数字、下划线 (Underscore, '_') 组成
 第一个字符必须为字母或下划线
 C 语言标识符是大小写敏感的
 标识符的名称一般应具有一定的含义
 不要与 C 语言关键字 (Keywords) 重复
 一般不要使用以下划线开头的标识符

C语言程序设计 - 第2章 数据类型、运算符和表达式 5


标识符示例
 正确的标识符
 student 、 num1 、 _SUM 、 _1_2_3
 MyName 、 myname 、 my_name
 错误的标识符
 room3-1 包含了其他字符(减号)
 2men 以数字开头
 long 与关键字重复
 Mr.Zhu 包含了其他字符(小数点)

C语言程序设计 - 第2章 数据类型、运算符和表达式 6


常量 (Constants)
 常量
 程序运行过程中,其值不能被改变的量
 例如: 12 、 -6.7 、 'a'…
 符号常量 (Symbolic Constants)
 用一个标识符代表的常量
 相当于把标识符用一个常量简单替换下来
 标识符是一个整体,不要试图拆开来替换
 含义清楚,一改全改
 习惯上符号常量名用大写字母

C语言程序设计 - 第2章 数据类型、运算符和表达式 7


常量示例
#define PRICE 30
#define NUM 12
符号常量
void main()
{
... ...
total = NUM * PRICE; => total = 12 * 30;
total2 = 84 * PRICE2;
printf("total=%d", total);
... ...
} 常量 不会被替换
C语言程序设计 - 第2章 数据类型、运算符和表达式 8
变量 (Variables)
 其值可以改变的量称为变量
 变量有一个名字,即标识符

 变量在存储器中占据一定的存储单元

 变量占据存储空间的大小由其类型决定

 变量名表示存储变量的存储单元地址

 程序使用变量名表示这个变量所占据的

存储单元里存储的数据的值
 变量要“先定义,后使用”

C语言程序设计 - 第2章 数据类型、运算符和表达式 9


变量的存储

变量名
a

34 变量值

存储单元 ( 地址 )

C语言程序设计 - 第2章 数据类型、运算符和表达式 10


整型 (Integer)
 整型常量的表示方法
 整型变量

 整型数据在内存中的存放形式
 整型变量的类型
 整型变量的定义
 整型数据的溢出
 整型常量的类型

C语言程序设计 - 第2章 数据类型、运算符和表达式 11


整型常量的表示方法
 十进制 (Decimal)
 例如, 123 、 -456 、 0
 八进制 (Octal)
以0 开头,不得含有 8 或 9
 例如, 0123 、 -0456
 错例, 0138 、 -0912
 十六进制 (Hexadecimal)
 以 0x 或 0X 开头,用 a~f 或 A~F 表示
10~15
 例如, 0x123 、 -0X45 、 0x3AB 、 -
C语言程序设计 - 第2章 数据类型、运算符和表达式 12
整型数据在内存中的存放方式
 二进制形式
 举例, int i=50; /*int 类型占 2 字节
*/
0 0 0 0 0 0 0 0 0 0 1 1 0 0 1 0

高地址字节 低地址字节

 补码 (Complement)
 正数:与原码一致,首位为 0
 负数:绝对值取反加一,首位为 1
 零:各位全为 0
C语言程序设计 - 第2章 数据类型、运算符和表达式 13
补码举例
 举例
 int i=-50; /*int 类型占 2 字节 */
50 的原码 0 0 0 0 0 0 0 0 0 0 1 1 0 0 1 0
取反

1 1 1 1 1 1 1 1 1 1 0 0 1 1 0 1
加一

-50 的补码 1 1 1 1 1 1 1 1 1 1 0 0 1 1 1 0

C语言程序设计 - 第2章 数据类型、运算符和表达式 14


整型变量的分类
 按占用存储空间的大小划分
 基本整型 int
 短整型 short [int]
 长整型 long [int]
 按有无符号划分
 有符号 [signed]
 无符号 unsigned
 上述两种分类方式组合,可得到 6 种类

C语言程序设计 - 第2章 数据类型、运算符和表达式 15
整数的长度
 整数的类型与长度
 short: 占 2 字节( 16bit )
 long: 占 4 字节( 32bit )
 int: 占 2 或 4 字节( 16 或 32bit )
 2Bytes = short ≤ int ≤ long = 4Bytes
 若需要精确的长度,可选用 short 或 long
 举例
 BC3.1: int 长度为 2Bytes
 gcc: int 长度为 4Bytes
C语言程序设计 - 第2章 数据类型、运算符和表达式 16
有符号数与无符号数
 有符号数
 二进制补码表示,首位为符号位
 指定 signed 或缺省情况,即为有符号数
 无符号数
 没有符号位,只能表示非负数
 无符号数类型必须指定为 unsigned
 若把负数赋值给无符号数,则把该负数的补
码当作无符号数进行处理

C语言程序设计 - 第2章 数据类型、运算符和表达式 17


有符号数与无符号数举例
-50 的补码 i,j
void main()
{ 1111111111001110
int i;
/2
unsigned j;
-25 的补码 i/2
i=j=-50; 1111111111100111
i=i/2; /*-25*/
j=j/2; /*32743*/ 32743 的补码 / 原 j/2

} 0111111111100111

C语言程序设计 - 第2章 数据类型、运算符和表达式 18


整型数据的取值范围
长度
类 型 取值范围
(bit)
[signed] short
16 -215 ~ 215-1
[int]
unsigned short
16 0 ~ 216-1
[int]
[signed] int 16 or 32 -215(31) ~ 215(31)-1

unsigned [int] 16 or 32 0 ~ 216(32)-1

[signed] long [int] 32 -231 ~ 231-1

unsigned long [int] 32 0 ~ 232-1

C语言程序设计 - 第2章 数据类型、运算符和表达式 19


整型变量的定义 (Definition)
 定义形式
 int a, b;
 unsigned c;
 long d;
 unsigned short e;
 变量的定义一般放在一个函数开头的声
明部分,关于变量定义的具体内容在以
后相关章节里详细介绍

C语言程序设计 - 第2章 数据类型、运算符和表达式 20


整型变量的定义与使用举例
void main()
{
int a; /* 定义有符号基本整型变量 a*/
unsigned b; /* 定义无符号基本整型变量 b*/
long c; /* 定义有符号长整型变量 c*/

a = -23; /*a 的值为 -23*/


b = 45; /*b 的值为 45*/
c = a + b; /*c 的值为 22*/
}
C语言程序设计 - 第2章 数据类型、运算符和表达式 21
整型数据的溢出 (Overflow)
 溢出
 数据超出了变量能够存储的范围,造成数据
丢失或数值改变等
 举例
32767 的补码
void main() 0111111111111111
{
+1
int a = 32767;
a++; /*32768?*/ 1000000000000000
} -32768 的补码

C语言程序设计 - 第2章 数据类型、运算符和表达式 22


整型常量的类型
 常量的类型后缀 (Suffix)
l、 L 表示常量是一个长整型
 u 、 U 表示常量是一个无符号整型数
 两种后缀可以一起使用
 举例
 123l 长整型常数 123
 456U 无符号整型常数 456
 789ul无符号长整型常数 789
 101Lu无符号长整型常数 101

C语言程序设计 - 第2章 数据类型、运算符和表达式 23


整型常量使用中的类型问题
 对整型变量赋值
 常量的值不要超过变量的取值范围

 直接使用常量
 带有 l 、
L 、 u 、 U 等后缀的整型常量一
般用于函数调用
 不带有后缀的整型常量的类型,是根据其数
值大小所处的范围来确定的

C语言程序设计 - 第2章 数据类型、运算符和表达式 24


浮点型 (Floating Point)
 浮点型常量的表示方法
 浮点型变量

 浮点型数据在内存中的存放形式
 浮点型变量的类型
 浮点型数据的舍入误差
 浮点型常数的类型

C语言程序设计 - 第2章 数据类型、运算符和表达式 25


浮点型常量的表示方法
 十进制小数形式
 由符号、数字和小数点 ( 必须 ) 组成
 整数和小数部分都可省略,但不能同时省略
 举例, 12.3 、 -.
123 、 123. 、 0. 、 .0
 指数形式
 由整数 ( 或小数 ) 、 e( 或 E) 、整数顺序组

 e 或 E 之前必须有数字,之后必须是整数
 举例, 123.4e-5 表示 123.4×10-5
C语言程序设计 - 第2章 数据类型、运算符和表达式 26
规范化指数形式
 规范化指数形式
 类似于“科学计数法”
 e 或 E 之前的小数中,小数点前面有且仅有
一个非零数字
 举例, 123.456
 规范化形式,
1.23456e2 、 1.23456E+002
 非规范化形式,
123.456 、 12.3456e1 、 12345.6e-
2 、 0.123456e3 、 12345600e-5…
C语言程序设计 - 第2章 数据类型、运算符和表达式 27
浮点型数据在内存中的存放方式
 二进制规范化指数形式
 小数部分长度与能表示的精度有关

 指数部分长度与能表示的数值范围有关

1 1 0 1 1 0 0 1 1 0 1 1 0 0 1 0

符号 指数部分 e 小数部分 f
s
v = (−1) (1. f ) × 2
s e

C语言程序设计 - 第2章 数据类型、运算符和表达式 28


几个特殊的数
 无穷大 (Infinition)
 Inf 举例, 1.0/0.0
 -Inf 举例, -1.0/0.0
 NaN (Not a Number)
 NaN 举例, sqrt(-1) /* 开平方 */
 -NaN 举例, -sqrt(-1)
 零 (Zero)
 浮点数用特殊的形式表示零

C语言程序设计 - 第2章 数据类型、运算符和表达式 29


浮点型变量的类型
 分类
 单精度 float
 双精度 double
 长双精度 long double
 长度和取值范围
长度
类 型 有效数字 绝对值范围
(bit)
float 32 6~7 10-37~1038
double 64 15~16 10-307~10308
long double 128 18~19 10-4931~104932

C语言程序设计 - 第2章 数据类型、运算符和表达式 30


浮点型数据的舍入误差
 由于浮点型变量能够表示的有效数字有
限,将有效位以外的数字舍去造成误差
 举例

float a=123456.789e5, b;
b = a + 20; /*b=12345678920?*/
printf("a=%f\nb=%f\n", a, b);

运行结果 > a=12345678848.000000


b=12345678848.000000
 思考: 1.0/3*3=?

C语言程序设计 - 第2章 数据类型、运算符和表达式 31


浮点型常量的类型
 类型后缀
f、 F 表示常量是一个单精度型浮点数
 l 、 L 表示常量是一个长双精度型浮点数
 无任何后缀的浮点型常量视作双精度型
 对浮点型变量赋值
 一个浮点型常量可以赋值给任何类型的浮点
型变量
 根据变量类型截取常量的相应有效数字
 注意防止出现溢出

C语言程序设计 - 第2章 数据类型、运算符和表达式 32


字符型 (Character)
 字符型常量
 字符型变量

 字符型数据在内存中的存放形式

 字符型数据的使用方法

 字符串常量

C语言程序设计 - 第2章 数据类型、运算符和表达式 33


字符型常量
 单引号括起来的一个字符
 举例, 'a' 、 'A' 、 '1' 、 '' 、 '?'…
 错例, 'abc' 、 '' 、 ' 我 '…
 转义字符
 以 '\'开头的特殊字符
 '\ddd' 1 到 3 位 8 进制数 ASCII 码代表的
字符
 '\xhh' 1 到 2 位 16 进制数 ASCII 码代表的
字符
 举例, '\n' 、 '\t' 、 '\
C语言程序设计 - 第2章 数据类型、运算符和表达式 34
字符型变量
 字符型变量只能存放一个字符
 定义与使用

void main()
{
char c1, c2; /* 定义字符型变量 c1 和 c2*/

c1 = 'a'; /*c1 的值为 'a'*/


c2 = '2'; /*c2 的值为 '2'*/
}

C语言程序设计 - 第2章 数据类型、运算符和表达式 35


字符型数据在内存中的存放形式
 一个字符型数据占一个字节的空间
 字符型数据以其 ASCII 码形式存放

c1='a' c1='2'
(ASCII=97) (ASCII=50)

01100001 00110010

 字符型数据的存放形式与只占一个字节
长度的整型数据完全相同

C语言程序设计 - 第2章 数据类型、运算符和表达式 36


字符型数据的使用方法
 可以把字符型数据视作一种长度为 1 字节
的整型数据处理
 当使用字符型数据时,与使用这个字符的
ASCII 码 ( 一个 8 位整数 ) 是完全一样的
 字符型数据的用法与整型数据完全一样,包
括运算、赋值、输入、输出等
 字符型数据使用过程中,同样需要注意溢出
、符号等问题
 是字符还是整数,只有在输出时才有意义

C语言程序设计 - 第2章 数据类型、运算符和表达式 37


字符型数据使用举例
void main()
{
char c;
int i, j;

c = 97; /*c = 'a'*/


i = c + 20;/*i = 117*/
j = '2'; /*j = 50*/
printf("%c, %d\n", c, c); /*a, 97*/
}
C语言程序设计 - 第2章 数据类型、运算符和表达式 38
字符型变量的符号
 字符型变量与整型变量一样,也分为有
符号数与无符号数
 无符号字符

 unsigned
char c;
 举例,表示一个班级的人数 (<256)
 赋值和使用中需要注意的问题,与整型
变量相同

C语言程序设计 - 第2章 数据类型、运算符和表达式 39


字符串 (String) 常量
 表示形式
 一对双引号括起来的字符序列
 引号内可以包括 0 个、 1 个或多个字符
 字符序列中的特殊字符用转义字符表示
 举例, "abc" 、 "a" 、 "" 、 "" 、 " 我
"
举
例, "12.4" 、 "$#*!" 、 "C:\\HOME"
 字符常量和字符串常量是不同类型的数据
 例如, 'a' 与 "a" 是不同的
C语言程序设计 - 第2章 数据类型、运算符和表达式 40
字符串在内存中的存放方式
 在内存中每个字符按顺序存放
 字符串结尾有一个空字符 (ASCII=0,

'\0') 作为字符串结束标志
 字符串结束标志 '\0' 是不能显示的,在

字符串常量中,也不用显式写出来
 举例

 "TEST" 'T' 'E' 'S' 'T' \0 84 69 83 84 00

 "" \0 00

 "a" 'a' \0 97 00

C语言程序设计 - 第2章 数据类型、运算符和表达式 41


变量赋初值 (Initialization)
 在定义变量的同时对变量赋值 ( 初始化 )
 举例

 int a=1;
/* 相当于 int a; a=1;*/
 int a, b=3;

/* 对 b 赋初值, a 没有初值 */
 int b, c, a=b=c=100;

/* 对三个变量赋同样的初值 */
 变量使用前,一般应先对它赋值
C语言程序设计 - 第2章 数据类型、运算符和表达式 42
各类数值型数据间的混合运算
 整型、字符型、浮点型数据可混合运算
 混合运算时,不同类型的数据按照一定

的规则先转换为同一类型,然后再运算
高 double float

long

unsigned

低 int char, short

C语言程序设计 - 第2章 数据类型、运算符和表达式 43


运算符 (Operator)
 运算符的种类
 运算符的优先级

 运算符的结合方向

C语言程序设计 - 第2章 数据类型、运算符和表达式 44


运算符的种类 (1)
 算术运算符 + - * / % ++ --
 关系运算符 > < == >= <= !=
 逻辑运算符 ! && ||
 位运算符 << >> ~ | ^ &
 赋值运算符 = += -= *= /= %=
>>= <<= &= ^= |=
 条件运算符 ?:

C语言程序设计 - 第2章 数据类型、运算符和表达式 45


运算符的种类 (2)
 逗号运算符 ,
 指针运算符 * &
 求字节数运算符 sizeof
 强制类型转换运算符 (type)
 分量运算符 . ->
 下标运算符 []
 其他运算符 ()

C语言程序设计 - 第2章 数据类型、运算符和表达式 46


运算符的优先级 (Precedence)
 优先级
 运算符的运算次序按优先级由高到低执行
 可以用圆括号 ( ) 改变运算符的执行次序
 举例
 a+b*c–d/e

/* 先算乘除,后算加减 */
/* 乘除比加减优先级高 */
 (a+b)*(c-d)/e

/* 先算加减,后算乘除 */
C语言程序设计 - 第2章 数据类型、运算符和表达式 47
运算符的结合方向 (Associativity)
 结合方向
 当一个操作数两侧的运算符优先级相同时,
运算次序按照结合方向的规定进行
 举例
 a+b-c

/*+ 和 - 的结合方向都是从左向右 */
/*b 先与 + 结合计算 a+b ,然后执行减法
*/
 a=b=1

/*= 的结合方向是从右向左,先计算
C语言程序设计 - 第2章 数据类型、运算符和表达式 48
运算符的结合方向规则
 单目运算符的结合方向都是“从右向左

!、 ~ 、 ++ 、 -- 、 +( 正号 ) 、 -( 负号 )
 *( 指针运算符 ) 、 &( 地址运算符 )
 sizeof 、 (type)
 赋值运算符的结合方向是“从右向左”
 三目运算符的结合方向是“从右向左”

 唯一的三目运算符:条件运算符 ?:
 其他运算符的结合方向都是“从左向右
” C语言程序设计 - 第2章 数据类型、运算符和表达式 49
优先级与结合方向总结
 不同优先级的运算符,运算次序按优先
级由高到低执行
 同一优先级的运算符,运算次序按结合

方向的规定执行
 可以使用圆括号 ( ) 明确运算次序

 圆括号 () 具有最高的优先级

C语言程序设计 - 第2章 数据类型、运算符和表达式 50


表达式 (Expression)
 表达式的概念
 表达式的类型

 表达式求值

 算术运算符和算术表达式
 赋值运算符和赋值表达式
 逗号运算符和逗号表达式

C语言程序设计 - 第2章 数据类型、运算符和表达式 51


表达式的概念
 表达式
 用运算符把操作数连接起来,并符合 C 语
言语法规则的式子
 操作数包括常量、变量、函数调用、表达式
 广义上,常量、变量、函数调用也可以看作
属于表达式的范畴
 举例
 a+2.5*b-6/c+'z'-max(x,y)
 !((a<1e-6)&&(b==(c+sqrt(f))))

C语言程序设计 - 第2章 数据类型、运算符和表达式 52


表达式的类型
 表达式的类型
 表达式的值的类型
 取决于操作数的类型以及它们所做的运算
 举例
 a+2.5*b-6/c+'z'

/* 混合类型算术运算,值为 double 类型
*/
 !((a<1e-6)&&(b==(c+sqrt(f))))

/* 逻辑判断的结果是逻辑值 */
/*C 语言用整型表示逻辑类型 */
C语言程序设计 - 第2章 数据类型、运算符和表达式 53
算术运算符 (Arithmetic
Operators)
 基本算术运算符
+ - * / %
 强制类型转换运算符
 ( 类型名 )
 自增、自减运算符
 ++ --

C语言程序设计 - 第2章 数据类型、运算符和表达式 54


基本算术运算符
运算符 名称 举例 说明
正值运算符 ( 正号
+ +b 值不变
) ( 负号
负值运算符
- -d 取相反数
)
+ 加法运算符 a+3 加法
- 减法运算符 c-4 减法
* 乘法运算符 a*3 乘法
/ 除法运算符 c/d 除法
% 模运算符 e%4 求余数、取模
C语言程序设计 - 第2章 数据类型、运算符和表达式 55
基本算术运算符的特性
 优先级 ( 从高到低 )
+( 正号 ) – ( 负号 )
* / %
+(加) –(减)
 结合方向
+ ( 正号 ) – ( 负号 ) :从右向左
 + ( 加 ) – ( 减 ) * / % :从左向右

C语言程序设计 - 第2章 数据类型、运算符和表达式 56


基本算术运算符的说明
 两个整数相除,结果也为整数
 直接舍去商的小数部分,而不会“四舍五入

 负数整数除法,结果的舍入方向没有规定
 如果需要得到精确的运算结果,可以把其中
一个操作数转换为浮点数
 举例, 5/3(=1) 、 5.0/3(=1.66666…)
 举例, -5/3(=-1?-2?)
 模运算符的两个操作数都必须是整数
 负数模运算结果的符号没有规定
 举例, 5%3(=2) 、 -5%3(=-2?1?)
C语言程序设计 - 第2章 数据类型、运算符和表达式 57
强制类型转换运算符
 形式
 ( 类型名 ) 操作数
 说明
 强制把表达式转换成所需的类型
 强制类型转换运算符的优先级比较高
 强制类型转换不会改变操作数自身的类型,
只是得到一个所需类型的中间量
 多用于自动类型转换不能实现的目的
 强制类型转换后,会影响 C 语言做类型检

C语言程序设计 - 第2章 数据类型、运算符和表达式 58
强制类型转换举例
float x=2.8, y=3.7, z;
int a, b, c, d=5, e=2;

a=(int)x+y; /* a=5, 2+3.7 => 5 */


b=(int)(x+y); /* b=6, (int)(6.5) */
c=(int)x;
printf("x=%f, c=%d\n", x, c);
/* x=2.800000, c=2 */
z=(float)d/e; /* z=2.5 */

C语言程序设计 - 第2章 数据类型、运算符和表达式 59


自增、自减运算符
 形式
 ++i, --i 使用 i 之前,先使 i 的值加 / 减 1
 i++, i-- 使用 i 之后,再使 i 的值加 / 减 1
 说明
 ++i 和 --i 的值是加 / 减 1 之后 i 的值
 i++ 和 i-- 的值是加 / 减 1 之前 i 的值
 ++ 和 -- 只能用于变量,不能用于常量和表达

 ++ 和 -- 的结合方向是“自右向左”

C语言程序设计 - 第2章 数据类型、运算符和表达式 60


自增、自减运算符举例
int i=3, j, a, b=1, c=2;

j = ++i; /* i=i+1, j=i, i=4, j=4 */


j = i++; /* j=i, i=i+1, i=5, j=4 */
j = -i++; /* -(i++), i=6, j=-5 */
j = i++*2; /* (i++)*2, i=7, j=12 */
a = (b+c)++; /* 非法 !!! */
a = 34++; /* 非法 !!! */
j = ++i++; /* 非法 !!! */

C语言程序设计 - 第2章 数据类型、运算符和表达式 61


有关表达式使用的问题
 表达式中子表达式的求值顺序没有规定
 i=3;j=(i++)+(i++)+(i++);
/* j=9? 12? */
 C 编译程序自左向右尽可能多的将若干
字符组合成一个运算符、标识符、关键

 i+++j /* (i++)+j? i+(++j)? */
 调用函数时,实参的求值顺序没有规定
 i=3;printf("%d,%d\n", i, i++);
/* 3,3? 4,3? */C语言程序设计 - 第2章 数据类型、运算符和表达式 62
赋值运算符 (Assignment
Operators)
 赋值运算符 =
 把右侧表达式的值赋给左侧的变量
 一般情况下,赋值运算符左侧只能是变量
 赋值运算符的优先级较低,“自右向左”结

 运算符两侧类型不一致时,要进行类型转换
 注意“赋值”与“等于”的区别,例如
i=i+2;
 复合赋值运算符
 = 前加上算术运算符或位运算符,如 += 、
C语言程序设计 - 第2章 数据类型、运算符和表达式 63
赋值表达式
 赋值表达式
 < 变量 >< 赋值运算符 >< 表达式 >
 赋值表达式的值就是所赋的值
 运算符右侧的表达式可以是一个赋值表达式
 举例
 a=5; /* 表达式的值为 5*/
 a=b=3; /*a=(b=3)*/
 a=b=c=1; /*a=(b=(c=1))*/
 a=(b=4)+(c=3);/*b=4, c=3, a=7*/

C语言程序设计 - 第2章 数据类型、运算符和表达式 64


逗号运算符
 逗号运算符 ,
 exp1, exp2
 逗号运算符的优先级最低,“自左向右”结

 逗号表达式的值是 exp2 的值
 exp1 和 exp2 都可以又是“逗号表达式”
 把多个表达式组合成一个表达式使用
 举例
 x=(a=3, 6*a) /* a=3, x=18 */
 x=a=3, 6*a /*C语言程序设计
a=3,- 第x=3 */
2章 数据类型、运算符和表达式 65
基本输入输出
 头文件
 #include <stdio.h>
 输入输出函数
 字符输出函数 putchar
 字符输入函数 getchar
 格式输出函数 printf
 格式输入函数 scanf
 字符串输出函数 puts
 字符串输入函数 gets
C语言程序设计 - 第2章 数据类型、运算符和表达式 66
字符输出函数 putchar
 函数说明
 int
putchar(int c);
 输出一个字符到标准输出设备
 参数说明
c 要输出的字符,可以是整数或字符
 int
,若超出字符型范围,则只使用低字节
 返回值
 若成功,返回输出字符的 ASCII 码值
 若失败,返回 EOF (End of File)
C语言程序设计 - 第2章 数据类型、运算符和表达式 67
函数 putchar 举例 (02-01.C)

int c, i;

putchar('a'); /* 输出 'a' */
putchar('\n'); /* 输出换行符 */
putchar(101); /* 输出 'e' */
putchar('\101'); /* 输出 'A' */

c = 1000;
i = putchar(c); /* 输出 'è' , i=232 */

C语言程序设计 - 第2章 数据类型、运算符和表达式 68


字符输入函数 getchar
 函数说明
 int
getchar(void);
 从标准输入设备输入一个字符
 需要输入回车后,函数才返回
 参数说明
 无参数
 返回值
 若成功,返回输入字符的 ASCII 码值
 若失败,返回 EOF (End of File)
C语言程序设计 - 第2章 数据类型、运算符和表达式 69
函数 getchar 举例 (02-02.C)

int c;

c = getchar(); /* 输入 'a' 后回车 */


putchar(c); /* 输出 'a' */
c = getchar(); /* 是否需要输入 ? */
printf("c=%d\n", c); /* 输出 c=? 10 */
c = getchar(); /* 输入 'abcd' 后回车 */
putchar(c); /* 输出 'a' */
putchar(getchar()); /* 输出 'b' */

C语言程序设计 - 第2章 数据类型、运算符和表达式 70


格式输出函数 printf
 函数说明
 int printf(char* format[,
args...]);
 格式化输出若干任意类型数据
 参数说明
 char* format 格式控制字符串
 args 需要输出的数据列表,可以多个或没有
 返回值
 若成功,返回输出的字节数,包括换行符
 若失败,返回 EOF (EndC语言程序设计
of File)- 第2章 数据类型、运算符和表达式 71
函数 printf 的参数说明
 格式字符串
 包括“格式说明”和“普通字符”
 “ 格式说明”由 % 和“格式字符”组成,
将输出数据按指定格式输出
 “ 普通字符”按原样输出
 输出列表
 需要输出的数据
 可以是变量、常量、表达式、函数调用等
 输出数据按顺序与“格式说明”对应输出

C语言程序设计 - 第2章 数据类型、运算符和表达式 72


函数 printf 的格式举例

printf("a=%d b=%d", a, b);

普通字符 格式说明 输出列表

输出结果 >a=3 b=4

C语言程序设计 - 第2章 数据类型、运算符和表达式 73


格式字符
格式字符 说 明
d, i 有符号十进制整数,正数不输出符号
o 无符号八进制整数,不输出前导 0
x, X 无符号十六进制整数,不输出前导 0x 或 0X
u 无符号十进制整数
转换为无符号字符型,以此为 ASCII 码输出一个字
c

s 输出字符串,直到遇到 '\0' 或达到指定宽度
f 小数形式单、双精度数,缺省精度为 6 位小数
以规范化指数形式输出浮点数,缺省精度为 6 位小
e, E

g, G 以 f(F) 和 e(E) 两种格式中较短的一种输出
% 输出一个 %
C语言程序设计 - 第2章 数据类型、运算符和表达式 74
附加格式字符
格式字符 说 明
h 有符号或无符号短整型
l 有符号或无符号长整型
L 长双精度型
m 一个正整数,输出数据的最小宽度
n 一个正整数,输出的小数位数或字符串截取个数
. 分隔 m 和 n
- 输出的数字或字符向左靠齐
+ 输出的数字一直带符号,即正号也输出
0 输出的数字不满规定宽度时,用前导 0 填充
 有符号数字如果没有输出符号,则前面加一个空格
# 八进制和十六进制数加前缀,浮点数格式也有所改变
C语言程序设计 - 第2章 数据类型、运算符和表达式 75
函数 printf 举例 (02-03.C)

int i=1234;
float f=-56.78;
printf("i=%+6d", i); /* "i=+1234" */
printf("%c", i); /* "ò" */
printf("%#08x", i); /* "0x0004d2" */
printf("%10.5E", f); /* "-5.67800E+01" */
printf("%7.4f%%", f);/* "-56.7800%" */
printf("%+6.3G", f); /* "-56.8" */
printf("%-6.3s", "Hello"); /* "Hel " */

C语言程序设计 - 第2章 数据类型、运算符和表达式 76


格式输入函数 scanf
 函数说明
 int scanf(char* format[,
addrs...]);
 格式化输入若干任意类型数据
 参数说明
 char* format 格式控制字符串
 addrs 需要输入的地址列表,可以有多个
 返回值
 返回输入并赋值的数据项的个数

C语言程序设计 - 第2章 数据类型、运算符和表达式 77


函数 scanf 使用说明
 “ 地址列表”中是变量的地址,而非变

 scanf("%d", &i);
 关于输入格式
 格式字符串中的普通字符须按相应位置输入
 除字符型 (%c) 外,输入项之间用一个或多
个空白字符分隔,包括空格、回车、制表符
 空白字符会作为 %c 对应的输入,如果需要
输入下一个非空白字符,可以用 %1s
 如规定了最大宽度,且输入数据超出宽度,
则按宽度截取数据 C语言程序设计 - 第2章 数据类型、运算符和表达式 78
格式字符
格式字符 说 明
d 有符号十进制整数
i 有符号整数,可以是八进制 ( 带前导 0) 或十六进
制 ( 带前导 0x 或 0X)
o 有符号八进制整数,可以带或不带前导 0
x, X 有符号十六进制整数,可以带或不带前导 0x 或
u 0X
无符号十进制整数
c 输入一个字符,包括空白字符
s 输入无空白字符的字符串,不需要用 "" 括起来
f,e,E,g,G 浮点数,可以用小数形式或指数形式
% 输入一个 %
C语言程序设计 - 第2章 数据类型、运算符和表达式 79
附加格式字符
格式字符 说 明

h 有符号或无符号短整型

l 有符号或无符号长整型或双精度型

L 长双精度型

m 一个正整数,输入数据的最大宽度

* 需要输入数据,但是在赋值时被跳过

C语言程序设计 - 第2章 数据类型、运算符和表达式 80


函数 scanf 举例 (02-04.C)
int i, j;
char c;

scanf("%d%d", &i, &j);


/* "2 3" or "2<TAB>3" or "2<Enter>3" */
scanf("i=%d, j=%d", &i, &j);
/* "i=2,j=3" or "i=2, j=3" */
scanf("%d%c%d", &i, &c, &j);
/* "2 a 3" => i=2, c='', j 出错 */
/* "2a 3" => i=2, c='a', j=3 */

C语言程序设计 - 第2章 数据类型、运算符和表达式 81


简单的 C 程序设计
 例 1 :输入球体半径,求球的体积。
4 3
V = πr
3
 例 2 :输入大写字母,转换为小写字母

C语言程序设计 - 第2章 数据类型、运算符和表达式 82


例 1 :球体体积 (02-05.C)
#include <stdio.h>
#define PI 3.1415926

void main()
{
float r, V;
printf("r=");
scanf("%f", &r);
V = 4.0 / 3 * PI * r * r * r;
printf("V=%f\n", V);
}
C语言程序设计 - 第2章 数据类型、运算符和表达式 83
例 2 :字母大小写转换 (02-06.C)
#include <stdio.h>

void main()
{
char cup, clow;

cup = getchar();
clow = cup + 'a' - 'A';
printf("%c\n", clow);
}

C语言程序设计 - 第2章 数据类型、运算符和表达式 84


作 业
习题 3.6 、 3.9 、 3.10 、 3.12(3)~(5)
习题 4.5 、 4.6 、 4.9

C语言程序设计 - 第2章 数据类型、运算符和表达式 85


结束

The End

C语言程序设计 - 第2章 数据类型、运算符和表达式 86

You might also like