幻灯片 1 - 欢迎访问牡丹江医学院主页

Download Report

Transcript 幻灯片 1 - 欢迎访问牡丹江医学院主页

C语言程序设计
主讲:高照艳
第一章 C语言概述

2
主要内容:
C语言的发展
– C语言的特点
– 简单C程序介绍
– 算法
– 结构化程序设计
– C程序的执行过程
–
2015/7/21
1.1C语言的发展
3
C语言出现的历史背景
(1)C语言的发展源于人们希望用高级语言编写操作系统。
ALGOL60(高级语言) 60
->CPL(剑桥大学推出 接近硬件 规模大 难实现) 63
->BCPL (剑桥大学 简化CPL)
67
->B 语言
(贝尔实验室用B写了UNIX操作系统) 70
->C 语言 (用C改写了UNIX 90%,即第5版)
72-
73
->标准C (K&R 《The C Programming language》)78
-> ANSI C
83
(ANSI 美国国家标准化协会)
-> 87 ANSI C
-> ISO C
90 (ISO-国际标准化组织)
版本:Microsoft C、Turbo C、Borland C、Quick C
(2)C语言既具有高级语言特性,又具有低级语言特性-中
级语言。
2015/7/21
4
1. 2 C语言的特点

语言简洁,表达能力强,易于理解
–只有32个关键字,9种控制语句
32个关键字:(由系统定义,不能重作其它定义)
auto
break
case
char
const
continue default
do
double else
enum
extern
float
for
goto
if
int
long
register return
short
signed sizeof
static
struct
switch
typedef unsigned union
void
volatile
while
2015/7/21
5
9种控制语句:
if( )~else~
for( )~
while( )~
do~while( )
continue
break
switch
goto
return
2015/7/21
6
运算符丰富
34种运算符,运算能力强、效率高。

算术运算符:+ - * / % ++ -关系运算符:< <=
==
>
>=
!=
逻辑运算符:! && ||
位运算符 :<<
>>
~ | ^ &
赋值运算符:= 及其扩展
条件运算符:?:
逗号运算符:,
指针运算符:* &
求字节数
:sizeof
强制类型转换:(类型)
分量运算符:. ->
下标运算符:[]
其它
:( ) 2015/7/21
7
短整型short
•数据类型丰富
整 型
整型int
长整型long
数值类型
单精度型float
浮点型
基本类型
字符类型char
双精度型double
数组
C
数
据
类
型
结构体struct
构造类型
共用体union
枚举类型enum
指针类型
空类型void
定义类型typedef
2015/7/21
8
具有结构化的控制语句
 程序书写格式自由
 能进行位操作,能实现汇编语言的大部分
功能,可以直接对硬件进行操作
 语言生成的代码质量高,程序执行效率高
 可移植性好

2015/7/21
9
1. 3简单C程序介绍
例1.1编写程序,在屏幕上打印字符串“This
is a C program.\n”。
main()
{
printf(" This is a C program.\n");
}
2015/7/21
10
例1.2
/*求两数之和*/
main( )
{
int a , b , sum ;
/*定义变量*/
a=123 ;
b=456 ;
sum= a + b ;
printf (“Sum is %d\n”, sum) ;
}
Sum is 579
2015/7/21
11
例1.3 求两数之最大值
main( )
{
int a , b , c ;
scanf (”%d,%d”, &a, &b) ;
c=max(a , b) ;
/*调用自定义函数max */
printf (“max=%d\n”, c) ;
}
int max(int x , int y)
/*自定义函数*/
{ int z ;
if (x>y) z=x ;
else z=y ;
return(z) ;
}
2015/7/21
12
C程序结构
C程序
– 由函数构成
–必须有,且只能有一个main(主函数)
– 总是从main函数开始执行
 函数
– 由函数首部和函数体组成
– 函数首部指定函数名、函数参数、类型
– 函数体从 { 开始,到 } 结束
– 函数内有语句

2015/7/21
13
C程序结构(续)
语句
– 包括说明性语句、可执行语句
– 以 ;表示语句结束
 注释
–可以出现在程序的任何位置
– 用 /* 和 */ 括起来,必须成对出现
 书写格式
– C语言没有行的概念,书写格式自由。
– 习惯小写字母,缩进格式。

2015/7/21
1.4 程序的灵魂-算法

14
程序包括两方面内容:
1.对数据的描述。数据元素及各元素之间的关
系,即数据结构。
2.对操作的描述。即操作步骤,也就是算法。
程序 = 数据结构 + 算法
程序 =数据结构 + 算法
+ 程序设计方法 + 语言工具环境
说明:
高级语言的数据结构是以数据类型来体现的。
2015/7/21
1.4.1 算法

什么是算法
–

15
为解决某一应用问题而采用的解题步骤
算法的描述方式
–
用自然语言描述算法
–
用流程图描述算法
–
用N-S结构图描述算法
–
用计算机语言表示算法(即实现算法)
例如:输出两个数中的最大数
2015/7/21
用自然语言描述算法
16
第一步:输入x和y的值
第二步:比较x和y的值,如果x大于y,则
输出x的值,否则输出y的值。
例如当描述“输出10个
数中最大数”的算法时,
会冗长、难于理解
2015/7/21
用流程图描述算法
起止框
输入/输出框
17
开始
输入x和y
判断框
Y
处理框
x >y ?
N
z= y
z= x
流程线
输出z
结束
图1.5 用流程图描述算法
2015/7/21
用N-S结构图描述算法
18
输入x、y的值
x>y
T
F
z=x z=y
输出z的值
图1.7 用N-S结构图描述的算法
2015/7/21
19
•算法的特性
(1)有穷性。
(2)确定性。
(3)有效性。
(4)输入。
(5)输出。
第一章 1.1 引言
2015/7/21
1.4.2结构化程序设计

20
程序的三种基本结构
– 顺序结构程序:按照书写顺序依次执行语句
– 选择结构程序:按照条件判断选择执行语句
– 循环结构程序:通过条件控制循环执行语句
三种基本结构的共同点:
• 都是只有一个入口和一个出口;
• 结构内的每一个框都有机会被执行;
• 结构内没有死循环。
2015/7/21
21
结构化程序设计的三种基本结构:
1) 顺序结构
传统流程图
N-S流程图
开始
A
A
B
B
结束
其中:A、B为操作框,可由一条或多条语句实现。
2015/7/21
22
2) 选择结构(分支结构)
N-S流程图
传统流程图
入口
T
P
F
B
A
P
T
A
F
B
出口
其中:P为分支判断条件;
A、B必有一个且只有一个被执行;
A、B之一可是空操作,用 表示。
2015/7/21
23
3) 循环结构
当型循环——先判断后循环,有可能一次也不循环。
入口
P
F
当P为真
A
T
A
出口
其中:P为循环判断条件;
A为要重复执行的操作,称为循环体;
2015/7/21
24
直到型循环——先循环后判断,至少循环一次。
入口
A
F
A
直到P为真
P
T
出口
其中:P为循环判断条件;
A为要重复执行的操作,称为循环体;
2015/7/21
25
算法举例
例:计算5! (1×2×3×4×5)
1→t
1→i
当i≤5
t×i→t
i+1→i
输出 t
当型循环
1→t
1→i
t×i→t
i+1→i
直到 i>5
输出 t
直到型循环
2015/7/21
结构化程序设计的基本原则:

26
结构化程序设计的基本原则:
– 采用自顶向下、逐步细化的方法进行设计;
– 采用模块化原则和方法进行设计。即将大型
任务从上向下划分为多个功能模块,每个模
块又可以划分为若干子模块,然后分别进行
模块程序的编写;
– 每个模块都是用结构化程序实现,即都只能
由三种基本结构组成,并通过计算机语言的
结构化语句实现。
2015/7/21
27
1.5 C语言的上机操作步骤
一. 上机过程:
有错误
正确
编辑
编译
正确
有错误
运行
正确
2015/7/21
28
C程序的执行过程
1.源程序文件的建立和编辑
– 编写源程序,形成 .C文件
– 需用编辑工具:tc.exe、记事本
2.编译
– 编译源程序,形成目标程序 . Obj文件
– 需用编译工具 :tcc.exe
3.连接
– 连接OBJ文件和调用的库函数,形成运行程
序 .exe 文件
– 需用连接工具 :tlink.exe
4.运行 .exe 文件
2015/7/21
29
2.上机过
程流程图:
装载c程序
编辑c程序
运行c程序(ctrl+F9)
否
正确?
是
看结果(alt+F5)
是
运行下一程序?
否
退出
2015/7/21
30
3.编写、
运行C程序
时常用功
能键
F3(打开源程序)
F2(保存当前源程序)
F9(编译当前源程序)
CTRL+F9(运行当前源程序)
ALT+F5(查看运行结果)
2015/7/21
31
三、需要记住的TC中一些常用功能键
F1:帮助。
F2:将当前文件存盘。
F3:装载原有文件或给新文件命名。
F4:程序运行到光标所在行。
F5:放大或缩小活动窗口切换。
F6:开或关活动窗口切换。
F7:单步运行程序,跟踪进入函数内部运行。
F8:单步运行程序,不跟踪进入函数内部。
第一章 1.3 C语言集成开发环境
2015/7/21
实验报告
32
实验一
[实验目的]
[实验内容和步骤]
1.设计算法,写出程序
2.在TurboC下编辑,得到源程序(.c)
3.编译,得到目标文件(.obj)
4.连接,得到可执行文件(.exe)
5.分析结果
[实验体会]
2015/7/21
C程序设计
数据类型、运算符与表达式
数据类型、运算符与表达式
2.1
2.2
2.3
2.4
2.5
2.6
2.7
2.8
34
CHAPTER 2
数据类型
常量与变量
整型数据
实型数据
字符型数据
变量赋初值
混合运算
运算符与表达式
2015/7/21
数据类型、运算符与表达式
35
C的数据类型
 C语言提供的数据结构是以数据类型形式出现的
 数据在内存中存放的情况有数据类型决定
 数据的操作要依靠运算符实现,而数据和运算符共同组
成了表达式。
2015/7/21
数据类型、运算符与表达式
36
C的数据类型
整型
字符型
基本类型
单精度
实型(浮点型)
枚举类型
双精度
数组类型
数据类型
构造类型
结构体类型
共用体类型
指针类型
空类型
2015/7/21
37
3.2常量与变量
3.2.1常量和符号常量
1. 常量:在运行过程中,其值不能被改变的量称为常量。
分类:整型﹑实型﹑字符﹑字符串
2. 符号常量,用一个标识符代表的常量。
习惯上,符号常量名用大写,变量用小写,以示区别。
-1,0,123为整型常量

4.6, -1.23为实型常量

‘a’, ‘d’ 为字符常量

#define PRICE 255
A=PRICE*A+6
C=PRICE+C/120
PRICE是标识符,符号常量

2015/7/21
38
3.2.2
变 量
1. 变量:在程序运行过程中,其值可以改变的量称为变量。
2. 标识符:用来标识变量名、符号常量名、函数名、类型名
、数组名、文件名的有效字符序列称为标识符。
由字母、数字和下划线三种字符组成,且第一个字符
必须为字母或下划线。


合法的变量名如: average,abd, a, s2,
student_name, _init
不合法的变量名:M.D.John, 1a, #33, a>b
3. C 语言要求对变量“先定义,后使用”。
2015/7/21
3.3
3.3.1
39
整型数据
整型常量
由一系列数字组成。也可带有减号,但不使用加号。

十进制整数:123,-456,0

八进制整数:以0开头的数据,如:-011,0123

十六进制整数:以0x开头的数据,如:0x123
整型常量的分类根据其值的范围而决定其类型,
并可以赋值给类型相匹配的整型变量。
2015/7/21
3.3.2
整型变量
40
1.整数数据在内存中的存放形式
数据在内存中是以二进制形式存放的。
例如:3 =(0000000000000011)2
要区别:+3 和 -3
方法是:将符号也数码化
即: 正的符号 +用 0 表示
负的符号 -用 1 表示
数值是以补码表示的。
正数的补码和其原码的形式相同。
负数的补码:将该数的绝对值的二进制形式,
按位取反再加1 。
2015/7/21
41
2.整型变量的分类
整型… int 在内存中以二进制形式存放,每一个整型变量在内存中占2个字节。
短整型… 以short int表示或以short表示, 一般与int占有的内存相同。
长整形…以long int表示或以long表示,一般占有在内存中字节为int两倍。
无符号型…只能存放正整数,它的表示是在上述三种类型之前加上
unsigned
类型名称
整型
类型符
bit
取值范围
--215~215-1
int
16
(短整型)
无符号整型
short [int]
unsigned [int]
long [int]
长整型
无符号长整型 unsigned long [int]
(-32768~32767 )
16
32
32
0 ~216-1
(0~65535 )
-231~231- 1
0 ~2322015/7/21
-1
42
3. 整型变量的定义
对变量的定义一般放在函数的开头部分。
[例2.1]
main()
{
int a,b,c,d;
unsigned u;
a = 12; b =-24; u =10; c = a+u; d = b+u;
printf(“a + u = %d, b + u = % d\n”, c, d);
}
不同类型的数可以直接运算
a+u = 22, b+u =-14
2015/7/21
43
4.整型数据的溢出
main()
{int a,b;
a=32767;
b=a+1;
printf(“%d,%d”,a,b);
} 运行结果为
32767,-32768
3.3.3 整型常量的类型
① 一个整常量,其值在-2^15~2^15-1内可认为是 int 型,并可赋
值给 int 型和 long int 型变量;
② 一个整常量,其值在 –2^31 ~ 2^31-1 范围内则认为它是 long
int 型,可赋值给一个 long int 型变量;
③ 常量中无 unsigned 型,但一个非负值的整常量可以赋给
unsigned 型整变量;
2015/7/21
3.4
实型数据
44
3.4.1 实型常量
1.十进制小数形式(日常记数形式)
1.0 +12.0 -12.0
0.0
2.指数形式(科学记数形式)
<尾数>E(e)<整型指数>。例如3.0E+5
等。
1.类型:
3.4.2 实型变量
小数部分
指数部分
单精度:float,分配4 Byte
双精度:double,分配 8 Byte
2.存储:小数的符号位
指数的符号位
2015/7/21
实型数据的类型及规定
类型
类型符
45
单精度型 float
4
绝对值的范
围
10-38 ~ 1038
双精度型 double
8
10-308 ~10308
Byte
有效数字
15~16位
6~7位
实型常量不分float和double,根据范围赋值给相应的变量。
如:float
a; double b;
a=111111.111; b=111111.111
a中实际存储的是111111.1
(7位有效)
b中实际存储的是111111.111 (全部有效)
2015/7/21
3.5
字符型数据
46
3.5.1字符常量
1. 定义
用一对单引号括起来的单个字符,称为字符常量。
例如,‘A’、‘1’、‘+’等。
2.转义字符
C语言还允许使用一种特殊形式的字符常量,就是以反斜杠“\ ”
开头的字符序列。
\0
\n
\t
\"
\dd
d
\xh
字符串结束标志
回车换行
跳到下一个输出位置
双引号字符
ddd为1到3位八进制数所代表的字符
hh为1到2位十六进制数所代表的字符
2015/7/21
47
3.5.2 字符型变量
字符变量的类型关键字为char,一般占用1字节内存单元
。
1.变量值的存储
将一个字符常量存储到一个字符变量中,实际上是将该
字符的ASCII码值(无符号整数)存储到内存单元中。
例如:
char ch1, ch2; /*定义两个字符变量:ch1,ch2*/
ch1=’a’; ch2=’b’; /*给字符变量赋值*/
’a’、’b’的ASCII码为97、98 。
2.特性
1)字符数据在内存中存储的是字符的ASCII码;
2)C语言允许字符型数据与整型数据之间通用,可以互相
赋值。
3)字符数据也可以整数形式输出。
2015/7/21
48
[例1] 字符变量的字符形式输出和整数
形式输出。
main()
{ char c1,c2;
c1='a';
c2='b';
printf(“c1=%c,c2=%c\n”,c1,c2);
printf(“c1=%d,c2=%d\n”,c1,c2);
}
程序运行结果:
2015/7/21
49
[例2] 大小写字母的转换。
main()
{ char c1,c2;
c1='a'; c2='b';
c1=c1-32;c2=c2-32;
printf(“%c c2=%c\n”,c1,c2);
}
程序运行结果:
A B
2015/7/21
数据类型、运算符与表达式
3.5.3

50
字符型数据
字符串常量
用双引号括起来的字符序列。如:
“How do you do”, “CHINA”, “a”, “$ 123.34” 等。

字符串可以一次输出。如:
printf(“How do you do”);

C语言规定:在存储字符串常量时,由系统在字符串的
末尾自动加一个‘\0’作为字符串的结束标志。在内存
中,对字符串常量是采用字符数组表示,即用一个字符
型数组来存放一个字符串。
注意: ‘a’是字符常量,“a”是字符串常量,二者不
同。

2015/7/21
51
综上所述,字符常量'A'与字符串常量"A"是两回事:
(1)定界符不同:字符常量使用单引号,而字符串常
量使用双引号;
(2)长度不同:字符常量的长度固定为1,而字符串常
量的长度,可以是某个整数;
(3)存储要求不同:字符常量存储的是字符的ASCII码
值,而字符串常量,除了要存储有效的字符外,还要存
储一个结束标志’\0’。
2015/7/21
52
3.6
变量赋初值
在变量定义的同时可以为变量赋初值。
如:
int a=3;
(相当于 int a; a=3;)
float f = 3.56;
char c = ‘a’;
int a,b,c = 5 ; 表示只给c赋初值。
(相当于int a,b,c; c = 5;)
2015/7/21
53
3.7 各类数值型数据间的混合运算

不同类型的数据(整型、实型、字符型)可进行混合运算。
如:10 + ‘a’ + 1.5 - 8765.1234 * ‘b’

必须首先将它们转换成同一类型的数值。

转换原则是由低向高转换,运算结果为最高级别的类型。
高
double
float
long
表示必须要转换
表示由低向高
unsigned
低
int
char,short
2015/7/21
数据类型、运算符与表达式
54
混合运算
如:10 +‘a’ + i * f - d/e
int
+ double
double
–
double
double
2015/7/21
55
例2-5:
已知: float a=2.0; int b =6,c =3;
求解: a*b/c-1.5+ ’A’ +abs(-5)=?
12.0/3
4.0 - 1.5
2.5
+65(int)
5
67.5
72.5
第二章 2.3 运算符和表达式
2015/7/21
56
3.8 算术运算符和算术表达式
1.基本的算术运算: +、-、*、/、%
% 是模运算,即求余运算,要求整数。
如:7%4的结果是3。
说明:
5/3的结果仍是整数,小数部分被忽略。
5.3/3或5/3.0的结果为double型。
C编译系统将实型常量作为双精度来处理。如果参加+、-、*、/
运算的两个数中有一个数为实数,则结果是double型。
2.算术表达式:用算术运算符将运算对象按C的语法规则连接起的式子。
例如:a * b/c-1.5+‘a’
优先级(算术运算):
() * / %
+-
在同一级别中,采取由左至右的结合方向。
如:a-b+c 相当于 (a-b)+c
2015/7/21
57
3.强制类型转换运算符可将一个表达式转换成所需类型。
其一般形式为:(类型名)(表达式)
例如:(double) a
(int) (x+y)
(float) (5%3)
在强制类型转换时,得到一个所需类型的中间变量,
原来变量的类型未发生变化。
2015/7/21
练习
58
main( )
{
int i;
float x;
x=3.6;
i=(int)x;
printf(" x=%f,i=%d\n",x,i);
}
2015/7/21
数据类型、运算符与表达式
59
运算符和表达式
4.自增、自减运算符
使变量的值加1或减1。
如:++i, --i
在使用i之前,先使i的值加(减)1
i++, i--
在使用i之后,再使i的值加(减)1
例如:i的值为3,则
j= + + i; j的值为4,i的值为4
j= i + +; j的值为3,i的值为4
又如: printf(“%d”, ++i); 输出结果为4
printf(“%d”,i++); 输出结果为3
单独使用时, i++ , ++i 等价
2015/7/21
60
结合性:
例:
自右向左
i = 2;
j = -i++;
分析:
(1)++、--、+、-是同级运算符,结合方向:自右向左。
(2) -i++等价于
-(i++)
(3) 对于括号内的自增运算,要先使用i,再使i增加1。
运算结果: i的值为3,j的值为-2。
第二章 2.3 运算符和表达式
2015/7/21
练习
61
 a=1,b=2,c=3,d=4
 下列式子的值分别是多少?
 a*b/c
 a*b%c+1
 ++a*b-c--
2015/7/21
62
3.9 赋值运算符和赋值表达式
1.赋值运算符:“=” 。
2.复合赋值运算:在赋值符号前加上其它运算符号。
+=,-=,*=,/=,%=,<<=,>>=,&=,^=,|=
例如:
a + = 3;
等价于a = a + 3;
x * = y + 8; 等价于x = x * ( y + 8 );
x % = 3;
等价于x = x % 3;

赋值运算符仅优先于“,” ,且具有右结合性
例如:

a= b= b*c
等价于:a= (b=(b*c) )
赋值号与数学中的等号含义不同
例如:数学中 a=b 等价于 b=a
C语言中 a=b 不等价于 b=a
2015/7/21
3.赋值运算中的类型转换

<实型变量> = <整型表达式>
– 小数部分自动补0

<整型变量> = <实型表达式>
– 自动舍去实型表达式的小数部分(注意不进行四舍五入)

<字符变量> = <整型表达式>
<整型变量> = <长整型表达式>
– 自动截取表达式值的低字节赋值,舍去高字节



63
<整型变量> = <字符数据>
<长整型变量> = <整型表达式>
– 自动给高字节补0 或补1
2015/7/21
数据类型、运算符与表达式
64
运算符和表达式
4.赋值表达式:
由赋值运算符将一个变量和一个表达式连
接起来的式子。
一般形式为:<变量><赋值运算符><表达式>

例如:int a=12;求下列运算的结果
a+=a-=a * a
a=a-a * a=12-12 * 12=-132)
a+=-132
a=a+(-132)=(-132)+(-132)=-264
a=-264
2015/7/21
练习
65
int i=1,j=2,k=3,m=4;
 计算下列式子的值
 i+=j+k
 j*=k=m+5

2015/7/21
数据类型、运算符与表达式
66
运算符和表达式
3.10 逗号运算符和逗号表达式

逗号运算符又称为“顺序求值运算符”,是所有运算符
中级别最低的,它将两个表达式连接起来。 一般形式为
:表达式1,表达式2

求解过程是:先求解表达式1,再求解表达式2,整个逗
号表达式的值是表达式2的值。
例如: a=3*5, a*4;
(a=3*5, a*4), a+5;
a的值为15,表达式的值为60
a的值为15, 表达式的值为20
又如: x=(a=3, 6*3);
x=a=3, 6*a
x的值为18
x的值为3, 表达式的值为18
2015/7/21
第4章 最简单的C程序设计
-顺序程序设计
68
1
C语句概述
2
赋值语句
3
数据的输入输出
4
字符数据输入输出
5
格式输入输出
7
程序举例
2015/7/21
69
4.1 C语句概述
用C语言编写的程序称为C语言源程序,简称C程序。
C语言一般由一个或若干个函数组成,而这些函数可以保存在一个
或几个源程序中,这些文件都以.C作为文件扩展名。
C程序
源程序文件1
…
预编译命令
…
源程序文件i
函数1
变量申明部分
…
源程序文件n
函数n
执行部分(语句)
[例] 求园的面积
#DEFINE PI=3.1415926
main()
{ float r,s;
r = 20;
s = r * r * PI;
printf (“area=%f ”,s);
}
语句是计算
机执行的最
小单位
area=1256.637
2015/7/21
70
C语句分类
和其他高级语言一样,C语言的语句也是用来向计算机发出操作命
令的。一条语句经过编译后生成若干条机器指令。在C语言中只有可执
行语句,没有非执行语句。
C语句有以下五类:
⑴ 控制语句,完成一定的控制功能;
① if( ) ~ else ~
② for( ) ~
③ while( ) ~
④ do ~ while ( )
⑤ continue
⑥ break
⑦ Switch
⑧ goto
⑨ return
(条件语句)
(循环语句)
(循环语句)
(循环语句)
(结束本次循环语句)
(中止执行switch或循环语句)
(多分支选择语句)
(转向语句)
(从函数返回语句)
2015/7/21
71
⑵ 函数调用语句,由一次函数调用加一个分号构成一个语句,
如:printf (“This is a C statement.”);
⑶ 表达式语句,由一个表达式构成一个语句,
如: a=3
(是表达式,不是语句)
a=3;
(是语句)
⑷ 空语句,只有一个分号,什么也不做;
⑸ 复合语句,用{ }把一些语句括起来成为复合语句。相当一条语句,
哪里有语句,哪里就可用复合语句。
if (a>b) { max=a; min=b; }
复合语句最后一个语句中最后的分号不能忽略不写。
2015/7/21
72
4.2 赋值语句

赋值表达式后面加上分号,构成赋值语句。

功能:将数据赋给变量。
如: x=3.1; a=‘d’+ 123 + b/d;
程序中基本的命令行必须是一个语句,表达式不能单独构成语句。
例如: ‘d’+ 123 + b/d 是一个表达式
a =‘d’+ 123 + b/d;是一个赋值语句
特点:
① C语言中的赋值号“ = ”作为赋值运算符;

② 作为赋值表达式可以被包括在其他表达式之中;
if((a=b)>0) t=a;
③ 赋值语句可以连接赋值;
a=b=c=2;
2015/7/21
73
4.3 数据输入输出的概念
1. 所谓输入输出是以计算机主机为主体而言的。主机向外
部设备
-“输出” ,外部设备向主机-“输入”。
2.C语言本身不提供输入输出语句,输入和输出操作是由函
数实现。
C语言通过调用四个系统函数来实现输入输出。
printf(),scanf(),getchar(), putchar()
3.在使用C语言库函数时,要用到预编译命令“#include”将
有关的“头文件包括到用户源文件中。
在调用标准输入输出库函数时,文件开头应有以下预编译
命令:
#include<stdio.h>
或
#include”stdio.h”
2015/7/21
74
4.4 字符数据的输入输出
1.字符输出函数putchar()
向终端输出一个字符。
如:putchar(c);
输出变量c的值,c可以是字符型变量或整型变量。
[例3.1]
#include “stdio.h”
main()
{ char a,b,c;
a= ‘B’; b= ‘O’;c= ‘Y’;
putchar(a);putchar(b);putchar(c);
}
BOY
2015/7/21
75
也可以输出控制字符,如putchar(’\n’)输出一个换行符。
[例3.2]
#include <stdio.h>
main()
{ char a,b,c;
a= 'B'; b='O';c='Y';
putchar(a); putchar('\n'); putchar(b);
putchar('\n'); putchar(c); putchar('\n');
}

B
O
Y
输出其它转义字符
putchar(‘\101’); 输出 ‘A’;
putchar(‘\’’);
输出单引号
putchar(‘\015’); 使输出回车,不换行
2015/7/21
76
2.字符输入函数getchar()
从终端(或系统隐含指定的输入设备)输入一个字符。
一般形式为: getchar();
函数的值就是从输入设备得到的字符
[例]
#include “stdio.h”
main()
{ char c;
c=getchar();
putchar(c);
}
a↓
a
2015/7/21
77
[例]从键盘上输入一个大写字母,分别用大小
写字母形式输出,同时输出它们的ascii码。
#include “stdio.h”
main()
{char c1,c2;
c1=getchar();
printf(“%c,%d\n”,c1,c1);
c2=c1+32;
printf(“%c,%d\n”,c2,c2);
}
A↓
A ,65
a ,97
2015/7/21
78
4.5格式输入与输出函数
1.格式输出函数printf()
按规定格式向终端输出若干个任意类型的数据。
一般格式: printf(控制格式,输出列表)
用双引号括起的转换控制字
符串,它包括两种信息:
格式说明,
由%开始。如:%d,%f,%c
printf(“%d %d”,a,b)
格式说明 输出列表
被输出的数据,可以
是常量、变量、表达式
普通字符,要输出的字符
printf(“ a=%d b=%d”,a,b);
控制格式
输出列表
2015/7/21
79
printf()格式字符
说
明
格式
字符
d, i 以带符号的十进制形式输出整数
(正数不输出符号)
o
以8进制无符号形式输出整数(不
输出前导符0)
x, X 以16进制无符号形式输出整数(不
输出前导符0x)
u
以无符号10进制形式输出整数
c
以字符形式输出,只输出一个字符
s
输出字符串
f
以小数形式输出单、双精度数,隐
2015/7/21
80
printf()附加格式说明字符
字符
字母l
说
明
用于长整型整数,可加在格式符d、o、x、u前
面
m(代表一个正
整数)
数据最小宽度
.n(代表一个正
整数)
对实数,表示输出n位小数;对字符串,表示截
取的字符个数
输出的数字或字符在域内向左靠
例如:
%ld —— 输出十进制长整型数
%m.nf —— 右对齐,m位域宽,n位小数或n个字符
%-m.nf —— 左对齐
2015/7/21
81
例1. main()
{int
x1=123;
long x2=123456;
printf("x1=%d,x1=%5d,x1=%-5d,x1=%2d\n", x1,x1,x1,x1);
printf("x2=%ld,x2=%8ld,x2=%5ld\n",x2,x2,x2);
}
程序运行结果如下:
x1=123,x1=□□123,x1=123□□,x1=123
x2=123456,x2=□□123456,x2=123456
2015/7/21
82
例2.
main( )
{
int m=-1; long n=123456789;
printf(“m= %d, %o, %x, %u\n",m,m,m,m);
printf("n=%d\n",n);
printf("n=%ld\n",n);
}
程序输出:
1122
a=11, b=22
m= -1, 177777, ffff, 65535
n=-13035
n=123456789
2015/7/21
83
例3.
main( )
{ float f=123.456;
double d1,d2;
d1=1111111111111.111111111;
d2=2222222222222.222222222;
printf("%f,%12f,%12.2f,%12.2f,%.2f\n",f,f,f,f,f);
printf("d1+d2=%f\n",d1+d2);
}
程序运行结果如下:
123.456001,□□123.456001,□□□□□□123.46,123.46□□□□□□,123.46
d1+d2=3333333333333.333010
对于实数,也可使用格式符%e,以标准指数2015/7/21
最简单的C程序设计
84
数据输出
在使用printf()函数时要注意:
1. 有些系统要求格式字符必须用小写字母;
2. 格式控制符中,可包含转义字符;
3. 格式说明必须以“ % ”开头;
4. 欲输出字符 % 则应在“格式控制”字符串中用
连续两个 % 表示。
5. 不同的系统在实现格式输出时,输出结果可能
会有一些小的差别。
2015/7/21
85
2.格式输入函数scanf()
把从输入设备输入的数值按先后顺序存入在内存的
地址中去。

一般格式: scanf(格式控制,地址列表)
[例]
main()
{ int a,b,c;
scanf(“%d%d%d”,&a,&b,&c);
printf(“%d,%d,%d”,a ,b ,c);
}
3
4
5↓
3,4,5
2015/7/21
86
最简单的C程序设计
数据输入
scanf()格式字符
格式字符
d, i
o
x, X
c
s
f
e, E, g,
G
说
明
用来输入十进制整数
用来输入8进制整数
用来输入16进制整数
用来输入单个字符
用来输入字符串,将字符串送到一个字符数组中,
在输入时以非空白字符开始,以第一个空白字符
结束。字符串以串结束标志 ‘\0’ 作为其最后一个
字符。
用来输入实数,可以用小数形式或指数形式输入
与 f 作用相同,e 和 f、g 可以互相替换
2015/7/21
最简单的C程序设计
87
数据输入
scanf()附加格式说明字符
字符
字母l
说
明
用于输入长整型数据(可用%ld、
%lo、%lx),以及double型数
据(用%lf或%le)
字母h
用于输入短整型数据(可用
%hd、%ho、%hx)
指定输入数据所占宽度(列数)
域宽
(为一正
2015/7/21
88
在使用scanf()函数时要注意:

Scanf()函数中的“格式控制”后面应当是变量
地址;

如果在“格式控制”字符串中除了格式说明以
外还有其他字符,则在输入数据时应输入与这
些字符相同的字符;

在用“%c”格式输入字符时,空格字符和“转
义字符”都作为有效字符输入;

在输入数据时,遇到以下情况时该数据认为结
束:
①遇空格,或按回车;
②遇指定的宽度结束,如“%3d”,只取3列;
③遇非法输入
2015/7/21
89
4.6 顺序结构程序设计举例
[例] 输入三角形的边长,求三角形的面积。
area = √s*(s-a)*(s-b)*(s-c)
s = (a+b+c)/ 2
#include "stdio.h"
#include "math.h"
main()
{ float a,b,c,s,area;
scanf("%f,%f,%f", &a, &b, &c);
3,4,6 ↓
s = 1.0/2 * (a+b+c);
area = sqrt(s*(s-a)*(s-b)*(s-c));
printf("a=%7.2f,b=%7.2f,c=%7.2f,s=%7.2f\n", a,c,b,s);
printf("area=%7.2f\n",area);
}
a=
3.00, b=
area= 5.33
4.00, c=
6.00, s=
6.50
2015/7/21
逻辑运算符和逻辑表达式
If语句三种形式
条件运算符
Switch语句
第五章
选择结构程序设计
91
5.1 关系运算符和关系表达式
1.关系运算符

关系运算实际上是两个量的比较,比较的结果只有两种可能:
真(1)、假(0)。
例如: a > 3 ?
当a=5时,比较的结果为真;
当a=1时,结果为假。

C语言提供6种关系运算符
•<
(小于)
•<=
(小于或等于)
•>
(大于)
•>=
(大于或等于)
==
• !=
•
相等
不等
2015/7/21
92
2.关系表达式

用关系运算符或者等式运算符将两个表达式连接起来,叫关系表达式。

合法的关系表达式:
a>b、
a+b>b+c、
(a==3)>(b==5)、 ‘a’<‘b’、
(a=3)>(b=5)、
(a>b)>(b<c)

关系表达式的值是一个逻辑值,非真即假.
关系表达式 5==3的值为假(在计算机中记为0);
5>=0的值为真(在计算机中记为1)。

例:a=3, b=2, c=1, 则:
(1)a>b的值为1
(2)(a>b)==c的值为真(即1)
(3)b+c<a的值为0
(4)d=a>b中d的值为a>b的值,为1。
(5)f=a>b>c中f的值为1>c的值,为0。
2015/7/21
93
关系、等式和逻辑运算符
关于优先次序

<,<=,>,>=为同一级别, ==和!=为同一级别。

在同一级别中,采取由左至右的结合方向。

高
算术运算符
关系运算符
等式运算符
低
赋值运算符
[例]
c>a+b
a>b!=c
a==b<c
a=b>c
c>(a+b)
(a>b)!=c
a = = (b<c)
a = (b>c)
2015/7/21
94
5.2 逻辑运算符
逻辑运算:产生真假值的运算。
 逻辑运算符:
① &&
逻辑与(AND)
② ||
逻辑或(OR)
③ !
逻辑非(NOT)
 “&&”和“||”是双目运算符。
 “!”是一元运算符.
如:
a && b
a,b同时为真,则表达式为真
a || b
a,b只要有一个为真,表达式为真
!a
a为真,则表达式为假

a
b
!a
!b
a&&b
a||b
T
T
F
F
T
T
T
F
F
T
F
T
F
T
T
F
F
T
F
F
T
T
F
F
2015/7/21
95
关系、等式和逻辑运算符
逻辑运算符的优先级

!
&&
||
逻辑运算符 “&&” 和 “||” 低于关系运算符,“!”高于
算术运算符
!
算术
关系
逻辑
赋值
a>b && x>y 相当于: (a>b) && (x>y)
a==b||x==y 相当于: (a==b) || (x==y)
!a || a>b 相当于: (!a ) || (a>b)
2015/7/21
96
逻辑表达式

用逻辑运算符将关系表达式或逻辑量连接起来就是逻辑表达式。

在C语言中,当判断一个量的真假时,一切非0数均被当成‘真’来处
理。
例如:若a=4,
则!a的值为0
若a=4, b=5, 则a && b的值为1
a || b的值为1
!a || b的值为1
4 && 0||2 的值为1

区分下面的表达式中算术运算量,关系运算量和逻辑运算量:
5>3 && 2|| 8<4-!0 结果为1
5>3是两个数值间的比较,结果为1
1&& 2是两个非0值(逻辑量)间的运算,结果为1
1||8<4-!0,根据优先级,先计算!0,结果为1
2015/7/21
97
关系、等式和逻辑运算符
[例] 判断某一年是否是闰年。条件是:
能被4整除,但不能被100整除;
能被4整除,又能被400整除。
用year表示年份,判断闰年的逻辑表达式为:
(year%4==0 && year%100!=0)||(year % 400==0)
如果给year输入一个值,使上面的表达式的值为1时,则year所代
表的年份就是闰年。
变换一下角度,如何判断year不是闰年?
!( (year%4==0 && year%100!=0)||(year % 400==0) )
当year的值使表达式的值为1时,则year所代表的就不是闰年。
2015/7/21
98
5.3 if 语句
if 语句的三种形式

if用来判断给定的条件的真假,并决定执行哪一种操作。
1. if <表达式> 语句
条件满足时执行表达式后面的语句,然后继续执行以下的
语句。条件不满足时,越过if表达式后面的语句,往下执
行。
例如:如果输入的是正数,
假(0)
则打印出来。
表达式
if (x>0) printf("%d",x);
真(非0)
语句
2015/7/21
99
选择结构程序设计
if语句
if 语句的三种形式
2. if <表达式> 语句1 else 语句2
条件满足时,执行语句1,然后继续执行if以下的语句。
条件不满足时,执行语句2,然后继续执行if以下的语句。
真
表达式
假
P
Y
语句1
N
语句2
A
B
例如:输出两个数中较大的一个。
if (x>y) printf("%d",x) ;
else printf("%d",y);
2015/7/21
0
选择结构程序设计
if语句
if 语句的 第三种形式
if <表达式1> 语句1;
else if <表达式2> 语句2;
else if <表达式3> 语句3;
else if <表达式4> 语句4;
else 语句5
表达式1
真
假
表达式2
真
假
表达式3
真
语句1
语句2
语句3
假
表达式4
真
语句4
假
语句5
2015/7/21
选择结构程序设计
1
if语句
例如:商场促销,购物500元以上,8折;购物300元以上,85折;
购物100元以上,9折;购物50元以上,95折;购物50元以
下,不打折。根据消费量,计算优惠率。
设:消费量为 money; 折扣为 cost; 实际花费 price
if (money>500) cost=0.2;
else if (money>300) cost=0.15;
else if (money>100) cost=0.1;
else if (money>50) cost=0.05;
else cost=0;
price=money-(money*cost);
2015/7/21
选择结构程序设计
2
if语句
If 语句的嵌套

嵌套的定义:在if 语句中又包含一个或多个if 语句。

嵌套的一般形式:
If ( )
if ( )
语句1
else
语句2
Else
if ( )
语句3
else
语句4
(注意!! If 与else的配对关系。)
2015/7/21
3
[例] 比较两个整数的关系。
#include <stdio.h>
main( )
{ int x, y;
printf ("Enter integer X and Y:");
scanf ("%d%d", &x, &y);
if ( x != y )
if ( x > y ) printf ("X>Y\n");
else printf ("X<Y\n");
else printf ("X=Y\n");
}
2015/7/21
4
[例] 输入两个数,按数值大小次序排列输出.
main()
{ float a,b,t;
scanf("%f,%f", &a, &b);
if (a>b) { t=a; a=b; b=t;}
printf("%5.2f,%5.2f",a,b);
}
输入为
3.6, -3.2
输出为
-3.20, 3.60
2015/7/21
5
[例] 输入三个数,按由小到大次序排列并输出。
main()
{ flaot a,b,c,t;
scanf("%f,%f,%f", &a,&b,&c);
if (a>b) {t=a;a=b;b=t;}
if (a>c) {t=a;a=c;c=t;}
if (b>c) {t=b;b=c;c=t;}
printf("%5.2f,%5.2f,%5.2f",a,b,c);
}
输入为:
3,7,1
输出为:
1.00, 3.00, 7.00
2015/7/21
选择结构程序设计
6
程序举例
[例] 写一程序判断某一年是否是闰年.
main()
{ int year,leap;
printf("输入年份:");
scanf("%d",&year);
if ((year%4==0&& year%100!=0)||(year % 400==0)) leap=1;
else leap=0;
if (leap)
printf("%d is leap year\n",year);
else
printf("%d is not leap year\n",year);
}
输入年份:2004
2004 is leap year
2015/7/21
选择结构程序设计
7
if语句
条件运算符

max=(a>b)?a:b; 条件表达式
当(a>b)为真时,表达式取a的值
当(a>b)为假时,表达式取b的值

条件运算符是三目运算符
表达式1 ? 表达式2 : 表达式 3

条件运算符的结合方向为"从右向左"
例如:
a>b?a:c>d?c:d
相当于 a>b?a:(c>d?c:d)
如果a=1,b=2,c=3,d=4,则条件表达式的值为4。
2015/7/21
8
选择结构程序设计
[例]
y=
-1 (x<0)
0 (x=0)
1 (x>0)
Y
main()
{ int x, y;
Y = -1
scarf("%d", &x);
if (x==0) y=0;
else if (x>0) y=1;
else y=-1;
print("x=%d, y=%d\n", x, y);
}
输入为: 4
输出为:
if语句
开始
输入X
N
X<0
Y
Y=0
X=0
N
Y=1
输出Y
结束
x=4, y=1
2015/7/21
选择结构程序设计
9
if语句
[例] 输入一个字符,判断大小写,如是大写,则转换成小写,
输出。
main()
{ char c;
scanf("%c",&c);
c=(c>= 'A' && c<= 'Z')? (c+32):c;
printf("%c",c)
}
2015/7/21
0
5.4 switch语句
Switch语句是多分支选择语句,也叫开关语句或者选择语句。
一般形式:
switch (表达式)
{case常量表达式1: 语句1;
case常量表达式2: 语句2;
…………
case常量表达式n: 语句n;
default: 语句n+1;
}
功能:1.计算表达式的值,与常量表达式的值比较,等于第i个值时,顺
序执行语句序列i、i+1、 …、 n+1
2.若与所有常量表达式值都不相等,执行语句序列n+1。
如:switch (a)
如:switch (a)
{ case 5: printf("&");
{ case 5: printf("&"); break;
case 2: printf("#");
case 2: printf("#"); break;
default:printf("$");
default:printf("$"); break;
}
}
2015/7/21
选择结构程序设计
[例] 根据成绩等级打出成绩范围.
main()
{ char grade;
printf("Enter your grade\n");
scanf("%c",&grade);
switch(grade);
{ case 'A': printf("85~100\n"); break;
case 'B': printf("70~84\n"); break;
case 'C': printf("60~69\n"); break;
case 'D': printf("<60\n"); break;
default: printf("error\n");
}
}
111
switch语句
输入为
B
输出为
70~84
2015/7/21
2
选择结构程序设计
switch语句
流程图如下:
grade
'A'
输出
"85~100"
'B'
'C'
输出
"70~84"
输出
"60~69"
'D'
default
输出
"<60"
输出
"error"
2015/7/21
3
例:给出百分制成绩,要求输出等级 'A','B','C','D','E'。 90分以
上为'A', 80—89分为'B',70—79分为'C',60—69分为'D',60分以下
为'E'。
main()
{ int score,num;
char grade;
scanf("%d",&score);
num=score/10;
switch(num)
{ case 10: grade='A'; break;
case 9 : grade='A'; break;
case 8 : grade='B': break;
case 7 : grade='C'; break;
case 6 : grade='D'; break;
default : grade='E';
输入为 76
}
printf("%d %c",score,grade);
输出为 76
C
}
2015/7/21
选择结构程序设计
4
switch语句
switch语句的说明
1.
条件表达式的类型和常量表达式的类型是整数、字符。
2.
当表达式的值与某一个 case 后面的常量表达式的值相等时,就执行此
case 后面的语句,若所有的 case 中的常量表达式的值都没有与表达式
的值匹配,则执行 default 后面的语句。
3.
每一个 case 的常量表达式的值必须互不相同。
4.
case常量表达式只起语句标号作用;必须用break语句终止多个case连续
执行,否则只要有一个case满足后,以下的语句全部无条件执行。
5.
多个case可共用一组执行语句。
2015/7/21
5
循环控制
1
2
3
4
5
6
7
8
概述
goto语句
while语句
do-while语句
for语句
循环的嵌套
break语句和continue语句
程序举例
2015/7/21
6
6.1 概述


一般需要使用循环的情况是:
 有重复的动作(循环体)
 循环次数可以控制(循环条件)
 例如: 1+2+3+….+100
在C语言中可以用下列语句实现循环:
 goto 和 if 结合
 while
 do-while
 for
2015/7/21
6.2 goto 语句

7
Goto语句的一般形式: goto 语句标号;
……
语句标号:语句;

功能:无条件转向语句。

Goto 语句的常用形式: 1. 与 if 语句构成循环;
2. 从循环体中转到循环体外。
例:求1+2+3+…+100。
main()
{int i,sum=0; i=1;
loop:if(i<=100)
{sum=sum+i;
i++;
goto loop;}
printf(“%d\n”,sum);
}
2015/7/21
8
6.3
while语句

一般形式: While (表达式) 语句

功能:实现“当型"循环,"先判断,后执行"。表达式为真时(非0值)
,执行while语句的内嵌语句。

说明:
① <表达式>可以是关系表达式、
逻辑表达式或其它类型,表达
式后不允许有分号结尾;
② 语句可以是简单的,也可以是
复合的;
表达式
0
非0
语句
③ 循环体中应有使循环趋向于结
束的语句。
2015/7/21
9
[例] 求1+2+3+….+100 。
main()
{ int i=1,sum=0;
while (i<=100)
{ sum=sum+i; //累加器
i++;
}
printf("%d",sum);
}
i=1,sum=0
i<=100
sum=sum+i
i=i+1
输出 sum
如果有一个以上的语句循环,则必须用{ }构成复合语句。
要有修改循环变量的语句。
2015/7/21
0
6.4 do-while语句

一般形式:
do
循环语句
while(表达式);

功能: 实现“当型"循环结构。

说明:
语句
非 0(真)
表达式
0 (假)
① 当 while 后面的表达式的第一次的值为"真"时,两
种循环得到的结果相同。否则,二者结果不相同。
② do while 中的循环体至少执行一次,而 while 语句中
的循环语句可能一次都不执行。
2015/7/21
1
[例] 求1+2+3+….+100 。
main()
{ int i,sum=0; i=1;
do
{
sum=sum+i;
i++;
}
while (i<=100);
printf("%d",sum);
}
i=1,sum=0
sum=sum+i
i++
直到i>100
输出 sum
2015/7/21
2
6.5 for 语句
在C语言中用 for 语句构成的循环最为灵活。

一般形式:
for(表达式1;表达式2;表达式3)语句
求解表达式1

执行过程:
从图中可以看出FOR语句等价于
下列程序:
表达式1;
While (表达式2)
{语句
表达式3;
}

例:for (i=1;i<=100;i++) sum=sum+i;
表达式2
假
真
语句
求解表达式3
For语句的
下一语句
2015/7/21
3

说明:
① 语句的一般形式中的"表达式1"可以省略,此时应在语句之前给循
环变量赋初值(注意!省略表达式1时,其后的分号不能省略);
– 如:for (; i<=100;i++)
sum=sum+i;
② 如果表达式2省略,即不判断循环条件,循环无终止地进行下去;
– 如:for (i=1; ; i++)
sum=sum+1;
③ 表达式3也可以省略,但此时应另外设法保证循环能正常结束;
– 如:for (i=1;i<=100; )
{sum=sum+i; i++}
④ 可以省略表达式1和表达式3,只有表达式2,即只给循环条件;
如:for ( ;i<=100; )
{sum=sum+i;
i++}
⑤ for (; ;) 表示无限循环,相当于while (1)语句;
2015/7/21
循环控制

4
for语句
说明:
循环终止条件的种类:
(逻辑)关系表达式:
如:for (; a>b && x<y ;)
如:for (; (c=getchar( )) != '\n';)
printf("%c",c);

由以上说明可以看出,C语言中 for 语句的功能比其它语言
中的 for 语句功能要强、要灵活,它能替代 while 语句。
2015/7/21
[例]求n!=1 × 2 × 3 × …n
main()
{ double s=1;
int k;
for(k=1;k<=100;k++)
s=s*k;
printf(" s=%f ",s);
}
整数连乘结果一定是整数,而本例中结果数值相当大,用long
型都无法存放,因此将存放累乘结果的变量s定义为double型。
6
6.6

循环的嵌套
嵌套的概念:一个循环体内又包含另一个完整的循环结构,称为
循环的嵌套。
⑴ while( )
{…
while( )
{… }
}
(2) for( ; ; )
{
for ( ; ; )
{… }
}
(3) for( ; ; )
{…
while( )
{}
…
}
2015/7/21
7
6.7
break语句和continue语句

break语句 用来从循环体里退出,中止循环

Continue语句 用来跳过剩下的语句,回到循环开始
n
表达式1
表达式1
y
y
语句
表达式2
n
语句
y
n
break
y
continue
表达式2
n
语句
循环的下一个语句
语句
循环的下一个语句
2015/7/21
8
[例]把100…200之间不能被3整除的数输出。
main()
{ int n;
for (n=100; n<=200; n++)
{
if (n%3==0)
continue;
printf("%d",n);
}
}
2015/7/21
9
[例] 判断m是否是素数。
操作:用2~m-1依次去除m, 若其中有任意一个数被除尽,则没有必要再
判断下去,它肯定不是素数,跳出循环;若所有数都不能被除尽,则循
环可以自然完成。
#include "math.h"
main()
{int m, i, k;
scanf("%d",&m);
k=m-1;
for (i=2;i<=k;i++)
if ((m % i)==0) break;
if (i>k+1)
printf("%d is prime number\n",m);
else
printf("%d is not a prime\n",m);
}
或一个数x在[2,sqrt(x)]范围内没有因子,我们就称其为素数(质数)。
k=sqrt(m);
2015/7/21
0
[例] 打印出100到200之间所有的素数。
#include "math.h"
main()
{ int m, i, k,n=0;
for (m=101;m<=200;m=m+2)
{ k=sqrt(m);
for (i=2;i<=k;i++)
if (m% i==0) break;
if (i>k)
{printf("%d \n",m);
n=n+1;}
if(n%10==0) printf(“\n”);
}
printf(“\n”);
}
2015/7/21
1
[例] 用/41-1/3+1/5-1/7+…的公式求的近似值,直到最后一项的绝
对值小于10-6为止。
t=1,pi=0,n=1,s=1
当| t | 10-6
pi=pi+t
n=n+2
s=-s;
t=s/n
pi=pi*4
输出pi
#include "math.h"
main()
{ int s;
float n, t, pi;
t=1; pi=0; n=1.0; s=1;
while ((fabs(t))>=1e-6)
{ pi=pi+t;
n=n+2;
s=-s;
t=s/n;
}
pi=pi*4;
printf("pi=%10.6f\n",pi);
}
2015/7/21
2
[例] 裴波那契数列的第1、2项分别为1、1,从第3个数开始,
该数是其前面两项之和。即1,1,2,3,5,8,13,…求前40项菲波
那契数。
分析:f1--第一个数 f2--第二个数
f1=f1+f2 第三个数
f2=f2+f1 第四个数
main()
{ long f1=1, f2=1;
int i;
for(k=3;k<=20;k++)
{printf(" %12ld%12ld", f1,f2);
if(k%2==0) printf(" \n ");
f1=f1+f2;
f2=f2+f1;
}
}
2015/7/21
循环控制

三种循环语句:while, do---while 和 for

建立循环通常有以下情况:
1. 给定次数, for比较适用 for(i=1;i<100;i++)
2. 给定条件, while比较适用 while((x+y)<z)
3. 字符的情况通常以回车做结束符
while((c=getchar())!='\n')
4. 判断字符范围是否为英文字母
(c>'a' &&c <'z')||(c>'A'&& c<'Z')
3
本章总结
2015/7/21
4
【例】编程序,输出以下图形。
*******
*****
***
*
思路:
 一共有4 行,每行由空格和星号组成:空格数
按行增加,星号按行减少
 变量 i 控制输出行数, 从1变化到4
 变量 j 控制输出每行的空格和星号:
– j 从1变化到 i,每次输出一个空格
– j 从1变化到 8-2*i+1,每次输出一个星号
2015/7/21
算法和程序:
5
for (i=1; i<=4; i++)
for (j=1; j<=i; j++)
main( )
输出一个空格
{ int i,j;
for (j=1; j<=8-(2*i-1); j++)
for (i=1; i<=4; i++)
输出一个星号
{ for (j=1; j<=i; j++)
换行
printf(" ");
for (j=1;j<=8-(2*i-1);j++)
printf("*");
思考:
printf("\n");
 如何输出10行图形?
}
 输出图形向右平移20个字符
}
位置,应如何修改程序?
2015/7/21
总结
6
for(…;…; …)
 while( ){ }
 do{ } while( )…
 continue
 break
 goto

2015/7/21
7
[例] 打印图形。
main()
{ int i,j,k;
for(i=1;i<=4;i++)
{for(j=1;j<=4-i;j++)
printf(" ");
for(j=1;j<=2*i-1;j++)
printf("*");
printf("\n");
}
for(i=1;i<=3;i++)
{for(j=1;j<=i;j++)
printf(" ");
for(j=1;j<=7-2*I;j++)
}
*
***
*****
*******
分析:
行的控制 i:1~4
'*'的个数j与当前行的关系j=2*i-1
'*'前面的空格k与行的关系:
–开始时,第一行有3个空格
–每多一行,少一个空格k=4-i
while (i<=4)
{for (k=1,k<=4-i,k++)
输出空格;
for (j=1,j<=2*i-1 ,k++)
输出*;
}
2015/7/21
8
[例] 输入若干字母,将它们变成其后的第四个字母,A-->E,
W-->A,非字母字符忽略。
思路:
1.建立循环, 循环结束以输入回车
符为准 ;
while (c=getchar()!='\n')
2.判断输入是否是字符,否则忽略;
if ((c>='a' && c<='z') ||
(c>='A' && c<='Z'))
3.变成其后的第四个字母 c=c+4;
4. 若变换后超出z时,要轮回.
if ((c>'Z' && c<'a')||(c>'z'))
c=c-26
#include "stdio.h"
main()
{ char c;
while ((c=getchar())!='\n')
{ if ((c>='a' && c<='z') ||
(c>='A' && c<='Z'))
{c=c+4;
if ((c>'Z' && c<=‘Z‘+4 )||(c>'z'))
c=c-26;
}
printf("%c",c);
}
}
abdEgW
efhIkA`
2015/7/21
9
第七章
数组
6.1
一维数组的定义和引用
6.2
二维数组的定义和引用
6.3
字符数组
2015/7/21
0
在c语言中,除了前面介绍的基本类型之外,还有另外
一些数据类型---构造类型。其中数组就属于构造类型中的一种
。
数组是有序数据的集合。数组中的每一个元素都属于
同一个数据类型。用一个统一的数组名和下标来唯一的确定数
组中的元素。
7.1一维数组的定义和引用
一、定义

一般形式:类型说明符 数组名[常量表达式];
例如: int a[10];
1
20
4
60
9
3
98
0
11
a[0] a[1] a[2] a[3] a[4] a[5] a[6] a[7] a[8]
50
a[9]
2015/7/21
1
二、一维数组元素的引用

数组元素的引用形式: 数组名[下标]

每次可引用一个数组元素,不能引用整个数组

一个数组元素就如同一个简单变量
[例]
main()
{
int i, a[10];
for (i=0;i<=9;i++)
a[i]=i;
for (i=9; i>=0;i--)
printf("%d",a[i]);
}
9 8 7 6 5 4 3 2 1 0
2015/7/21
2
数组
一维数组的定义和引用
一维数组的初始化

初始化方法:从数组的第一个元素开始依次给出初始值表;表
中各值之间用逗号分开,并用一对大括号括起来。
 在定义数组时对数组元素赋予初值
int a[10]={0,1,2,3,4,5,6,7,8,9};
 只给一部分元素赋初值
int a[10]={0,1,2,3,4};
 欲使一个数组中全部元素初值为0,可以写成
int a[10] = {0,0,0,0,0,0,0,0,0,0,};或 int a[10]={0};
 在对全部数组元素赋初值时,可以不指定数组长度
int a[ ]={0,1,2,3,4,5};
2015/7/21
数组
3
一维数组的定义和引用
[例] 求Fibonacci数列 {1,1,2,3,5,8,13,21,...}
main() {
int f[20] = {1,1};
int i;
for (i = 2; i < 20; i++)
f[i]=f [i-2] + f [i-1];
for (i = 0;i < 20;i++)
{
if (i % 5 == 0) printf("\n");
printf("%12d",f[i]);
}
}
2015/7/21
4
[例] 用冒泡法对10个数排序。
{99 8 5 4 2 0 6 1 3 7}
8954206137
8 5 99 44 2 0 6 1 3 7
8549206137
第1次, a[0]和a[1]比较
第2次, a[1]和a[2]比较
8542906137
8542096137
8542069137
8542061937
8 5 4 2 0 6 1 39 7
8542061379
第i次, a[i]和a[i+1]比较
for (i=0;i<9;i++)
for (j=0;j<9-i;j++)
if (a[j]>a[j+1])
{
t=a[j];
a[j]=a[j+1];
a[j+1]=t;
}
2015/7/21
5
main()
{int a[11]
int i, j,t;
printf(“input 10 number:\n);
for (i = 1; i < 11; i++)
scanf(“%d”,&a[i]); //从键盘给数组元素赋值
printf(“\n”);
for (j = 1; j < =9; j++)
//排序
for (i = 1; i< =10-i; i++)
if (a[i] > a[i+1])
{t = a[i];
a[i] = a[i+1];
a[i+1] = t;
}
for (i = 1;i < 11;i++)
//输出数组元素
printf("%3d",a[i]);
}
2015/7/21
6
7.2 二维数组的定义和引用
一、二维数组的定义

一般形式:类型说明符 数组名[常量表达式][常量表达式];
例如: float a[3][4]
a[0][0] a[0][1] a[0][2] a[0][3]
a[1][0] a[1][1] a[1][2] a[1][3]
a[2][0] a[2][1] a[2][2] a[2][3]

二维数组在内存中的存放形式:
 "按行存放",即在内存中先存放第一行的元素,再存放
第二行的元素。
2015/7/21
7
多维数组的定义

多维数组的定义与二维数组相同。
 例如:三维数组 float a[2][3][4] 共有2×3×4=24个元素
 float a[100][100][100] 共有1000000个元素
a[0][0][0]
a[0][1][0]
a[99][99][99]
2015/7/21
8
二、二维数组元素的引用

二维数组元素的引用形式: 数组名[下标][下标]
三、二维数组的初始化

初始化方法:
 分行给二维数组赋初值
int a[3][4] = { {1,2,3,4}, {5,6,7,8}, {9,10,11,12} };
 可以将所有数据写在一个花括弧内,按数组排列的顺序对各元素赋
初值
int a[3][4] = {1,2,3,4,5,6,7,8,9,10,11,12};
 可以对部分元素赋初值,其余元素值自动为0
int
int
int
int
a[3][4] = { {1},
a[3][4] = { {1},
a[3][4] = { {1},
a[3][4] = { {1},
{5}, {9} };
{0,6}, {9,0,11} };
{5,6} };
{ }, {9} };
2015/7/21
9

初始化方法:
 如果对全部元素都赋初值,则定义数组时对第一维的长度可以
不指定,但第二维的长度不能省
int a[ ][4] = {1,2,3,4,5,6,7,8,9,10,11,12};
int a[ ][4] = { {0,2,3}, { }, {0,10} };

在程序中为数组赋值的方法:
 用scanf语句由用户输入
 由循环变量自动构成
for (i=0;i<3;i++)
for ( j=0;j<4;j++)
a[i][j] = 4*i+j+1;
for (i=0;i<=2;i++)
for (j=0;j<=3;j++)
scanf("%d",&a[i][j]);
1 2 3 4
5 6 7 8
9 10 11 12
2015/7/21
0
数组
二维数组的定义和引用
[例] 将一个二维数组行和列元素互换,存到另一个数组中。
a= 1 2 3
456
1 4
b= 2 5
3 6
for (i=0;i<3;i++)
for (j=0;j<2;j++)
b[i][j]=a[j][i]
2015/7/21
1
数组
二维数组的定义和引用
[例] 求出3*4矩阵中的最大值及其所在的行列号。
分析:
1.设一个变量存放最
大值max;
2.设两个变量row和
column存放最大值
在数组中的行列;
3.遍历数组中的每一
个元素。
max=a[0][0]
for i=0 to 2
for j=0
y
to 3
a[i][j]>max
n
max=a[i][j]
row=i
column=j
输出 max, row,column
2015/7/21
2
main()
{
int i,j,row,column,max;
int a[3][4]={{1,2,3,4},{9,8,7,6},{-10,10,-5,2}};
max=a[0][0];
for (i=0;i<3;i++)
for(j=0;j<4;j++)
if (a[i][j]>max)
{
max=a[i][j];
row=i;
column=j;
}
printf(“max=%d,row=%d,colum=%d\n", max, row, column);
}
2015/7/21
3
7.3 字符数组
一、字符数组的定义
字符数组: 可以存放若干个字符,也可以存放字符串。
字符串:字符串的末尾必须有’\0’字符,它的ASCII码值为0。
字符数组定义:char
ch i na \
0
数组名[exp];
如:char s[10];
s数组是一维字符数组,它可以存放10个字符或一个长度不大于9
的字符串。
2015/7/21
4
二、字符数组的初始化
1.逐个元素初始化。
例如:char c[10] = {'c', ' h', 'a', 'r' };
2. 说明:
 如果初值个数>数组长度,则作语法错误处理;
 如果初值个数<数组长度,则只将这些字符赋给数组中前面那些元素,其
余元素自动定为空字符(即’\0’);
 如果初值个数=数组长度,则在定义时可省略数组长度。
c
h
a
r
'\0'
'\0'
'\0' '\0'
'\0' '\0'
3. 用字符串来初始化字符数组
char a[11] =”I am a boy” ;
2015/7/21
三、字符数组的引用
5
main() /*输出一个钻石图形的程序*/
{
char diamond[ ][5]={{' ', ' ','*'},
{' ','*',' ','*'},
{'*' ,' ',' ', ' ','*'},
{' ','*', ' ','*'},
{' ',' ','*'}};
int i,j;
for (i=0;i<5;i++)
{ for (j=0;j<5;j++)
printf("%c",diamond[i][j]);
printf("\n");
}
}
2015/7/21
6
四、字符数组的输入输出
1.用格式符"%c"逐个输入/输出一个字符
scanf("%c",&a[0]);
printf("%c",a[0]);
2.用格式符"%S"整个输入/输出字符串
char c[10 ];
scanf(“%s”,c);
//注意此处用数组名
printf("%s",c); //注意此处用数组名
注意事项:


用“%s”格式输入或输出字符数组时,函数scanf的地址项、函数printf的输出
项都是字符数组名。这时数组名前不能再加“&”符号,因为数组名就是数组
的起始地址。
用语句“scanf("%s",s);”为字符数组s输入数据时,遇空格键或回车键时结
束输入。但所读入的字符串中不包含空格键或回车键,而是在字符串末尾添加
'\0'。
2015/7/21
7

同时输入多个字符串,输入数据时以空格或回车键为分隔符。
char str1[5],str2[5],str3[5];
scanf("%s%s%s",str1,str2,str3);
how are you?
h o w \0
str1
a r e \0
str2
y o u ? \0
str3
 如果改为:
char str[13];
scanf("%s",str);
how are you?
h o w \0
str
2015/7/21
8
五、字符串处理函数

函数是一个提供某种功能的程序段,可以通过名字调用,需要参数,
返回结果。
1. puts(str)
在显示器上输出str数组中的字符串,输出后自动换行。
例如:char str[ ]="China\nBiejing";
China
puts(str);
Beijing
2. gets(str)
从键盘读入一个字符串存入str数组中,并且得到一个函数值,该函数
值是str数组的首地址。
例如: gets(str);
输入为“How are you?” 则str中存有整个字符串及‘\0’。
main( )
程序运行情况如下:
{ char c1[20],c2[20];
How are you? 
gets(c1); gets(c2);
Fine thank you. 
puts(c1); puts(c2);
How are you?
}
Fine thank you.
2015/7/21
9
3. strcat(字符数组1,字符数组2)
连接两个字符数组中的字符串,把字符串2接到字符串1的后
面,结果放在字符串字符串1中,函数调用后得到一个函数
值——字符数组1的地址。
例如: char str1[30]={"People's Republic of "};
str2[ ]={"China"};
printf("%s", strcat(str1,str2));
输出: People's Republic of China
 字符数组1必须足够大,以便容纳连接后的新字符串。
 连接前两个字符串后面都有一个'\0',连接时将紧跟字符
串1后面的'\0'取消,只在新串最后保留一个'\0' 。
2015/7/21
0
4. strcpy(字符数组1,字符串2)
将字符串2拷贝到字符数组中,相当于赋值语句。
例如: char str1[10], str2[ ]={"China"};strcpy(str1,str2);
 字符数组1必须是写成数组名,字符串2 可以是数组名也
可以是一个字符串。 如:strcpy(str1, "china");
 不能用赋值语句将一个字符串常量或字符数组直接赋给
一个字符数组。但可以给一个字符变量或字符数组元素
赋值。
如:char str1[ ]={"China"},str2[20]; str2=str1;(╳)
 可以将字符串2前面若干个字符复制到字符数组1中去。
如:strcpy(str1, str2, 2);
2015/7/21
1
5. strcmp(字符串1,字符串2)
比较两个字符串的大小,即对两个字符串自左至右逐个字符相比
(ASCII值大的为大),直到出现不同的字符或遇到‘\0’为止。如
全部字符相同,则认为相等;若出现不同的字符,则以第一个不相同
的字符的比较结果为准。
如:“A”<“B”, “computer”>”compare”
返回值:
 零,两个串相等
 正数, str1>str2
 负数, str1<str2
注意:两个字符串不能用关系运算符比较
例如,下面的写法是不合法的:
if (str1==str2) printf("yes");
应写成 : if (strcmp(str1,str2)==0) printf("yes");
2015/7/21
数组
2
字符数组
6. strlen(字符数组)
测试字符串的长度。函数的值为字符串中的实际长度,不包
括'\0'在内。
例如:char str[10]={"China"};
printf ("%d", strlen(str));
5
7. strlwr(字符串)
将字符串中大写字母转换成小写字母。
8. strupr(字符串)
将字符串中小写字母转换成大写字母。
2015/7/21
3
例:输入一行字符,统计其中有多少个单词,单词之间用空格分隔开。
程序如下:
#include<stdio.h>
main()
{char string[81];
解题思路:单词的数目由空格出现的次数决定。若测出某
一个字符为非空格,而它的前面的字符是空格,则表示“
新的单词出现了”,此时使num累加1.
int i,num=0,word=0;
char c;
gets(string);
for(i=0;(c=string[i])!=‘\0’; i++)
if (c==‘ ‘) word=0;
else if(word==0)
{word=1;
运行如下:
Iam a boy.
there are 4 words in the line.
num++;}
printf(“there are %d words in the line.\n”,num);
}
2015/7/21
第八章
8.1
函数
4
概述
模块化程序设计:
基本思想:将一个大的程序按功能分割成一些小模块
特点:
各模块相对独立、功能单一、结构清晰、接口简单
控制了程序设计的复杂性
提高元件的可靠性
缩短开发周期
避免程序开发的重复劳动
易于维护和功能扩充
开发方法: 自顶向下,逐步分解,分而治之
2015/7/21
5
例:打印图形:
******************
How do you do!
******************
******************
编程:
main()
{ printf("******************\n");
printf(" How do you do!
printf("******************\n");
printf("******************\n");
}
则原程序可简化为:
\n");
三个语句一样,可编写成函数:
printstar()
{ printf("*********
*********\n");
}
main()
{ printstar();
printf(" How do you do!\n"):
printstar():
printstar();
}
2015/7/21
6
–
函数分类
从用户角度
– 标准函数(库函数):由系统提
供
– 用户自定义函数
从函数形式
– 无参函数
– 有参函数
2015/7/21
7
8.2

函数的一般形式
函数的定义形式
函数类型 函数名(形式参数表)
{ 说明部分
语句 int max(int x, int y) /*形式参数说明*/
{ int z;
/*函数体内部说明*/
z=x>y? x:y;
}
}
return(z);
/*返回值*/
2015/7/21
8
8.3 函数的参数和函数的值
一、形式参数和实际参数


在函数定义时指定的参数为形式参数(形参);
在函数调用时给出的参数叫实际参数(实参)。
main()
{ int a,b,c;
scanf("%d,%d",&a,&b);
c=max(a,b);
printf("Max is %d",c);
}
max(int x,int y)
{ int z;
z=x>y?x:y;
return(z);
}
2015/7/21
9
说明:
实参必须有确定的值
形参与实参类型一致,个数相同
参数传递方式为值传递方式:函数调用时,为形参分配单元,并将实参
的值复制到形参中;调用结束,形参单元被释放,实参单元仍保留并
维持原值。
特点:
形参与实参占用不同的内存单元;单向值传递。
2015/7/21
0
[例]
main()
{
int a,b;
a=2;b=3;
printf("%d %d",a,b);
change(a,b);
printf("%d %d",a,b);
}
change(int a,int b)
{
a=10;b=20;
printf("%d %d",a,b);
}
2 3
10 20
2 3
a 2
b 3
main 空间
a 2
b 3
change 空间
10
20
2015/7/21
1
二、函数的返回值

形式: return(表达式);
或
return 表达式;
功能:使程序控制从被调用函数返回到调用函数中,同时把返回值
带给调用函数
说明:
 函数中可有多个return语句
 若无return语句,遇 } 时,自动返回调用函数
 若函数类型与return语句中表达式值的类型不一致,按前者为
准,自动转换----函数调用转换
 void型函数用来明确表明函数不带回任何值

例 无返回值函数
void swap(int x,int y )
{ int temp;
temp=x; x=y; y=temp;}
2015/7/21
2

说明:
 函数类型决定返回值类型;
[例] main()
{
float a,b,c;
scanf("%f,%f",&a,&b);
c=max(a,b);
printf("Max is %f",c);
}
max(float x, float y)
{
float z;
z =x>y? x:y;
return(z); /*返回整数*/
}
1.5, 2.5
Max is 2.000000
2015/7/21
8.4 函数的调用
3
一、函数调用的一般形式
函数调用的一般形式: 函数名 (实参表列);
实参的个数、类型以及顺序必须与形参表一致。
二、函数调用的方式
1.
函数语句: 此时只要求函数完成一定的操作。
printstar();
1.
函数表达式:被调用函数出现在一个表达式中;函数返回一个值。
c=2*max(a,b);
2.
函数参数: 函数作为另一个函数的实参。
m = max(a, max(b,c));
printf("%d", max(a,b));
2015/7/21
4
二、对被调用函数的声明和函数原型
1.对被调用函数要求:
必须是已存在的函数
库函数: #include <*.h>
用户自定义函数: 主调函数对被调函数作函数声明,
对函数的声明称为函数原型
2.函数声明
• 一般形式:函数类型 函数名(形参类型1[形参名1],….. );
• 作用:告诉编译系统函数类型、参数个数及类型,以便检验
• 函数定义与函数声明不同
• 函数声明位置:程序的数据说明部分(函数内或外)
下列情况下,可不作函数声明
若函数返值是char或int型,系统自动按int型处理
被调用函数定义出现在主调函数之前
在所有的函数定义之前,在函数的外部已做了函数声明
2015/7/21
5
[例]
main()
{
float add(float x, float y); /*在主函数中对被调用函数进行声明*/
float a,b,c;
scanf("%f,%f",&a,&b);
c=add(a,b);
printf("sum is %f",c);
}
float add(float x, float y)
{
float z;
z=x+y;
return(z);
}
2015/7/21
6

8.5 函数的嵌套调用
– 嵌套调用
C规定:函数定义不可嵌套,但可以嵌套调用函数
main( )

a函数

调用函数a


b函数


调用函数b



结束
2015/7/21
7
8.6
函数的递归调用
 递归调用的概念:在调用一个函数的过程中又出现直接或间接的调
用该函数本身—递归调用。
f函数
调用f函数
 递归的说明
:
 递归必须是有条件的;程序中只应出现有限次数的、有终止的递
归调用;
 递归函数的执行在时间和空间上都不节省,但从算法角度讲,
结构清晰,代码紧凑;
 每调用函数一次,在内存堆栈区分配空间,用于存放函数变量、
返回值等信息,所以递归次数过多,可能引起堆栈溢出
 在实际使用时,除非特殊需要一般尽量不采用递归调用。
2015/7/21
8
例: 5个人坐一起,问第5个人多少岁?他说比第4个人大2岁。问第4个人多少
岁?他说比第3个人大2岁。问第3个人多少岁?他说比第2个人大2岁。问第1
个人多少岁?他说10岁。请问第5个人多大?
主函数
2
1
3
4
2
3
1
返回
age(5)
age(5)
=age(4)+2
=18
递
归
调
用
age(4 )
=age(3)+2
/int age (int n)
{ int c;
if(n==1) c=10;
else c=age(n-1)+2;
return(c);
}
main()
{ printf("%d\n",age(5));
}
递
归
返
回
age(4)
=16
age(3)
age(3)
=age(2)+2
=14
age(2)
age(2)
=age(1)+2
=12
age(1)
=10
2015/7/21
9
[例] 求一个自然数的阶乘。
n!= 1
(n=0,1)
n*(n-1)! (n>1)
float fac (int n)
{
float f;
if (n==0 || n==1) f=1;
else f=n*fac(n-1);
return(f);
}
main()
{int n; float y;
scanf(“%d”,&n);
y=fac(n);
printf(“%d!=10.0f”,n,y);
}
运行情况如下:
10!= 3628800
2015/7/21
0
8.7 数组作为函数参数
数组元素和整个数组均可以作为实参和形参。
1.
数组元素做函数实参:值传递
[例]比较两个数组的对应元素,比较过程在函数中完成,比较结果在主函数中输出。
main()
{int a[10],b[10],i,n=0,m=0,k=0;
printf("输入数组 a:\n");
for (i=0;i<10;i++)
scanf("%d",&a[i]);
large(int x, int y)
printf("输入数组b:\n");
{
for (i=0;i<10;i++)
int flag;
scanf("%d",&b[i]);
}
for (i=0;i<10;i++)
{ if(large(a[i],b[i])==1) n++;
else if (large(a[i],b[i])==0) m++;
else k++;
}
}
printf("a>b%d次\na=b%d次\na<b%d次\n",n,m,k);
if (x>y) flag=1;
else if(x<y) flag=-1
else flag=0;
return(flag);
2015/7/21
1
2. 用数组名作函数参数:地址传递(双向传递)
 用数组名作函数参数,应该在主调函数和被调函数中分别定义
数组;
 实参数组与形参数组类型应一致;
 形参数组可以不指定大小,定义时在数组名后跟一个空的方括
号;
 数组名作函数参数时不是“值传送”,而是把实参数组从起始地
址传送给形参数组,“地址传递”。
 形参和实参共用一个存储空间。形参的改变会导致实参的改变。
2015/7/21
2
[例]一维数组score内放10个学生成绩,求平均成绩。
float average (float array[10])
{
int i;
float aver;
sum = array[0];
for (i = 1;i<10;i++)
sum=sum+array[i];
aver = sum/10;
return(aver);
}
score
main()
{
float score[10], aver;
int i;
for (i = 0;i < 10;i++)
scanf("%d",&score[i]);
aver = average(score);
printf("average score is %5.2f",aver);
}
0
12
1
23
2
.
56
….
….
9
88
.
array
2015/7/21
3
8.8 局部变量与全局变量
一、局部变量
– 局部变量也称为内部变量
定义:在函数内定义,只在本函数内
局部变量
有效
float f1( int a) {
说明:
int b,c;
…
a,b,c有效
– main中定义的变量只在main
}
char f2( int x,int y) {
int i,j;
x,y,i,j有效
…
}
main() {
int y,m,n;
…
y,m,n有效
}
中有效
– 不同函数中同名变量,占不同
内存单元
例:不同函数中同名变量
– 形参属于局部变量
2015/7/21
4

二、 全局变量
– 全局变量也称为外部变量
定义:在函数外定义,可为本文件其
他函数共用
有效范围:从定义变量的位置开始到
本源文件结束。
说明:
– 设全局变量的作用增加了数据联
系的渠道
– 为区别局部与全局变量,习惯将
全局变量的第一个字母大写
– 应尽量少使用全局变量,因为:
2015/7/21
5
int p=1,q=5;
float f1(int a)
{ int b,c;
…….
}
int f3()
{…..
}
char c1,c2;
char f2(int x,int y)
{ int i,j;
……
}
main()
{ int m,n;
…….
}
p,q作用范围
c1,c2作用范围
2015/7/21
8.9
一、

变量的存储类别
动态存储方式与静态存储方式
从变量存在的时间(生存期)分动态与静态
两种存储方式
–静态存储:程序运行期间分配固
定存储空间
–动态存储:程序运行期间根据需
要动态分配存储空间
 生存期

内存用户区
–静态:
束
从程序开始执行到程序结
7
用户区
程序区
静态存储区
(全局变量)
动态存储区
(函数形参变量、
自动变量、
函数调用时的现场
保护和返回地址)
在程序开始执行时给全局变量分配存
储区,在程序执行过程中占据固定的
存储单元,程序执行完毕才释放。
在函数调用开始时分配动态存储空间,
函数结束时即释放这些空间。
(1) auto int x;
(2) static int y;
(3) register int i;
(4) int z;
extern z;
2015/7/21
8
二、auto变量
函数中的局部变量,如不专门声明为static存储类别,都是动态地分配
存储空间的,数据存储在动态存储区中。这类局部变量称为自动变量。
三、用static声明局部变量
如果希望函数中的局部变量的值在函数调用结束后不消失而保留原值
,即其占用的存储单元不释放,在下一次函数调用时,该变量的值为上一
次函数调用结束时的值,这时应指定该局部变量为"静态局部变量"。
在下列情况下使用静态局部变量:
 需要保留函数上一次调用结束时的值;
 如果初始化后,变量只被引用而不改变其值,则使用静态局部变量比
较方便,以免每次调用时重新赋值。
2015/7/21
9
四、register变量

如果有些变量使用频繁,则为存取变量的值要花不少时间,为提高执
行效率,C语言允许将局部变量的值放在CPU中的寄存器中,需要时
直接从寄存器中取出参加运算,不必再到内存中去存取。这种变量称
为"寄存器变量"。

说明:
 只有局部自动变量和形式参数可作为寄存器变量;在调用一个函数
时占用一些寄存器以存放寄存器变量的值,函数调用结束时释放
寄存器。
五、 用extern声明外部变量


全局变量是在函数外部定义的,有效范围从定义变量的位置开始到
本源文件结束。静态存储。
可以使用extern 扩展外部变量的作用域。
在一个文件内声明外部变量:在定义外部变量的定义点之前的函数想
引用该外部变量,则在引用之前用关键字extern做“外部变量声明”,
声明时类型名可省略。
2015/7/21
0
六、存储类别小结
局部变量
存储类别
存储方式
存储区
生存期
auto
register
外部变量
局部static
动态
动态区
外部
外部static
静态
寄存器
静态存储区
函数调用开始至结束
程序整个运行期间
作用域
定义变量的函数或复合语句内
本文件
其它文件
赋初值
每次函数调用时
编译时赋初值,只赋一次
未赋初值
不确定
自动赋初值0或空字符
局部变量默认为auto型
extern不是变量定义,可扩展外部变量作用域
2015/7/21
1
七、内部函数和外部函数
根据函数能否被其他源文件调用,将函数区分为内部函数和外
部函数。

内部函数:如果一个函数只能被本文件中其他函数所调用,称为内部
函数,又称静态函数。
static 类型标识符 函数名(形参表)

外部函数:
 在定义函数时,如果在函数首部的最左端冠以关键字extern,则
表示次函数为外部函数,可供其他文件调用;
 C语言规定,若定义时省略extern,则隐含为外部函数。
2015/7/21
第九章
2
预处理命令
作用:对源程序编译之前做一些处理, 生成扩展C源程序
种类:
宏定义
#define
文件包含
#include
条件编译
#if--#else--#endif 等
格式:
“#”开头
语句尾不加分号
2015/7/21
3
9.1 宏定义
一、不带参数的宏定义
命令的一般格式:
#define
宏名
字符串
宏定义的功能:
在进行编译前,用字符串原样替换程序中的宏名。

这个替换过程称为“宏替换”或“宏展开”,字符串也
称为替换文本。

2015/7/21
4
源程序:
#define
#define
main(
{float
)


PI
S
3.14159
PI*r*r

编译预处理后的程序:

main( )
{ float r;
scanf("%f",&r);
printf("S=%.2f
\n",3.14159*r*r);
}



r;
scanf("%f",&r);

printf("S=%.2f \n",S);
}
进入编译
2015/7/21
5
二、 带参数的宏定义
命令的一般形式
#define
宏名(形参表)
字符串
例: #define S(a,b) a*b
………..
area=S(3,2);
宏展开:area =3*2;
功能:
在编译预处理时,把源程序中所有带参数的宏名用宏定
义中的字符串替换,并且用宏名后圆括号中的实参替换字符
串中的形参。
2015/7/21
6







【例】
#define MAX(x,y) ((x)>(y)?(x):(y))
main( )
{…
printf("%d\n",a,b, MAX(a,b));
printf("%d\n",MAX(a+m,b+n));
}
分两次替换:
①将宏名MAX(a,b) 替换成字符串 ((x)>(y)?(x):(y))。
②用实参a替换形参x,实参b替换形参y。
程序中的两个printf语句被展开为:
printf("%d\n", ((a)>(b)?(a):(b)));
printf("%d\n", ((a+m)>(b+n)?( a+m):( b+n)));
2015/7/21
7

9.2 文件包含
 功能:一个源文件可将另一个源文件的内容全部
包含进来
–
–
一般形式: #include “文件名”
或: #include
<文件名>
 处理过程:预编译时,
用被包含文件的内容取
代该预处理命令,再对“包含”后的文件作一
个源文件编译
#include “file2.c”
B
B
A
A
file2.c
file1.c
file1.c
2015/7/21
8
–
被包含文件内容
 源文件(*.c)
 头文件(*.h)
–
C
宏定义
数据结构定义
函数说明等
B
file1.c
A
文件包含可嵌套
#include “file2.c”
#include “file3.c”
C
A
B
file3.c
file1.c
file2.c
2015/7/21
9
例 文件包含举例
/* powers.h */
#define sqr(x) ((x)*(x))
#define cube(x) ((x)*(x)*(x))
#define quad(x) ((x)*(x)*(x)*(x))
#include <stdio.h>
#include "powers.h"
#define MAX_POWER 10
void main()
{ int n;
printf("number\t exp2\t exp3\t exp4\n");
printf("----\t----\t-----\t------\n");
for(n=1;n<=MAX_POWER;n++)
printf("%2d\t %3d\t %4d\t %5d\n",n,sqr(n),cube(n),quad(n));
}
2015/7/21

0
9.3 条件编译
– 功能:对一部分内容指定编译的条件。
– 一般形式:条件编译命令有以下几种形式:
1.
2.
3.
#ifdef 标识符
程序段1
[ #else
程序段2]
#endif
#ifndef 标识符
程序段1
[ #else
程序段2]
#endif
#if 表达式
程序段1
#else
作用是:当标识符已经被定义
过,则编译程序段1,否则编译程
序段2。#else部分可以省略。
作用是:当标识符没有被定义
过,则编译程序段1,否则编译程
序段2。#else部分可以省略。
作用是:当表达式的值为真,
则编译程序段1,否则编译程序段2。
2015/7/21
1
2015/7/21
2
例 输入一行字母,根据需要设置条件编译,使之能将字
母全部改为大写输出,或全改为小写字母输出。
#define LETTER 1
main()
{ char str[20]="C Language",c;
int i;
i=0;
while((c=str[i])!='\0')
{ i++;
#if LETTER
if (c>='a'&&c<='z') c=c-32;
#else
if(c>='A'&&c<='Z') c=c+32;
#endif
printf("%c",c);
}
printf("\n");
}
2015/7/21