白 雪 飞
baixf@ustc.edu.cn
中国科学技术大学电子科学与技术系
Dept,of Elec,Sci,& Tech.,USTC
Fall,2003
第 2章 数据类型、运算符和表达式
C语言程序设计 - 第 2章 数据类型、运算符和表达式 2
目 录
数据类型、常量和变量的定义
运算符的种类、优先级和结合方向
表达式的类型和求值
简单的 C程序设计及基本输入输出
C语言程序设计 - 第 2章 数据类型、运算符和表达式 3
C的数据类型 (Data Types)
基本类型
整型、字符型、浮点型(实型)、枚举类型
构造类型
数组类型、结构体类型、共用体类型
指针类型
空类型
C语言程序设计 - 第 2章 数据类型、运算符和表达式 4
数据类型、常量和变量
C的数据结构是以数据类型形式出现的
由前述数据类型可以构造出更复杂的数据结构
C语言的数据有常量和变量之分
常量和变量都分别属于某一数据类型
程序中用到的所有数据都必须指定类型
本章仅介绍基本数据类型
C语言程序设计 - 第 2章 数据类型、运算符和表达式 5
标识符 (Identifier)
标识符
变量名、符号常量名、函数名、类型名 …
标识符命名规范
由字母、数字、下划线 (Underscore,'_')组成
第一个字符必须为字母或下划线
C语言标识符是大小写敏感的
标识符的名称一般应具有一定的含义
不要与 C语言关键字 (Keywords)重复
一般不要使用以下划线开头的标识符
C语言程序设计 - 第 2章 数据类型、运算符和表达式 6
标识符示例
正确的标识符
student,num1,_SUM,_1_2_3
MyName,myname,my_name
错误的标识符
room3-1 包含了其他字符(减号)
2men 以数字开头
long 与关键字重复
Mr.Zhu 包含了其他字符(小数点)
C语言程序设计 - 第 2章 数据类型、运算符和表达式 7
常量 (Constants)
常量
程序运行过程中,其值不能被改变的量
例如,12,-6.7,'a'…
符号常量 (Symbolic Constants)
用一个标识符代表的常量
相当于把标识符用一个常量简单替换下来
标识符是一个整体,不要试图拆开来替换
含义清楚,一改全改
习惯上符号常量名用大写字母
C语言程序设计 - 第 2章 数据类型、运算符和表达式 8
常量示例
#define PRICE 30
#define NUM 12
void main()
{
...,..
total = NUM * PRICE;
total2 = 84 * PRICE2;
printf("total=%d",total);
...,..
} 不会被替换
=> total = 12 * 30;
常量符号常量
C语言程序设计 - 第 2章 数据类型、运算符和表达式 9
变量 (Variables)
其值可以改变的量称为变量
变量有一个名字,即标识符
变量在存储器中占据一定的存储单元
变量占据存储空间的大小由其类型决定
变量名表示存储变量的存储单元地址
程序使用变量名表示这个变量所占据的存储单元里 存储的数据的值
变量要“先定义,后使用”
C语言程序设计 - 第 2章 数据类型、运算符和表达式 10
变量的存储
34
a 变量名存储单元 (地址 )
变量值
C语言程序设计 - 第 2章 数据类型、运算符和表达式 11
整型 (Integer)
整型常量的表示方法
整型变量
整型数据在内存中的存放形式
整型变量的类型
整型变量的定义
整型数据的溢出
整型常量的类型
C语言程序设计 - 第 2章 数据类型、运算符和表达式 12
整型常量的表示方法
十进制 (Decimal)
例如,123,-456,0
八进制 (Octal)
以 0开头,不得含有 8或 9
例如,0123,-0456
错例,0138,-0912
十六进制 (Hexadecimal)
以 0x或 0X开头,用 a~f或 A~F表示 10~15
例如,0x123,-0X45,0x3AB,-0xabc
C语言程序设计 - 第 2章 数据类型、运算符和表达式 13
整型数据在内存中的存放方式
二进制形式
举例,int i=50; /*int类型占 2字节 */
补码 (Complement)
正数:与原码一致,首位为 0
负数:绝对值取反加一,首位为 1
零:各位全为 0
0 0 0 0 0 0 0 0 0 0 1 1 0 0 1 0
高地址字节 低地址字节
C语言程序设计 - 第 2章 数据类型、运算符和表达式 14
补码举例
举例
int i=-50; /*int类型占 2字节 */
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
1 1 1 1 1 1 1 1 1 1 0 0 1 1 1 0
50的原码
-50的补码取反加一
C语言程序设计 - 第 2章 数据类型、运算符和表达式 15
整型变量的分类
按占用存储空间的大小划分
基本整型 int
短整型 short [int]
长整型 long [int]
按有无符号划分
有符号 [signed]
无符号 unsigned
上述两种分类方式组合,可得到 6种类型
C语言程序设计 - 第 2章 数据类型、运算符和表达式 16
整数的长度
整数的类型与长度
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章 数据类型、运算符和表达式 17
有符号数与无符号数
有符号数
二进制补码表示,首位为符号位
指定 signed或缺省情况,即为有符号数
无符号数
没有符号位,只能表示非负数
无符号数类型必须指定为 unsigned
若把负数赋值给无符号数,则把该负数的补码当作无符号数进行处理
C语言程序设计 - 第 2章 数据类型、运算符和表达式 18
有符号数与无符号数举例
void main()
{
int i;
unsigned j;
i=j=-50;
i=i/2; /*-25*/
j=j/2; /*32743*/
}
1 1 1 1 1 1 1 1 1 1 0 0 1 1 1 0
-50的补码 i,j
/ 2
1 1 1 1 1 1 1 1 1 1 1 0 0 1 1 1
0 1 1 1 1 1 1 1 1 1 1 0 0 1 1 1
i/2-25的补码
j/232743的补码 /原码
C语言程序设计 - 第 2章 数据类型、运算符和表达式 19
整型数据的取值范围类 型 长度 (bit) 取值范围
[signed] short [int] 16 -215 ~ 215-1
unsigned short [int] 16 0 ~ 216-1
[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章 数据类型、运算符和表达式 20
整型变量的定义 (Definition)
定义形式
int a,b;
unsigned c;
long d;
unsigned short e;
变量的定义一般放在一个函数开头的声明部分,关于变量定义的具体内容在以后相关章节里详细介绍
C语言程序设计 - 第 2章 数据类型、运算符和表达式 21
整型变量的定义与使用举例
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章 数据类型、运算符和表达式 22
整型数据的溢出 (Overflow)
溢出
数据超出了变量能够存储的范围,造成数据丢失或数值改变等
举例
void main()
{
int a = 32767;
a++; /*32768?*/
}
0 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1
1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+1
32767的补码
-32768的补码
C语言程序设计 - 第 2章 数据类型、运算符和表达式 23
整型常量的类型
常量的类型后缀 (Suffix)
l,L 表示常量是一个长整型
u,U 表示常量是一个无符号整型数
两种后缀可以一起使用
举例
123l 长整型常数 123
456U 无符号整型常数 456
789ul无符号长整型常数 789
101Lu无符号长整型常数 101
C语言程序设计 - 第 2章 数据类型、运算符和表达式 24
整型常量使用中的类型问题
对整型变量赋值
常量的值不要超过变量的取值范围
直接使用常量
带有 l,L,u,U等后缀的整型常量一般用于函数调用
不带有后缀的整型常量的类型,是根据其数值大小所处的范围来确定的
C语言程序设计 - 第 2章 数据类型、运算符和表达式 25
浮点型 (Floating Point)
浮点型常量的表示方法
浮点型变量
浮点型数据在内存中的存放形式
浮点型变量的类型
浮点型数据的舍入误差
浮点型常数的类型
C语言程序设计 - 第 2章 数据类型、运算符和表达式 26
浮点型常量的表示方法
十进制小数形式
由符号、数字和小数点 (必须 )组成
整数和小数部分都可省略,但不能同时省略
举例,12.3,-.123,123.,0.,.0
指数形式
由整数 (或小数 ),e(或 E)、整数顺序组成
e或 E之前必须有数字,之后必须是整数
举例,123.4e-5表示 123.4× 10-5
错例,e1,12e,1.2e3.4,.e5,e
C语言程序设计 - 第 2章 数据类型、运算符和表达式 27
规范化指数形式
规范化指数形式
类似于“科学计数法”
e或 E之前的小数中,小数点前面有且仅有一个非零数字
举例,123.456
规范化形式,1.23456e2,1.23456E+002
非规范化形式,123.456,12.3456e1、
12345.6e-2,0.123456e3、
12345600e-5…
C语言程序设计 - 第 2章 数据类型、运算符和表达式 28
浮点型数据在内存中的存放方式
二进制规范化指数形式
小数部分长度与能表示的精度有关
指数部分长度与能表示的数值范围有关
1 1 0 1 1 0 0 1 1 0 1 1 0 0 1 0
指数部分 e 小数部分 f符号 s
es fv 2).1()1(
C语言程序设计 - 第 2章 数据类型、运算符和表达式 29
几个特殊的数
无穷大 (Infinition)
Inf 举例,1.0/0.0
-Inf 举例,-1.0/0.0
NaN (Not a Number)
NaN 举例,sqrt(-1) /*开平方 */
-NaN 举例,-sqrt(-1)
零 (Zero)
浮点数用特殊的形式表示零
C语言程序设计 - 第 2章 数据类型、运算符和表达式 30
浮点型变量的类型
分类
单精度 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章 数据类型、运算符和表达式 31
浮点型数据的舍入误差
由于浮点型变量能够表示的有效数字有限,将有效位以外的数字舍去造成误差
举例
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章 数据类型、运算符和表达式 32
浮点型常量的类型
类型后缀
f,F 表示常量是一个单精度型浮点数
l,L 表示常量是一个长双精度型浮点数
无任何后缀的浮点型常量视作双精度型
对浮点型变量赋值
一个浮点型常量可以赋值给任何类型的浮点型变量
根据变量类型截取常量的相应有效数字
注意防止出现溢出
C语言程序设计 - 第 2章 数据类型、运算符和表达式 33
字符型 (Character)
字符型常量
字符型变量
字符型数据在内存中的存放形式
字符型数据的使用方法
字符串常量
C语言程序设计 - 第 2章 数据类型、运算符和表达式 34
字符型常量
单引号括起来的 一个 字符
举例,'a','A','1','?','?'…
错例,'abc','','我 '…
转义字符
以 '\'开头的特殊字符
'\ddd' 1到 3位 8进制数 ASCII码代表的字符
'\xhh' 1到 2位 16进制数 ASCII码代表的字符
举例,'\n','\t','\\','\'','\"'、
'\123','\x3A'…
C语言程序设计 - 第 2章 数据类型、运算符和表达式 35
字符型变量
字符型变量只能存放 一个 字符
定义与使用
void main()
{
char c1,c2; /*定义字符型变量 c1和 c2*/
c1 = 'a'; /*c1的值为 'a'*/
c2 = '2'; /*c2的值为 '2'*/
}
C语言程序设计 - 第 2章 数据类型、运算符和表达式 36
字符型数据在内存中的存放形式
一个字符型数据占一个字节的空间
字符型数据以其 ASCII码形式存放
字符型数据的存放形式与只占一个字节长度的整型数据完全相同
01100001
c1='a'
(ASCII=97)
00110010
c1='2'
(ASCII=50)
C语言程序设计 - 第 2章 数据类型、运算符和表达式 37
字符型数据的使用方法
可以把字符型数据视作一种长度为 1字节的整型数据处理
当使用字符型数据时,与使用这个字符的
ASCII码 (一个 8位整数 )是完全一样的
字符型数据的用法与整型数据完全一样,包括运算、赋值、输入、输出等
字符型数据使用过程中,同样需要注意溢出、
符号等问题
是字符还是整数,只有在输出时才有意义
C语言程序设计 - 第 2章 数据类型、运算符和表达式 38
字符型数据使用举例
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章 数据类型、运算符和表达式 39
字符型变量的符号
字符型变量与整型变量一样,也分为有符号数与无符号数
无符号字符
unsigned char c;
举例,表示一个班级的人数 (<256)
赋值和使用中需要注意的问题,与整型变量相同
C语言程序设计 - 第 2章 数据类型、运算符和表达式 40
字符串 (String)常量
表示形式
一对双引号括起来的字符序列
引号内可以包括 0个,1个或多个字符
字符序列中的特殊字符用转义字符表示
举例,"abc","a","","?","我 "
举例,"12.4","$#*!","C:\\HOME"
字符常量和字符串常量是不同类型的数据
例如,'a'与 "a"是不同的
不能把一个字符串赋值给一个字符型变量
C语言程序设计 - 第 2章 数据类型、运算符和表达式 41
字符串在内存中的存放方式
在内存中每个字符按顺序存放
字符串结尾有一个 空字符 (ASCII=0,'\0')
作为字符串结束标志
字符串结束标志 '\0'是不能显示的,在字符串常量中,也不用显式写出来
举例
"TEST"
""
"a"
'T''E''S' 'T' \0 84 69 83 84 00
\0
'a' \0
00
97 00
C语言程序设计 - 第 2章 数据类型、运算符和表达式 42
变量赋初值 (Initialization)
在定义变量的同时对变量赋值 (初始化 )
举例
int a=1;
/*相当于 int a; a=1;*/
int a,b=3;
/*对 b赋初值,a没有初值 */
int b,c,a=b=c=100;
/*对三个变量赋同样的初值 */
变量使用前,一般应先对它赋值
C语言程序设计 - 第 2章 数据类型、运算符和表达式 43
各类数值型数据间的混合运算
整型、字符型、浮点型数据可混合运算
混合运算时,不同类型的数据按照一定的规则先转换为同一类型,然后再运算
double
long
unsigned
int
float
char,short
高低
C语言程序设计 - 第 2章 数据类型、运算符和表达式 44
运算符 (Operator)
运算符的种类
运算符的优先级
运算符的结合方向
C语言程序设计 - 第 2章 数据类型、运算符和表达式 45
运算符的种类 (1)
算术运算符 + - * / % ++ --
关系运算符 > < == >= <= !=
逻辑运算符 ! && ||
位运算符 << >> ~ | ^ &
赋值运算符 = += -= *= /= %=
>>= <<= &= ^= |=
条件运算符?:
C语言程序设计 - 第 2章 数据类型、运算符和表达式 46
运算符的种类 (2)
逗号运算符,
指针运算符 * &
求字节数运算符 sizeof
强制类型转换运算符 (type)
分量运算符,->
下标运算符 []
其他运算符 ()
C语言程序设计 - 第 2章 数据类型、运算符和表达式 47
运算符的优先级 (Precedence)
优先级
运算符的运算次序按优先级由高到低执行
可以用圆括号 ( )改变运算符的执行次序
举例
a+b*c–d/e
/*先算乘除,后算加减 */
/*乘除比加减优先级高 */
(a+b)*(c-d)/e
/*先算加减,后算乘除 */
C语言程序设计 - 第 2章 数据类型、运算符和表达式 48
运算符的结合方向 (Associativity)
结合方向
当一个操作数两侧的运算符优先级相同时,
运算次序按照结合方向的规定进行
举例
a+b-c
/*+和 -的结合方向都是从左向右 */
/*b先与 +结合计算 a+b,然后执行减法 */
a=b=1
/*=的结合方向是从右向左,先计算 b=1*/
C语言程序设计 - 第 2章 数据类型、运算符和表达式 49
运算符的结合方向规则
单目运算符的结合方向都是“从右向左”
!,~,++,--,+(正号 ),-(负号 )
*(指针运算符 ),&(地址运算符 )
sizeof,(type)
赋值运算符的结合方向是“从右向左”
三目运算符的结合方向是“从右向左”
唯一的三目运算符:条件运算符?:
其他运算符的结合方向都是“从左向右”
C语言程序设计 - 第 2章 数据类型、运算符和表达式 50
优先级与结合方向总结
不同优先级的运算符,运算次序按优先级由高到低执行
同一优先级的运算符,运算次序按结合方向的规定执行
可以使用圆括号 ( )明确运算次序
圆括号 ()具有最高的优先级
C语言程序设计 - 第 2章 数据类型、运算符和表达式 51
表达式 (Expression)
表达式的概念
表达式的类型
表达式求值
算术运算符和算术表达式
赋值运算符和赋值表达式
逗号运算符和逗号表达式
C语言程序设计 - 第 2章 数据类型、运算符和表达式 52
表达式的概念
表达式
用运算符把操作数连接起来,并符合 C语言语法规则的式子
操作数包括常量、变量、函数调用、表达式
广义上,常量、变量、函数调用也可以看作属于表达式的范畴
举例
a+2.5*b-6/c+'z'-max(x,y)
!((a<1e-6)&&(b==(c+sqrt(f))))
C语言程序设计 - 第 2章 数据类型、运算符和表达式 53
表达式的类型
表达式的类型
表达式的值的类型
取决于操作数的类型以及它们所做的运算
举例
a+2.5*b-6/c+'z'
/*混合类型算术运算,值为 double类型 */
!((a<1e-6)&&(b==(c+sqrt(f))))
/*逻辑判断的结果是逻辑值 */
/*C语言用整型表示逻辑类型 */
C语言程序设计 - 第 2章 数据类型、运算符和表达式 54
算术运算符 (Arithmetic Operators)
基本算术运算符
+ - * / %
强制类型转换运算符
(类型名 )
自增、自减运算符
++ --
C语言程序设计 - 第 2章 数据类型、运算符和表达式 55
基本算术运算符运算符 名称 举例 说明
+ 正值运算符 (正号 ) +b 值不变
- 负值运算符 (负号 ) -d 取相反数
+ 加法运算符 a+3 加法
- 减法运算符 c-4 减法
* 乘法运算符 a*3 乘法
/ 除法运算符 c/d 除法
% 模运算符 e%4 求余数、取模
C语言程序设计 - 第 2章 数据类型、运算符和表达式 56
基本算术运算符的特性
优先级 (从高到低 )
+ (正号 ) – (负号 )
* / %
+ (加 ) – (减 )
结合方向
+ (正号 ) – (负号 ):从右向左
+ (加 ) – (减 ) * / %,从左向右
C语言程序设计 - 第 2章 数据类型、运算符和表达式 57
基本算术运算符的说明
两个整数相除,结果也为整数
直接舍去商的小数部分,而不会“四舍五入”
负数整数除法,结果的舍入方向没有规定
如果需要得到精确的运算结果,可以把其中一个操作数转换为浮点数
举例,5/3(=1),5.0/3(=1.66666…)
举例,-5/3(=-1?-2?)
模运算符的两个操作数都必须是整数
负数模运算结果的符号没有规定
举例,5%3(=2),-5%3(=-2?1?)
C语言程序设计 - 第 2章 数据类型、运算符和表达式 58
强制类型转换运算符
形式
(类型名 )操作数
说明
强制把表达式转换成所需的类型
强制类型转换运算符的优先级比较高
强制类型转换不会改变操作数自身的类型,
只是得到一个所需类型的中间量
多用于自动类型转换不能实现的目的
强制类型转换后,会影响 C语言做类型检查
C语言程序设计 - 第 2章 数据类型、运算符和表达式 59
强制类型转换举例
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章 数据类型、运算符和表达式 60
自增、自减运算符
形式
++i,--i 使用 i之 前,先使 i的值 加 /减 1
i++,i-- 使用 i之 后,再使 i的值 加 /减 1
说明
++i和 --i的值是加 /减 1之后 i的值
i++和 i--的值是加 /减 1之前 i的值
++和 --只能用于变量,不能用于常量和表达式
++和 --的结合方向是“自右向左”
C语言程序设计 - 第 2章 数据类型、运算符和表达式 61
自增、自减运算符举例
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章 数据类型、运算符和表达式 62
有关表达式使用的问题
表达式中子表达式的求值顺序没有规定
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章 数据类型、运算符和表达式 63
赋值运算符 (Assignment Operators)
赋值运算符 =
把右侧表达式的值赋给左侧的变量
一般情况下,赋值运算符左侧只能是变量
赋值运算符的优先级较低,“自右向左”结合
运算符两侧类型不一致时,要进行类型转换
注意“赋值”与“等于”的区别,例如
i=i+2;
复合赋值运算符
=前加上算术运算符或位运算符,如 +=,|=
举例,z*=x+y; /* z=z*(x+y); */
C语言程序设计 - 第 2章 数据类型、运算符和表达式 64
赋值表达式
赋值表达式
<变量 ><赋值运算符 ><表达式 >
赋值表达式的值就是所赋的值
运算符右侧的表达式可以是一个赋值表达式
举例
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章 数据类型、运算符和表达式 65
逗号运算符
逗号运算符,
exp1,exp2
逗号运算符的优先级最低,“自左向右”结合
逗号表达式的值是 exp2的值
exp1和 exp2都可以又是“逗号表达式”
把多个表达式组合成一个表达式使用
举例
x=(a=3,6*a) /* a=3,x=18 */
x=a=3,6*a /* a=3,x=3 */
C语言程序设计 - 第 2章 数据类型、运算符和表达式 66
基本输入输出
头文件
#include <stdio.h>
输入输出函数
字符输出函数 putchar
字符输入函数 getchar
格式输出函数 printf
格式输入函数 scanf
字符串输出函数 puts
字符串输入函数 gets
C语言程序设计 - 第 2章 数据类型、运算符和表达式 67
字符输出函数 putchar
函数说明
int putchar(int c);
输出一个字符到标准输出设备
参数说明
int c 要 输出的字符,可以是整数或字符,
若超出字符型范围,则只使用低字节
返回值
若成功,返回输出字符的 ASCII码值
若失败,返回 EOF (End of File)
C语言程序设计 - 第 2章 数据类型、运算符和表达式 68
函数 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章 数据类型、运算符和表达式 69
字符输入函数 getchar
函数说明
int getchar(void);
从标准输入设备输入一个字符
需要输入回车后,函数才返回
参数说明
无参数
返回值
若成功,返回输入字符的 ASCII码值
若失败,返回 EOF (End of File)
C语言程序设计 - 第 2章 数据类型、运算符和表达式 70
函数 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章 数据类型、运算符和表达式 71
格式输出函数 printf
函数说明
int printf(char* format[,args...]);
格式化输出若干任意类型数据
参数说明
char* format 格式控制字符串
args 需要输出的数据列表,可以多个或没有
返回值
若成功,返回输出的字节数,包括换行符
若失败,返回 EOF (End of File)
C语言程序设计 - 第 2章 数据类型、运算符和表达式 72
函数 printf的参数说明
格式字符串
包括“格式说明”和“普通字符”
“格式说明”由 %和“格式字符”组成,将输出数据按指定格式输出
“普通字符”按原样输出
输出列表
需要输出的数据
可以是变量、常量、表达式、函数调用等
输出数据按顺序与“格式说明”对应输出
C语言程序设计 - 第 2章 数据类型、运算符和表达式 73
函数 printf的格式举例
printf("a=%d b=%d",a,b);
格式说明普通字符 输出列表输出结果 >a=3 b=4
C语言程序设计 - 第 2章 数据类型、运算符和表达式 74
格式字符格式字符 说 明
d,i 有符号十进制整数,正数不输出符号
o 无符号八进制整数,不输出前导 0
x,X 无符号十六进制整数,不输出前导 0x或 0X
u 无符号十进制整数
c 转换为无符号字符型,以此为 ASCII码输出一个字符
s 输出字符串,直到遇到 '\0'或达到指定宽度
f 小数形式单、双精度数,缺省精度为 6位小数
e,E 以规范化指数形式输出浮点数,缺省精度为 6位小数
g,G 以 f(F)和 e(E)两种格式中较短的一种输出
% 输出一个 %
C语言程序设计 - 第 2章 数据类型、运算符和表达式 75
附加格式字符格式字符 说 明
h 有符号或无符号短整型
l 有符号或无符号长整型
L 长双精度型
m 一个正整数,输出数据的最小宽度
n 一个正整数,输出的小数位数或字符串截取个数
,分隔 m和 n
- 输出的数字或字符向左靠齐
+ 输出的数字一直带符号,即正号也输出
0 输出的数字不满规定宽度时,用前导 0填充
有符号数字如果没有输出符号,则前面加一个空格
# 八进制和十六进制数加前缀,浮点数格式也有所改变
C语言程序设计 - 第 2章 数据类型、运算符和表达式 76
函数 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章 数据类型、运算符和表达式 77
格式输入函数 scanf
函数说明
int scanf(char* format[,addrs...]);
格式化输入若干任意类型数据
参数说明
char* format 格式控制字符串
addrs 需要输入的地址列表,可以有多个
返回值
返回输入并赋值的数据项的个数
C语言程序设计 - 第 2章 数据类型、运算符和表达式 78
函数 scanf使用说明
,地址列表”中是变量的地址,而非变量
scanf("%d",&i);
关于输入格式
格式字符串中的普通字符须按相应位置输入
除字符型 (%c)外,输入项之间用一个或多个空白字符分隔,包括空格、回车、制表符
空白字符会作为 %c对应的输入,如果需要输入下一个非空白字符,可以用 %1s
如规定了最大宽度,且输入数据超出宽度,
则按宽度截取数据
C语言程序设计 - 第 2章 数据类型、运算符和表达式 79
格式字符格式字符 说 明
d 有符号十进制整数
i 有符号整数,可以是八进制 (带前导 0)或十六进制
(带前导 0x或 0X)
o 有符号八进制整数,可以带或不带前导 0
x,X 有符号十六进制整数,可以带或不带前导 0x或 0X
u 无符号十进制整数
c 输入一个字符,包括空白字符
s 输入无空白字符的字符串,不需要用 ""括起来
f,e,E,g,G 浮点数,可以用小数形式或指数形式
% 输入一个 %
C语言程序设计 - 第 2章 数据类型、运算符和表达式 80
附加格式字符格式字符 说 明
h 有符号或无符号短整型
l 有符号或无符号长整型或双精度型
L 长双精度型
m 一个正整数,输入数据的最大宽度
* 需要输入数据,但是在赋值时被跳过
C语言程序设计 - 第 2章 数据类型、运算符和表达式 81
函数 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章 数据类型、运算符和表达式 82
简单的 C程序设计
例 1:输入球体半径,求球的体积。
例 2:输入大写字母,转换为小写字母。
3
3
4
rV
C语言程序设计 - 第 2章 数据类型、运算符和表达式 83
例 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章 数据类型、运算符和表达式 84
例 2:字母大小写转换 (02-06.C)
#include <stdio.h>
void main()
{
char cup,clow;
cup = getchar();
clow = cup + 'a' - 'A';
printf("%c\n",clow);
}
C语言程序设计 - 第 2章 数据类型、运算符和表达式 85
作 业习题 3.6,3.9,3.10,3.12(3)~(5)
习题 4.5,4.6,4.9
C语言程序设计 - 第 2章 数据类型、运算符和表达式 86
结束
The End
baixf@ustc.edu.cn
中国科学技术大学电子科学与技术系
Dept,of Elec,Sci,& Tech.,USTC
Fall,2003
第 2章 数据类型、运算符和表达式
C语言程序设计 - 第 2章 数据类型、运算符和表达式 2
目 录
数据类型、常量和变量的定义
运算符的种类、优先级和结合方向
表达式的类型和求值
简单的 C程序设计及基本输入输出
C语言程序设计 - 第 2章 数据类型、运算符和表达式 3
C的数据类型 (Data Types)
基本类型
整型、字符型、浮点型(实型)、枚举类型
构造类型
数组类型、结构体类型、共用体类型
指针类型
空类型
C语言程序设计 - 第 2章 数据类型、运算符和表达式 4
数据类型、常量和变量
C的数据结构是以数据类型形式出现的
由前述数据类型可以构造出更复杂的数据结构
C语言的数据有常量和变量之分
常量和变量都分别属于某一数据类型
程序中用到的所有数据都必须指定类型
本章仅介绍基本数据类型
C语言程序设计 - 第 2章 数据类型、运算符和表达式 5
标识符 (Identifier)
标识符
变量名、符号常量名、函数名、类型名 …
标识符命名规范
由字母、数字、下划线 (Underscore,'_')组成
第一个字符必须为字母或下划线
C语言标识符是大小写敏感的
标识符的名称一般应具有一定的含义
不要与 C语言关键字 (Keywords)重复
一般不要使用以下划线开头的标识符
C语言程序设计 - 第 2章 数据类型、运算符和表达式 6
标识符示例
正确的标识符
student,num1,_SUM,_1_2_3
MyName,myname,my_name
错误的标识符
room3-1 包含了其他字符(减号)
2men 以数字开头
long 与关键字重复
Mr.Zhu 包含了其他字符(小数点)
C语言程序设计 - 第 2章 数据类型、运算符和表达式 7
常量 (Constants)
常量
程序运行过程中,其值不能被改变的量
例如,12,-6.7,'a'…
符号常量 (Symbolic Constants)
用一个标识符代表的常量
相当于把标识符用一个常量简单替换下来
标识符是一个整体,不要试图拆开来替换
含义清楚,一改全改
习惯上符号常量名用大写字母
C语言程序设计 - 第 2章 数据类型、运算符和表达式 8
常量示例
#define PRICE 30
#define NUM 12
void main()
{
...,..
total = NUM * PRICE;
total2 = 84 * PRICE2;
printf("total=%d",total);
...,..
} 不会被替换
=> total = 12 * 30;
常量符号常量
C语言程序设计 - 第 2章 数据类型、运算符和表达式 9
变量 (Variables)
其值可以改变的量称为变量
变量有一个名字,即标识符
变量在存储器中占据一定的存储单元
变量占据存储空间的大小由其类型决定
变量名表示存储变量的存储单元地址
程序使用变量名表示这个变量所占据的存储单元里 存储的数据的值
变量要“先定义,后使用”
C语言程序设计 - 第 2章 数据类型、运算符和表达式 10
变量的存储
34
a 变量名存储单元 (地址 )
变量值
C语言程序设计 - 第 2章 数据类型、运算符和表达式 11
整型 (Integer)
整型常量的表示方法
整型变量
整型数据在内存中的存放形式
整型变量的类型
整型变量的定义
整型数据的溢出
整型常量的类型
C语言程序设计 - 第 2章 数据类型、运算符和表达式 12
整型常量的表示方法
十进制 (Decimal)
例如,123,-456,0
八进制 (Octal)
以 0开头,不得含有 8或 9
例如,0123,-0456
错例,0138,-0912
十六进制 (Hexadecimal)
以 0x或 0X开头,用 a~f或 A~F表示 10~15
例如,0x123,-0X45,0x3AB,-0xabc
C语言程序设计 - 第 2章 数据类型、运算符和表达式 13
整型数据在内存中的存放方式
二进制形式
举例,int i=50; /*int类型占 2字节 */
补码 (Complement)
正数:与原码一致,首位为 0
负数:绝对值取反加一,首位为 1
零:各位全为 0
0 0 0 0 0 0 0 0 0 0 1 1 0 0 1 0
高地址字节 低地址字节
C语言程序设计 - 第 2章 数据类型、运算符和表达式 14
补码举例
举例
int i=-50; /*int类型占 2字节 */
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
1 1 1 1 1 1 1 1 1 1 0 0 1 1 1 0
50的原码
-50的补码取反加一
C语言程序设计 - 第 2章 数据类型、运算符和表达式 15
整型变量的分类
按占用存储空间的大小划分
基本整型 int
短整型 short [int]
长整型 long [int]
按有无符号划分
有符号 [signed]
无符号 unsigned
上述两种分类方式组合,可得到 6种类型
C语言程序设计 - 第 2章 数据类型、运算符和表达式 16
整数的长度
整数的类型与长度
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章 数据类型、运算符和表达式 17
有符号数与无符号数
有符号数
二进制补码表示,首位为符号位
指定 signed或缺省情况,即为有符号数
无符号数
没有符号位,只能表示非负数
无符号数类型必须指定为 unsigned
若把负数赋值给无符号数,则把该负数的补码当作无符号数进行处理
C语言程序设计 - 第 2章 数据类型、运算符和表达式 18
有符号数与无符号数举例
void main()
{
int i;
unsigned j;
i=j=-50;
i=i/2; /*-25*/
j=j/2; /*32743*/
}
1 1 1 1 1 1 1 1 1 1 0 0 1 1 1 0
-50的补码 i,j
/ 2
1 1 1 1 1 1 1 1 1 1 1 0 0 1 1 1
0 1 1 1 1 1 1 1 1 1 1 0 0 1 1 1
i/2-25的补码
j/232743的补码 /原码
C语言程序设计 - 第 2章 数据类型、运算符和表达式 19
整型数据的取值范围类 型 长度 (bit) 取值范围
[signed] short [int] 16 -215 ~ 215-1
unsigned short [int] 16 0 ~ 216-1
[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章 数据类型、运算符和表达式 20
整型变量的定义 (Definition)
定义形式
int a,b;
unsigned c;
long d;
unsigned short e;
变量的定义一般放在一个函数开头的声明部分,关于变量定义的具体内容在以后相关章节里详细介绍
C语言程序设计 - 第 2章 数据类型、运算符和表达式 21
整型变量的定义与使用举例
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章 数据类型、运算符和表达式 22
整型数据的溢出 (Overflow)
溢出
数据超出了变量能够存储的范围,造成数据丢失或数值改变等
举例
void main()
{
int a = 32767;
a++; /*32768?*/
}
0 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1
1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+1
32767的补码
-32768的补码
C语言程序设计 - 第 2章 数据类型、运算符和表达式 23
整型常量的类型
常量的类型后缀 (Suffix)
l,L 表示常量是一个长整型
u,U 表示常量是一个无符号整型数
两种后缀可以一起使用
举例
123l 长整型常数 123
456U 无符号整型常数 456
789ul无符号长整型常数 789
101Lu无符号长整型常数 101
C语言程序设计 - 第 2章 数据类型、运算符和表达式 24
整型常量使用中的类型问题
对整型变量赋值
常量的值不要超过变量的取值范围
直接使用常量
带有 l,L,u,U等后缀的整型常量一般用于函数调用
不带有后缀的整型常量的类型,是根据其数值大小所处的范围来确定的
C语言程序设计 - 第 2章 数据类型、运算符和表达式 25
浮点型 (Floating Point)
浮点型常量的表示方法
浮点型变量
浮点型数据在内存中的存放形式
浮点型变量的类型
浮点型数据的舍入误差
浮点型常数的类型
C语言程序设计 - 第 2章 数据类型、运算符和表达式 26
浮点型常量的表示方法
十进制小数形式
由符号、数字和小数点 (必须 )组成
整数和小数部分都可省略,但不能同时省略
举例,12.3,-.123,123.,0.,.0
指数形式
由整数 (或小数 ),e(或 E)、整数顺序组成
e或 E之前必须有数字,之后必须是整数
举例,123.4e-5表示 123.4× 10-5
错例,e1,12e,1.2e3.4,.e5,e
C语言程序设计 - 第 2章 数据类型、运算符和表达式 27
规范化指数形式
规范化指数形式
类似于“科学计数法”
e或 E之前的小数中,小数点前面有且仅有一个非零数字
举例,123.456
规范化形式,1.23456e2,1.23456E+002
非规范化形式,123.456,12.3456e1、
12345.6e-2,0.123456e3、
12345600e-5…
C语言程序设计 - 第 2章 数据类型、运算符和表达式 28
浮点型数据在内存中的存放方式
二进制规范化指数形式
小数部分长度与能表示的精度有关
指数部分长度与能表示的数值范围有关
1 1 0 1 1 0 0 1 1 0 1 1 0 0 1 0
指数部分 e 小数部分 f符号 s
es fv 2).1()1(
C语言程序设计 - 第 2章 数据类型、运算符和表达式 29
几个特殊的数
无穷大 (Infinition)
Inf 举例,1.0/0.0
-Inf 举例,-1.0/0.0
NaN (Not a Number)
NaN 举例,sqrt(-1) /*开平方 */
-NaN 举例,-sqrt(-1)
零 (Zero)
浮点数用特殊的形式表示零
C语言程序设计 - 第 2章 数据类型、运算符和表达式 30
浮点型变量的类型
分类
单精度 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章 数据类型、运算符和表达式 31
浮点型数据的舍入误差
由于浮点型变量能够表示的有效数字有限,将有效位以外的数字舍去造成误差
举例
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章 数据类型、运算符和表达式 32
浮点型常量的类型
类型后缀
f,F 表示常量是一个单精度型浮点数
l,L 表示常量是一个长双精度型浮点数
无任何后缀的浮点型常量视作双精度型
对浮点型变量赋值
一个浮点型常量可以赋值给任何类型的浮点型变量
根据变量类型截取常量的相应有效数字
注意防止出现溢出
C语言程序设计 - 第 2章 数据类型、运算符和表达式 33
字符型 (Character)
字符型常量
字符型变量
字符型数据在内存中的存放形式
字符型数据的使用方法
字符串常量
C语言程序设计 - 第 2章 数据类型、运算符和表达式 34
字符型常量
单引号括起来的 一个 字符
举例,'a','A','1','?','?'…
错例,'abc','','我 '…
转义字符
以 '\'开头的特殊字符
'\ddd' 1到 3位 8进制数 ASCII码代表的字符
'\xhh' 1到 2位 16进制数 ASCII码代表的字符
举例,'\n','\t','\\','\'','\"'、
'\123','\x3A'…
C语言程序设计 - 第 2章 数据类型、运算符和表达式 35
字符型变量
字符型变量只能存放 一个 字符
定义与使用
void main()
{
char c1,c2; /*定义字符型变量 c1和 c2*/
c1 = 'a'; /*c1的值为 'a'*/
c2 = '2'; /*c2的值为 '2'*/
}
C语言程序设计 - 第 2章 数据类型、运算符和表达式 36
字符型数据在内存中的存放形式
一个字符型数据占一个字节的空间
字符型数据以其 ASCII码形式存放
字符型数据的存放形式与只占一个字节长度的整型数据完全相同
01100001
c1='a'
(ASCII=97)
00110010
c1='2'
(ASCII=50)
C语言程序设计 - 第 2章 数据类型、运算符和表达式 37
字符型数据的使用方法
可以把字符型数据视作一种长度为 1字节的整型数据处理
当使用字符型数据时,与使用这个字符的
ASCII码 (一个 8位整数 )是完全一样的
字符型数据的用法与整型数据完全一样,包括运算、赋值、输入、输出等
字符型数据使用过程中,同样需要注意溢出、
符号等问题
是字符还是整数,只有在输出时才有意义
C语言程序设计 - 第 2章 数据类型、运算符和表达式 38
字符型数据使用举例
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章 数据类型、运算符和表达式 39
字符型变量的符号
字符型变量与整型变量一样,也分为有符号数与无符号数
无符号字符
unsigned char c;
举例,表示一个班级的人数 (<256)
赋值和使用中需要注意的问题,与整型变量相同
C语言程序设计 - 第 2章 数据类型、运算符和表达式 40
字符串 (String)常量
表示形式
一对双引号括起来的字符序列
引号内可以包括 0个,1个或多个字符
字符序列中的特殊字符用转义字符表示
举例,"abc","a","","?","我 "
举例,"12.4","$#*!","C:\\HOME"
字符常量和字符串常量是不同类型的数据
例如,'a'与 "a"是不同的
不能把一个字符串赋值给一个字符型变量
C语言程序设计 - 第 2章 数据类型、运算符和表达式 41
字符串在内存中的存放方式
在内存中每个字符按顺序存放
字符串结尾有一个 空字符 (ASCII=0,'\0')
作为字符串结束标志
字符串结束标志 '\0'是不能显示的,在字符串常量中,也不用显式写出来
举例
"TEST"
""
"a"
'T''E''S' 'T' \0 84 69 83 84 00
\0
'a' \0
00
97 00
C语言程序设计 - 第 2章 数据类型、运算符和表达式 42
变量赋初值 (Initialization)
在定义变量的同时对变量赋值 (初始化 )
举例
int a=1;
/*相当于 int a; a=1;*/
int a,b=3;
/*对 b赋初值,a没有初值 */
int b,c,a=b=c=100;
/*对三个变量赋同样的初值 */
变量使用前,一般应先对它赋值
C语言程序设计 - 第 2章 数据类型、运算符和表达式 43
各类数值型数据间的混合运算
整型、字符型、浮点型数据可混合运算
混合运算时,不同类型的数据按照一定的规则先转换为同一类型,然后再运算
double
long
unsigned
int
float
char,short
高低
C语言程序设计 - 第 2章 数据类型、运算符和表达式 44
运算符 (Operator)
运算符的种类
运算符的优先级
运算符的结合方向
C语言程序设计 - 第 2章 数据类型、运算符和表达式 45
运算符的种类 (1)
算术运算符 + - * / % ++ --
关系运算符 > < == >= <= !=
逻辑运算符 ! && ||
位运算符 << >> ~ | ^ &
赋值运算符 = += -= *= /= %=
>>= <<= &= ^= |=
条件运算符?:
C语言程序设计 - 第 2章 数据类型、运算符和表达式 46
运算符的种类 (2)
逗号运算符,
指针运算符 * &
求字节数运算符 sizeof
强制类型转换运算符 (type)
分量运算符,->
下标运算符 []
其他运算符 ()
C语言程序设计 - 第 2章 数据类型、运算符和表达式 47
运算符的优先级 (Precedence)
优先级
运算符的运算次序按优先级由高到低执行
可以用圆括号 ( )改变运算符的执行次序
举例
a+b*c–d/e
/*先算乘除,后算加减 */
/*乘除比加减优先级高 */
(a+b)*(c-d)/e
/*先算加减,后算乘除 */
C语言程序设计 - 第 2章 数据类型、运算符和表达式 48
运算符的结合方向 (Associativity)
结合方向
当一个操作数两侧的运算符优先级相同时,
运算次序按照结合方向的规定进行
举例
a+b-c
/*+和 -的结合方向都是从左向右 */
/*b先与 +结合计算 a+b,然后执行减法 */
a=b=1
/*=的结合方向是从右向左,先计算 b=1*/
C语言程序设计 - 第 2章 数据类型、运算符和表达式 49
运算符的结合方向规则
单目运算符的结合方向都是“从右向左”
!,~,++,--,+(正号 ),-(负号 )
*(指针运算符 ),&(地址运算符 )
sizeof,(type)
赋值运算符的结合方向是“从右向左”
三目运算符的结合方向是“从右向左”
唯一的三目运算符:条件运算符?:
其他运算符的结合方向都是“从左向右”
C语言程序设计 - 第 2章 数据类型、运算符和表达式 50
优先级与结合方向总结
不同优先级的运算符,运算次序按优先级由高到低执行
同一优先级的运算符,运算次序按结合方向的规定执行
可以使用圆括号 ( )明确运算次序
圆括号 ()具有最高的优先级
C语言程序设计 - 第 2章 数据类型、运算符和表达式 51
表达式 (Expression)
表达式的概念
表达式的类型
表达式求值
算术运算符和算术表达式
赋值运算符和赋值表达式
逗号运算符和逗号表达式
C语言程序设计 - 第 2章 数据类型、运算符和表达式 52
表达式的概念
表达式
用运算符把操作数连接起来,并符合 C语言语法规则的式子
操作数包括常量、变量、函数调用、表达式
广义上,常量、变量、函数调用也可以看作属于表达式的范畴
举例
a+2.5*b-6/c+'z'-max(x,y)
!((a<1e-6)&&(b==(c+sqrt(f))))
C语言程序设计 - 第 2章 数据类型、运算符和表达式 53
表达式的类型
表达式的类型
表达式的值的类型
取决于操作数的类型以及它们所做的运算
举例
a+2.5*b-6/c+'z'
/*混合类型算术运算,值为 double类型 */
!((a<1e-6)&&(b==(c+sqrt(f))))
/*逻辑判断的结果是逻辑值 */
/*C语言用整型表示逻辑类型 */
C语言程序设计 - 第 2章 数据类型、运算符和表达式 54
算术运算符 (Arithmetic Operators)
基本算术运算符
+ - * / %
强制类型转换运算符
(类型名 )
自增、自减运算符
++ --
C语言程序设计 - 第 2章 数据类型、运算符和表达式 55
基本算术运算符运算符 名称 举例 说明
+ 正值运算符 (正号 ) +b 值不变
- 负值运算符 (负号 ) -d 取相反数
+ 加法运算符 a+3 加法
- 减法运算符 c-4 减法
* 乘法运算符 a*3 乘法
/ 除法运算符 c/d 除法
% 模运算符 e%4 求余数、取模
C语言程序设计 - 第 2章 数据类型、运算符和表达式 56
基本算术运算符的特性
优先级 (从高到低 )
+ (正号 ) – (负号 )
* / %
+ (加 ) – (减 )
结合方向
+ (正号 ) – (负号 ):从右向左
+ (加 ) – (减 ) * / %,从左向右
C语言程序设计 - 第 2章 数据类型、运算符和表达式 57
基本算术运算符的说明
两个整数相除,结果也为整数
直接舍去商的小数部分,而不会“四舍五入”
负数整数除法,结果的舍入方向没有规定
如果需要得到精确的运算结果,可以把其中一个操作数转换为浮点数
举例,5/3(=1),5.0/3(=1.66666…)
举例,-5/3(=-1?-2?)
模运算符的两个操作数都必须是整数
负数模运算结果的符号没有规定
举例,5%3(=2),-5%3(=-2?1?)
C语言程序设计 - 第 2章 数据类型、运算符和表达式 58
强制类型转换运算符
形式
(类型名 )操作数
说明
强制把表达式转换成所需的类型
强制类型转换运算符的优先级比较高
强制类型转换不会改变操作数自身的类型,
只是得到一个所需类型的中间量
多用于自动类型转换不能实现的目的
强制类型转换后,会影响 C语言做类型检查
C语言程序设计 - 第 2章 数据类型、运算符和表达式 59
强制类型转换举例
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章 数据类型、运算符和表达式 60
自增、自减运算符
形式
++i,--i 使用 i之 前,先使 i的值 加 /减 1
i++,i-- 使用 i之 后,再使 i的值 加 /减 1
说明
++i和 --i的值是加 /减 1之后 i的值
i++和 i--的值是加 /减 1之前 i的值
++和 --只能用于变量,不能用于常量和表达式
++和 --的结合方向是“自右向左”
C语言程序设计 - 第 2章 数据类型、运算符和表达式 61
自增、自减运算符举例
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章 数据类型、运算符和表达式 62
有关表达式使用的问题
表达式中子表达式的求值顺序没有规定
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章 数据类型、运算符和表达式 63
赋值运算符 (Assignment Operators)
赋值运算符 =
把右侧表达式的值赋给左侧的变量
一般情况下,赋值运算符左侧只能是变量
赋值运算符的优先级较低,“自右向左”结合
运算符两侧类型不一致时,要进行类型转换
注意“赋值”与“等于”的区别,例如
i=i+2;
复合赋值运算符
=前加上算术运算符或位运算符,如 +=,|=
举例,z*=x+y; /* z=z*(x+y); */
C语言程序设计 - 第 2章 数据类型、运算符和表达式 64
赋值表达式
赋值表达式
<变量 ><赋值运算符 ><表达式 >
赋值表达式的值就是所赋的值
运算符右侧的表达式可以是一个赋值表达式
举例
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章 数据类型、运算符和表达式 65
逗号运算符
逗号运算符,
exp1,exp2
逗号运算符的优先级最低,“自左向右”结合
逗号表达式的值是 exp2的值
exp1和 exp2都可以又是“逗号表达式”
把多个表达式组合成一个表达式使用
举例
x=(a=3,6*a) /* a=3,x=18 */
x=a=3,6*a /* a=3,x=3 */
C语言程序设计 - 第 2章 数据类型、运算符和表达式 66
基本输入输出
头文件
#include <stdio.h>
输入输出函数
字符输出函数 putchar
字符输入函数 getchar
格式输出函数 printf
格式输入函数 scanf
字符串输出函数 puts
字符串输入函数 gets
C语言程序设计 - 第 2章 数据类型、运算符和表达式 67
字符输出函数 putchar
函数说明
int putchar(int c);
输出一个字符到标准输出设备
参数说明
int c 要 输出的字符,可以是整数或字符,
若超出字符型范围,则只使用低字节
返回值
若成功,返回输出字符的 ASCII码值
若失败,返回 EOF (End of File)
C语言程序设计 - 第 2章 数据类型、运算符和表达式 68
函数 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章 数据类型、运算符和表达式 69
字符输入函数 getchar
函数说明
int getchar(void);
从标准输入设备输入一个字符
需要输入回车后,函数才返回
参数说明
无参数
返回值
若成功,返回输入字符的 ASCII码值
若失败,返回 EOF (End of File)
C语言程序设计 - 第 2章 数据类型、运算符和表达式 70
函数 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章 数据类型、运算符和表达式 71
格式输出函数 printf
函数说明
int printf(char* format[,args...]);
格式化输出若干任意类型数据
参数说明
char* format 格式控制字符串
args 需要输出的数据列表,可以多个或没有
返回值
若成功,返回输出的字节数,包括换行符
若失败,返回 EOF (End of File)
C语言程序设计 - 第 2章 数据类型、运算符和表达式 72
函数 printf的参数说明
格式字符串
包括“格式说明”和“普通字符”
“格式说明”由 %和“格式字符”组成,将输出数据按指定格式输出
“普通字符”按原样输出
输出列表
需要输出的数据
可以是变量、常量、表达式、函数调用等
输出数据按顺序与“格式说明”对应输出
C语言程序设计 - 第 2章 数据类型、运算符和表达式 73
函数 printf的格式举例
printf("a=%d b=%d",a,b);
格式说明普通字符 输出列表输出结果 >a=3 b=4
C语言程序设计 - 第 2章 数据类型、运算符和表达式 74
格式字符格式字符 说 明
d,i 有符号十进制整数,正数不输出符号
o 无符号八进制整数,不输出前导 0
x,X 无符号十六进制整数,不输出前导 0x或 0X
u 无符号十进制整数
c 转换为无符号字符型,以此为 ASCII码输出一个字符
s 输出字符串,直到遇到 '\0'或达到指定宽度
f 小数形式单、双精度数,缺省精度为 6位小数
e,E 以规范化指数形式输出浮点数,缺省精度为 6位小数
g,G 以 f(F)和 e(E)两种格式中较短的一种输出
% 输出一个 %
C语言程序设计 - 第 2章 数据类型、运算符和表达式 75
附加格式字符格式字符 说 明
h 有符号或无符号短整型
l 有符号或无符号长整型
L 长双精度型
m 一个正整数,输出数据的最小宽度
n 一个正整数,输出的小数位数或字符串截取个数
,分隔 m和 n
- 输出的数字或字符向左靠齐
+ 输出的数字一直带符号,即正号也输出
0 输出的数字不满规定宽度时,用前导 0填充
有符号数字如果没有输出符号,则前面加一个空格
# 八进制和十六进制数加前缀,浮点数格式也有所改变
C语言程序设计 - 第 2章 数据类型、运算符和表达式 76
函数 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章 数据类型、运算符和表达式 77
格式输入函数 scanf
函数说明
int scanf(char* format[,addrs...]);
格式化输入若干任意类型数据
参数说明
char* format 格式控制字符串
addrs 需要输入的地址列表,可以有多个
返回值
返回输入并赋值的数据项的个数
C语言程序设计 - 第 2章 数据类型、运算符和表达式 78
函数 scanf使用说明
,地址列表”中是变量的地址,而非变量
scanf("%d",&i);
关于输入格式
格式字符串中的普通字符须按相应位置输入
除字符型 (%c)外,输入项之间用一个或多个空白字符分隔,包括空格、回车、制表符
空白字符会作为 %c对应的输入,如果需要输入下一个非空白字符,可以用 %1s
如规定了最大宽度,且输入数据超出宽度,
则按宽度截取数据
C语言程序设计 - 第 2章 数据类型、运算符和表达式 79
格式字符格式字符 说 明
d 有符号十进制整数
i 有符号整数,可以是八进制 (带前导 0)或十六进制
(带前导 0x或 0X)
o 有符号八进制整数,可以带或不带前导 0
x,X 有符号十六进制整数,可以带或不带前导 0x或 0X
u 无符号十进制整数
c 输入一个字符,包括空白字符
s 输入无空白字符的字符串,不需要用 ""括起来
f,e,E,g,G 浮点数,可以用小数形式或指数形式
% 输入一个 %
C语言程序设计 - 第 2章 数据类型、运算符和表达式 80
附加格式字符格式字符 说 明
h 有符号或无符号短整型
l 有符号或无符号长整型或双精度型
L 长双精度型
m 一个正整数,输入数据的最大宽度
* 需要输入数据,但是在赋值时被跳过
C语言程序设计 - 第 2章 数据类型、运算符和表达式 81
函数 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章 数据类型、运算符和表达式 82
简单的 C程序设计
例 1:输入球体半径,求球的体积。
例 2:输入大写字母,转换为小写字母。
3
3
4
rV
C语言程序设计 - 第 2章 数据类型、运算符和表达式 83
例 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章 数据类型、运算符和表达式 84
例 2:字母大小写转换 (02-06.C)
#include <stdio.h>
void main()
{
char cup,clow;
cup = getchar();
clow = cup + 'a' - 'A';
printf("%c\n",clow);
}
C语言程序设计 - 第 2章 数据类型、运算符和表达式 85
作 业习题 3.6,3.9,3.10,3.12(3)~(5)
习题 4.5,4.6,4.9
C语言程序设计 - 第 2章 数据类型、运算符和表达式 86
结束
The End