语言程序设计实例教程中国高等职业技术教育研究会推荐丁爱萍 刘瑞新 庄建敏 编高 职 系 列 教 材西安电子科技大学出版社出版
h t t p,/ / w w w,x d u p h,c o m
第 1章 程序设计与 C语言第 2章 C语言程序设计初步知识第 3章 简单程序设计第 4章 选择结构程序设计第 5章 循环结构程序设计第 6章 数 组第 7章 函 数第 8章 指 针第 9章 编译预处理第 10章 结构体和共用体第 11章 位运算第 12章 文 件第 13章 程序调试与常见错误分析目录退出第 1章 程序设计与 C语言
1.1 程序设计的基本概念
1.2 算法
1.3 结构化程序及设计步骤
1.4 C语言的特点
1.5 C语言程序的基本结构
1.6 C程序的上机操作返回主目录
1.1 程序设计的基本概念
1.1.1 程序电子计算机只是一种以二进制数据形式在内部存储信息,以程序存储为基础,由程序自动控制的电子设备 。
程序是一条条有序指令的集合 。
第 1章 程序设计与 C语言
1.1.2 计算机语言程序设计语言是实现程序设计,以便人与计算机进行信息交流的必备工具,又称计算机语言 。 目前,社会上广泛使用的是高级语言,
是一种接近人们习惯的程序设计语言,它使用人们所熟悉的文字,符号及数学表达式来编写程序,使程序的编写和操作都显得十分方便 。
第 1章 程序设计与 C语言由高级语言编写的程序称为“源程序”。
在计算机内部,源程序必须翻译为机器能够接受的二进制代码所表示的“目标程序”(也称机器语言)。其中,具有这种翻译功能的程序称为
“编译程序”,如图 1.1所示。
源程序 编译程序 目标程序图 1.1 源程序编译过程第 1章 程序设计与 C语言
1.1.3 程序设计程序设计的一般步骤:
1,确定数据结构 。
2,确定算法 。
3,编程 。
4,调试 。
5 整理源程序并总结资料。
第 1章 程序设计与 C语言返回章目录
1.2 算法所谓算法,是为解决某一特定的问题,所给出的一系列确切的,有限的操作步骤 。
1.2.1 算法设计程序实际上是用计算机语言所描述的算法 。 也就是说,依据算法所给定的步骤,用计算机语言所规定的表达形式去实现这些步骤,即为源程序 。
在算法设计中应遵循的准则:
(1) 可执行性 。
(2) 确定性 。
(3) 有穷性 。
(4) 输入 。
(5) 输出 。
第 1章 程序设计与 C语言
1.2.2 算法的描述目前,对算法的描述,一般采用自然语言,
一般流程图或 N-S结构流程图 。
常用一般流程图符号如图 1.2所示 。
处理框 输入输出框 判断框 流程线图 1.2 常用流程图符号第 1章 程序设计与 C语言返回章目录
1.3 结构化程序及设计步骤
1.3.1 结构化程序设计的概念结构化程序由 3种基本结构组成:顺序结构,选择结构,循环结构 。 使用这基本结构编写的程序,称为结构化程序 。
第 1章 程序设计与 C语言
1,顺序结构程序中的语句按先后顺序逐条执行。
s=a+b
输出
b=4
a=3
a=3
b=4
s=a+b
输出 s
图 1.4 顺序结构流程图
( a)一般流程图;( b) N-S结构流程图
(a) (b)
第 1章 程序设计与 C语言
2,选择结构在执行程序中的选择结构语句时,该语句的执行将根据不同的条件执行不同分支的语句。
图 1.5 选择结构流程图
(a) 一般流程图; (b)?N-S结构流程图
a>b
max=a max=b
输出 max
noyes a>b
yes no
max=a max=b
(a) (b)
第 1章 程序设计与 C语言
3,循环结构在执行程序中的循环结构语句时,该语句将根据各自的条件,对循环结构所限定的语句 ( 即循环体 ) 重复执行多次或零次 。
循环结构又分为当型循环和直到型循环两种情况。
1)当型循环该循环的特点是:当条件满足时,就执行循环体,否则就退出循环结构。
第 1章 程序设计与 C语言图 1.6 当型循环流程图
( a)一般流程图;( b) N-S结构流程图
i=1,t=1
第 1章 程序设计与 C语言
(a)
i<=n
输出 t
i=1,t=1
输入 n
循环体
t=t*i
i=i+1
no
yes
循环条件 i<=n
循环体
t=t*i
i=i+1
输出 t
(b)
2) 直到型循环该循环的特点是:先执行循环体,再判断循环条件,条件不满足时,就退出循环结构。
图 1.7 直到型循环流程图
(a)一般流程图; (b) N-S结构流程图
i=1,t=1
输入 n
循环体
t=t*i
i=i+1
i<=n?
输出 t
yes
no
i=1,t=1
循环体
t=t*i
i=i+1
循环条件 i<=n
输出 t
(b)
(a)
第 1章 程序设计与 C语言
1.3.2 结构化程序设计步骤结构化程序设计步骤与前面一般程序设计步骤大体相同,其步骤如图 1.8所示。
编程算法设计 调试运行确定数学模型数据结构分析问题图 1.8 结构化程序设计步骤框图第 1章 程序设计与 C语言返回章目录
1.4 C语言的特点
C语言主要特点如下:
(1) C语言是一种模块化程序设计语言 。
(2) 语言简洁,结构紧凑,程序书写方便,
实用灵活 。
(3) 运算符丰富,数据处理能力强 。
(4) 数据类型丰富 。
(5) 具有结构化的控制语句 。
(6) 可移植性好 。
(7) 用小写字母书写程序 。
(8) 使用方便,完好的集成开发环境。
第 1章 程序设计与 C语言返回章目录
1.5 C语言程序的基本结构一个 C语言程序至少包含一个主函数 ( main
函数 ) 或若干个其它函数 。
C语言程序结构有以下特点:
(1) C语言是由函数组成的 。 程序必须包含一个 main函数,也可包含若干个其它函数 。 程序的全部工作由函数来完成 。
(2) 程序总是从 main( )函数开始执行 。 由
main函数开始调用其它函数 。 其它函数间也可以相互调用,最终返回主函数结束程序 。
第 1章 程序设计与 C语言
(3) 一个函数由两个组成部分 。
a,函数的说明部分:确定函数名并说明函数类型,函数的形式参数名及其类型 。
b,函数体:由函数说明部分下的第 1对花括号 { }内的若干语句构成 。
(4) 程序书写较自由,一行可写几条语句,
一条语句也可以分行书写 。
(5) 分号是一条 C语言的结束符 。
(6) 在每条 C语句后,可用/ * … * /对该语句进行注解,以增加程序的可读性。
第 1章 程序设计与 C语言返回章目录
1.6 C程序的上机操作
1.6.1 Turbo C的安装
1.6.2 Turbo C的使用
1,启动 Turbo C
启动 Turbo C应在 DOS方式下执行如下命令:
C:\> CD\TC 〈 回车 〉
C:\TC> TC 〈 回车 〉
启动成功后,屏幕上将显示 Turbo C的主菜单窗口 。
2,选择用户文件的存放目录选择,File‖菜单中的,Change dir‖项后回车,弹出子目录提示框。在该提示框中输入用户文件的存放目录,
输入完后按回车键即可。
第 1章 程序设计与 C语言
3,建立工作环境操作步骤如下:
(1) 按 〈 F10〉 键,选择,Option‖菜单并按回车键 。
(2) 在,Option‖子菜单中选择,Directories‖选项并按回车键,将弹出子菜单 。
,Include directories‖选项:说明标准包含文件的目录 。
,Library directory‖选项:说明 Turbo C运行时库文件所在的目录 。
,Output directory‖选项:即编译,连接后的可执行文件所存放的目录 。
,Turbro C directory‖选项:即 Turbo C文件所在的目录 。
第 1章 程序设计与 C语言
4,编写源程序操作步骤如下:
(1) 在主菜单中选择,File‖选项并按回车键 。
(2) 在,File‖的下拉菜单中,选择,Load‖选项,屏幕将出现一个提示框 。
用户输入要编辑的文件名并按回即可,将进入全屏幕编辑状态 。
第 1章 程序设计与 C语言
5,常用编辑键
〈 Insert〉 键:控制工作状态是否为,插入状态,。
〈 Delete〉 键:删除光标所在的字符 。
〈 Ctrl〉 +〈 Y〉 键:删除光标所在的一行 。
〈 Ctrl〉 +〈 N〉 键:插入一行 。
第 1章 程序设计与 C语言
6,编译,连接,运行
(1) 对单一源程序文件进行编译,连接,运行 。
操作步骤如下:
a,按 〈 F10〉 键选择,Compile‖选项 。
b,选中,Make exe File‖项,回车 。
c,按 〈 Esc〉 键回到主菜单,选择,Run‖菜单中的,Run‖项,运行已生成的可执行文件 。
第 1章 程序设计与 C语言
(2) 对两个以上源程序文件进行编译,连接,运行 。
利用 Turbo C提供的,Project‖菜单项,其功能可直接将两个以上的文件编译连接后生成一个完整的运行程序 。
操作步骤如下:
a,假设有两个文件组成一个程序,首先要生成两个源文件 ( 如 File1.c和 File2.c) 。
b,构造 Project文件 。
c,选择,Project‖菜单中的,Project name‖项,回车,输入 Project文件名,按 〈 F9〉 键产生相应的可执行文件 。
d,停止编译的方式 。
e,运行 。
第 1章 程序设计与 C语言返回章目录第 2章 C语言程序设计初步知识
2.1 标识符、常量和变量
2.2 简单数据类型
2.3 基本运算表达式返回主目录
2.1 标识符、常量和变量
2.1.1 标识符标识符是用来标识变量名,符号常量名,函数名,文件名以及一些具有专门含义的有效字符序列 。
C语言规定:合法的标识符只能由字母,数字和下划线组成,第一个字符必须为字母或下划线 。
大写字母和小写字母被视为两个不同的字符 。 标识符的长度规定取前 8个字符为有效字符 。 例如:
sum,area,aver.PI,_above,L_1_2_3,S12
合法的标识符
A.B.C,A.123,13,3area,a+b
不合法的标识符第 2章 C语言程序设计初步知识
1,关键字标识符关键字又称为命令符,在程序中具有特定的含义,不能另作它用,其他字符又无法直接替代 。
2,预定义标识符预定义标识符是指 C语言提供的库函数名和预编译处理命令 ( 如 printf,scanf,define) 等 。
第 2章 C语言程序设计初步知识
3,用户标识符由用户根据需要自定义的标识符称为用户标识符 。 使用用户自定义标识符时,应注意:
(1) 最好根据其含义选用英文缩写及汉语拼音作标识符,这样便于阅读程序 。
(2) 不能与关键字相同 。
(3) 如果与预定义标识符相同系统并不报错,
程序仍能运行,只是预定义标识符失去原来的含义,代之以用户确认的含义。
第 2章 C语言程序设计初步知识
2.1.2 常量和变量
1,常量在程序运行过程中,其值不能被修改的固定量称为常量,C语言中有 3种常量:
(1) 算术型运算常量 ( 如整型常量,实型常量等 ) ;
(2) 字符型常量 ( 如字符常量,字符串常量 ) ;
(3) 标识符所定义的常量。
第 2章 C语言程序设计初步知识
2,变量程序运行过程中,其值可以改变的量叫变量;程序中使用的变量,属于用户自定义标识符,
任何一个变量名必须先定义 ( 即确定变量名和变量的类型 ) 后使用 。
变量也有类型之分,常用的有整型变量、
实型变量、字符型变量等。
第 2章 C语言程序设计初步知识返回章目录
2.2 简单数据类型
C语言中的数据类型,如图 2.1所示。
图 2.1 C语言中的数据类型无符号型( unsigned)
长整型( long)
短整型( short)
整型( int)
单精度型( float)
双精度型( double)
整型文件类型( file)
字符串类型数据类型指针类型空类型基本类型
(简单类型)
数值类型字符型( char)
构造类型数组类型结构体类型( struct)
共用体类型( union)
实型枚举类型( enum)
第 2章 C语言程序设计初步知识
2.2.1 整型数据
1,整型常量整型常量,即整型常数 。 C语言整型常量可用以下 3种形式表示:
(1) 十进制整型常数 。
(2) 八进制数 。 以 0开头的数 。
(3) 十六进制整数。以 0x开头的数为十六进制数。
第 2章 C语言程序设计初步知识
2,整型变量
1) 整型变量的分类整型变量可分为以下 4种整型类型:
a,基本型,以 int表示;
b,短整型,以 short表示;
c,长整型,以 long表示;
d,无符号整型,以 unsigned表示。
第 2章 C语言程序设计初步知识
2) 整型变量的定义,使用变量必须先定义,后使用 。 定义整型变量的格式为:
int i,j ; /* 定义 i,j为整型变量 */
long e,f ; /* 定义 e,f为长整型变量 */
int a=3,b=4 ; /* 定义 a,b为整型变量同时将 3和 4分别赋予 a和 b */
3,整型数据在内存中的存放形式在 C语言中,一个整型数通常占用 2个字节,低位在前一个字节,高位在后一个字节 。
第 2章 C语言程序设计初步知识
2.2.2 实型数据
1,实型常量在 C语言中实型表示实数的集合,实型常量又称实数 。 实型常量有两种表现形式 。
1) 十进制数形式十进制数形式和数学中的实数形式类同,
由数字和小数点组成,小数点是实数的标志 。
2) 指数形式实数的指数形式类似于数学中的指数形式 。
组成格式如下:
数字 [小数 ]E[± ]整数 ( [ ]内为可省 项 )
第 2章 C语言程序设计初步知识
2,实型变量在 C语言中实型变量分为单精度 ( float) 和双精度 ( double) 两类 。
实型变量的定义:
float a,b ; /* 定义 a,b为单精度实型变量 */
double x,y ; /* 定义 x,y为双精度实型变量 */
第 2章 C语言程序设计初步知识
2.2.3 字符型数据
1,字符型常量字符型常量 ( 简称字符常量 ) 是一个字符,
在表示时由两个单引号括起来 。 例如 'A','a','+'、
'2'等 。
字符型常量在内存中占用一个字节,存放的是字符的 ASCII码值,如字符 'A'的值为 65; 'B'的值为 66。所有字符常量还可作为整型量进行运算,
以及参与相应的各种操作。
第 2章 C语言程序设计初步知识
2,转义字符
C语言中有一种特殊的字符常量 ——转义字符,这类字符常量是以反斜杠字符,\‖开头的字符序列,它表示某个特定的 ASCII码字符 。 在程序中,转义字符要放在一对单引号内 。
常用的转义字符及其含义:
'\n' 回车换行至下一行开头
'\r' 回车至本行开头
'\b' 退格符
'\ \' 反斜杠字符 \
'\′' 单引号字符 ′
第 2章 C语言程序设计初步知识
3,字符变量字符变量用于存放一个字符常量 。
字符变量的定义格式为:
char c1,c2;
其中 c1和 c2分别被定义为字符型变量 。
一个字符型变量在内存中占一个字节,字符型变量可以参加任何整型运算。
第 2章 C语言程序设计初步知识返回章目录
2.3 基本运算表达式
2.3.1 算术运算符及表达式
1,基本算术运算符基本算术运算符及特性,见表 2-4。
第 2章 C语言程序设计初步知识表 2-4 基本运算符列表运算符 功能 操作数个数 结合方向 优先级
+
-
求正求负单目单目自右至左自右至左 高低
*
/
%
乘法除法求余双目双目双目自左至右自左至右自左至右
+
-
加法减法双目双目自左至右自左至右第 2章 C语言程序设计初步知识
2,算术表达式由算术运算符将操作数连接起来的有意义的式子称为算术表达式 。 例如 2+a*b。
使用运算符时,应注意:
(1) 表达式本身的功能 。
(2) 操作数的个数 。
(3) 操作数的类型 。
(4) 运算符的优先级 。
(5) 结合性 。
(6) 任何一个表达式除了有其所实现的功能外,还有表达式其自身的值 。
第 2章 C语言程序设计初步知识
2.3.2 赋值运算符及表达式
1,赋值运算符
,=‖符就是赋值运算符,赋值运算符构成的表达式格式如下:
〈 变量名 〉 =表达式
2,复合赋值运算符在,=‖前面加上双目运算符,如,+‖,,-‖、
,*”,,%‖,,/‖即构成复合赋值运算符 。
例如,a+=3 等价于 a=a+3
所有复合赋值运算符级别相同,且与赋值运算符同一优先级,都具有右结合性 。
例如,设 a的初值为 10,则表达式 a+=a-=a*=a等价于,a+=(a-=a*=a)
第 2章 C语言程序设计初步知识
2.3.3 不同类型数据间的转换
1,数据类型自动转换数据类型的自动转换常发生在以下情况中:
(1) 进行运算时转换 。
(2) 赋值转换 。
(3) 输出转换 。
(4) 函数调用转换。
2,不同类型数据间的混合运算整型、实型、字符型数据可以进行混合运算。
在进行运算时,应先把不同类型的数据转换为同一类型,然后进行运算,转换规则,参见图 2.2所示。
第 2章 C语言程序设计初步知识图 2.2 混合运算时不同类型数据间的转换
double
long
unsigned
int char,short
float高低第 2章 C语言程序设计初步知识
3,赋值转换
(1) 将整型数据赋给实型变量,这时数值不变,
但以实型数据形式存到变量中 。
(2) 将实型数据赋给整型变量,这时舍弃小数部分,取整数部分赋给整型变量中 。
(3) 将 int型整型数据赋给无符号型整型变量,
int型数据按存储单元中实际二进制位的内容直接赋给 unsigned型变量 。
若 int型数据为正数,即存储单元中最高位为 0,
赋值后,则 int型数据与 unsigned型数据的数值相同 。
若 int型数据为负数,即存储单元中最高位为 1,
赋值后,unsigned型数据在使用时,最高位将代表一定的数值 。
第 2章 C语言程序设计初步知识
(4) 字符型数据赋给整型变量 。
字符型数据占 1个字节,而整型变量占 2个字节,
因此赋值转换过程中,存在位的扩展 。
a,对于 unsigned型变量,字符型数据 ( 8位 )
传送给 unsigned变量的低 8位,而 unsigned变量的高 8位只须补 0;
b,对于 int型变量,若字符型数据最高位为
0,则 int型变量高 8位补 0。若字符型数据最高位为 1,则 int型变量的高 8位补 1。这样可以保持数值不变。
第 2章 C语言程序设计初步知识
4,强制类型转换在 C语言中,可以利用强制类型转换符,将表达式的类型转换为所需类型 。
一般形式:
(类型名 )表达式例如,(int)a表示将 a转换成 int类型;
第 2章 C语言程序设计初步知识
2.3.4 自增、自减运算符及表达式
1,格式与功能格式:
i++ i--
功能:先使用 i的值,然后,变量 i的值增加
( 减少 ) 1,即 i=i± 1。
格式:
++i --i
功能:变量 i先增加(减少) 1,即 i=i± 1,
然后,再使用 i的值。
第 2章 C语言程序设计初步知识
2,自增,自减运算符的运算自增、自减运算为单目运算,其运算数据为单操作数,且操作数只能是变量,不能是常量或表达式。
3,自增,自减运算符的结合性自增,自减运算符属右结合性 。
注意:
(1) 使用 ++i或 i++单独构成语句时,其作用是等价的,均为 i=i+1。
(2) 运算对象只能是整型变量和实型变量 。
(3) 对于表达式 (i++)+(i++)+(i++),不同的编程环境,其结果不同。
第 2章 C语言程序设计初步知识
2.3.5 逗号运算符及表达式用逗号将表达式连接起来的式子称为逗号表达式 。
1,逗号表达式的一般形式表达式 1,表达式 2,表达式 3,… 表达式 n
2,逗号表达式的功能先计算表达式 1,再计算表达式 2,最后计算表达式 n。最后一个表达式的值即为此逗号表达式的值。
第 2章 C语言程序设计初步知识
3,逗号运算符的优先级在所有运算符中,逗号运算符级别是最低的 。
利用逗号表达式可实现在一条 C语言中对多个变量赋予不同的值 。
第 2章 C语言程序设计初步知识返回章目录第 3章 简单程序设计
3.1 顺序结构程序设计的概念
3.2 赋值语句
3.3 数据输出
3.4 数据输入
3.5 复合语句和空语句返回主目录
3.1 顺序结构程序设计的概念顺序结构是一种线性结构,其特点是:在该结构中,各操作块 ( 简称块,它所对应的计算机语言表述形式是程序段 ) 按照各自出现的先后顺序,依次逐块执行 。
3.2 赋值语句赋值语句由赋值表达式加上一个分号构成 。
格式为:
变量 =〈 表达式 〉 ;
第 3章 简单程序设计返回章目录
3.3 数据输出在使用库函数中的输入输出函数时,要用编译预处理命令,#include‖将有关的,头文件,包含到用户源程序中 。 例如,在使用标准输入输出库函数时,要用到,stdio.h‖文件,因此要将此文件包含进来,文件开头应使用下面的编译预处理命令:
# include <stdio.h>

# include "stdio.h"
第 3章 简单程序设计返回章目录
3.3.1 printf函数
1,printf函数的一般格式
printf函数的一般格式为:
printf ( 格式控制,输出项 1,输出项 2,… )
该函数按照指定的格式,将输出项列表中的各项输出到标准输出文件中。
第 3章 简单程序设计
2,printf函数中格式控制说明每个格式控制说明必须用,%‖开头,以一个格式控制字符结束,在格式控制字符的前面还可以插入,宽度说明,,左对齐符号,-‖、
前导零符号,0‖等附加字符 。
1) 格式控制字符常用的格式控制字符和它们的功能,见表
3-1。使用时要注意区分大小写。
第 3章 简单程序设计表 3-1 printf函数的格式控制字符格式控制字符 说 明
d,i 输出带符号的十进制整型数 ( 正数不输出符号 )
o 输出无符号八进制整型数
x 或 X 输出无符号十六进制整型数 ( 用 x时输出 a~ f,用 X时输出 A~F)
u 输出无符号十进制整型数
c 输出一个字符
s 输出字符串
f 以小数形式输出浮点数 ( 隐含输出 6位小数 )
e 或 E 以指数形式输出浮点数,数字部分小数位数隐含输出 6位 。
g 或 G 选用 %f和 %e格式中输出宽度较短的一种格式
p 输出变量或数组的地址第 3章 简单程序设计
2) 附加格式说明字符为了使程序的输出结果更加整齐美观,可以在控制字符的前面加上附加格式说明字符,见表 3-2。
表 3-2 printf函数的附加格式说明符字 符 说 明字母 l 用于长整型数据,可加在格式控制符 d,o,x,u的前面
m( 正整数 ) 数据最小宽度
n ( 正整数 )
对于浮点数,表示输出 n位小数;对于字符串,表示截取的字符个数;对于整数,指定必须输出的数字个数,若输出的数字少于指定的个数,则前面补 0,否则按原样输出
- 输出的数字或字符向左对齐
+ 输出的结果总是带有 +号或 -号
0 在输出数据前加 0
第 3章 简单程序设计
3.3.2 putchar函数
putchar函数的作用是向屏幕终端输出一个字符 。 格式为:
putchar(ch) ;
其中 ch可以是字符型常量、变量或整型变量。
第 3章 简单程序设计返回章目录
3.4 数据输入3.4.1 scanf函数
scanf函数的格式为:
scanf(格式控制,地址 1,地址 2,… );
3.4.2 getchar函数此函数的作用是从屏幕终端输入一个字符 。
getchar函数没有参数,其一般格式为:
getchar( )
当执行此函数调用语句时,变量将获得一个从标准设备上读取的字符代码值。
第 3章 简单程序设计返回章目录
3.5 复合语句和空语句
3.5.1 复合语句在 C语言中,一对花括号,{ }‖不仅可用作函数体的开头和结尾的标志,也可用作复合语句的开头和结尾的标志;复合语句也可称为,语句块,,复合语句的语句格式为:
{语句 1 ; 语句 2 ; … ; 语句 n ; }
一个复合语句在语法上视为一条语句,在一对花括号中的语句数量不限 。
3.5.2 空语句
C程序中的所有语句必须由一个分号,;,作为结束 。
如果语句只有一个分号,就是空语句 。 程序执行空语句时不产生任何动作 。
第 3章 简单程序设计返回章目录第 4章 选择结构程序设计选择结构是计算机科学用来描述自然界和社会生活中分支现象的手段 。 其特点是:根据所给定选择条件为真 ( 即分支条件成立 ) 与否,而决定从各实际可能的不同操作分支中执行某一分支的相应操作,并且任何情况下恒有,无论分支多寡,必择其一;纵然分支众多,仅选其一,的特性 。
4.1 关系运算符及表达式
4.2 逻辑运算符及表达式
4.3 条件运算符
4.4 单条件选择 if 语句
4.5 开关分支 switch 语句第 4章 选择结构程序设计返回主目录第 4章 选择结构程序设计
4.1 关系运算符及表达式关系表达式是由关系运算符连接表达式构成的 。
1,关系运算符关系运算符都是双目运算符,共有如下 6种:
>,<,>=,<=,==,!=
2,关系表达式由关系运算符组成的表达式,称为关系表达式 。
例如 x>y,(x=5)<=y等 。
关系表达式的值是整数 0或 1,其中 0代表逻辑假; 1代表逻辑真 。
第 4章 选择结构程序设计返回章目录
4.2 逻辑运算符及表达式逻辑表达式是由逻辑运算符连接表达式构成的 。
1,逻辑运算符
C语言中提供了 3种逻辑运算符:
(1) 单目逻辑运算符,!( 逻辑,非,) 。
(2) 双目逻辑运算符,&&( 逻辑,与,) 。
(3) 双目逻辑运算符,||( 逻辑,或,) 。
其中逻辑“与” &&的优先级大于逻辑“或” ||,
它们的优先级都小于逻辑“非” !。逻辑运算符具有自左至右的结合性。
第 4章 选择结构程序设计
2,逻辑表达式由逻辑运算符组成的表达式称为逻辑表达式 。
逻辑表达式的结果为 1( 结果为,真,时 )
或 0( 结果为,假,时 ) 。
表达式 a和表达式 b进行逻辑运算时,其运算规则,见表 4-1。
第 4章 选择结构程序设计表 4-1 逻辑运算的真值表
a b !a !b a && b a || b
非 0 非 0 0 0 1 1
非 0 0 0 1 0 1
0 非 0 1 0 0 1
0 0 1 1 0 0
第 4章 选择结构程序设计
3,短路表达式在由 && 和 || 运算符组成的逻辑表达式中,
只对能确定整个表达式值所需要的最少数目的子表达式进行计算。也就是说,当计算出一个子表达式的值之后便可确定整个逻辑表达式的值时,
后面的子表达式就不需要再计算了,整个表达式的值就是该子表达式的值。这种表达式也称为短路表达式。
第 4章 选择结构程序设计返回章目录
4.3 条件运算符条件运算符是 C语言中唯一的三目运算符,条件表达式的一般格式为:
表达式 1? 表达式 2,表达式 3
条件运算符的执行过程是:先求解表达式 1,当值为非
0(真),则求解表达式 2,此时表达式 2的值就作为整个条件表达式的值;否则求解表达式 3,此时表达式 3的值就作为整个条件表达式的值。
条件运算符的优先级高于赋值运算符,但是低于关系运算符和算术运算符。条件运算符的结合性为自右至左。
第 4章 选择结构程序设计返回章目录
4.4 单条件选择 if 语句单条件选择结构的特点是:所给定的选择条件(它可以是逻辑表达式也可以是关系表达式)
的值如果为真,则执行为真时的分支;如果为假则执行为假时的分支。
第 4章 选择结构程序设计
4.4.1 if 语句
if 语句是根据所给定的条件决定执行的操作,
是,二选一,的分支结构 。 If 语句的一般格式为:
if (表达式 )
{
语句序列 1;
}
else
{
语句序列 2;
}
第 4章 选择结构程序设计
4.4.2 if 语句的嵌套条件分支嵌套就是在一个分支中可以嵌套另一个分支 。
单条件选择 if 语句完整的嵌套格式为:
if(表达式 1)
if(表达式 2) 语句序列 1 ;
else 语句序列 2 ;
else
if(表达式 3) 语句序列 3 ;
else 语句序列 4 ;
第 4章 选择结构程序设计返回章目录
4.5 开关分支 switch语句
C语言提供了 switch多路选择语句 。 格式如下:
switch(表达式 )
{
case 常量表达式 1,语句组 1 ;
case 常量表达式 2,语句组 2 ;

case 常量表达式 n,语句组 n ;
default,语句组 n+1 ;
}
第 4章 选择结构程序设计返回章目录第 5章 循环结构程序设计
5.1 循环结构程序设计的概念
5.2 while 语句
5.3 do … while 语句
5.4 for 语句
5.5 循环结构嵌套
5.6 break 语句和 continue 语句
5.7 语句标号和 goto 语句返回主目录
5.1 循环结构程序设计的概念实现循环的程序结构称为循环结构,是计算机科学中用以描述客观世界循环现象的重要手段 。
程序设计中的循环(简称循环)是指在程序设计中,从某处开始有规律地反复执行某一操作块(或程序块)。如果循环永远不会终止,这样的循环就称为死循环。
第 5章 循环结构程序设计返回章目录
5.2 while语句
while语句用来实现,当型,循环结构 。
5.2.1 while语句的一般格式
while语句是一个循环控制语句,用来控制程序段的重复执行 。 其一般格式为:
while(表达式 )
循环体 ;
格式中的循环体,可以是单个语句、空语句,也可以是复合语句。
第 5章 循环结构程序设计
5.2.2 while语句的执行过程当表达式为非 0时,执行 while语句中的循环体,然后继续进行表达式的判断,如此循环 。
当表达式为 0时,则退出循环 。
说明:如果循环体包含一个以上的语句,
就构成块语句,应该用花括号 { }括起来。
第 5章 循环结构程序设计返回章目录
5.3 do … while 语句
C语言中,用 do … while语句构成直到型循环结构 。
5.3.1 do … while语句的一般格式
do … while语句也是一个循环控制语句 。 其特点是先执行循环体,然后判断条件是否成立 。
其一般格式为:
do
循环体
while(表达式 ) ;
说明:循环体至少执行一次。当循环体有多个语句时必须加花括号 { }。
第 5章 循环结构程序设计
5.3.2 do … while 语句的执行过程先执行一次指定的循环体语句,然后判断表达式 。 当表达式的值为非 0的数据时,返回重新执行循环体,如此反复直到表达式的值为 0为止,此时循环结束 。
第 5章 循环结构程序设计返回章目录
5.4 for 语句
for语句可以用于循环次数已经确定的情况,
还可用于循环次数不确定而只给出循环结束条件的情况 。
5.4.1 for语句的一般格式
for语句的一般格式为:
for (表达式 1 ; 表达式 2 ; 表达式 3)
循环体第 5章 循环结构程序设计
5.4.2 for语句的执行过程
for语句的执行过程为:
(1) 先求解表达式 1,表达式 1只执行一次,
一般是赋值语句,用于初始化变量 。
(2) 求解表达式 2,若为假 ( 0),则结束循环 。
(3) 当表达式 2为真 ( 非 0) 时,执行循环体 。
(4) 执行表达式 3。
(5) 转回 (2)。
第 5章 循环结构程序设计返回章目录
5.5 循环结构嵌套一个循环体内包含另一个完整的循环结构,称为循环的嵌套 。 循环之中还可以套循环,称为多层循环 。 三种循环 ( while循环,do … while循环和 for循环 ) 可以互相嵌套 。 例如:
while( )
{

for ( )
{

}

}
第 5章 循环结构程序设计返回章目录
5.6 break语句和 continue语句
5.6.1 break语句
break语句可以用在循环语句和 switch语句中 。
在循环语句中用来结束内部循环;在 switch语句中用来跳出 switch语句 。
5.6.2 continue语句
continue语句的作用是结束本次循环,忽略
continue后面的语句,进行下一次循环判定。
第 5章 循环结构程序设计返回章目录
5.7 语句标号和 goto语句
goto语句为无条件转向语句,它的一般格式为:
goto 语句标号 ;
第 5章 循环结构程序设计返回章目录第 6章 数 组
6.1 数组和数组单元的基本概念
6.2 一维数组
6.3 二维数组
6.4 字符数组返回主目录
6.1 数组和数组单元的基本概念
1,数组将一组排列有序的,个数有限的变量作为一个整体,用一个统一的名字来表示,则这些有序变量的全体称为数组;或者说,数组是用一个名字代表顺序排列的一组数,顺序号就是下标变量的值 。
第 6章 数 组
2,数组单元在同一数组中,构成该数组的成员称为数组单元 ( 或数组元素,下标变量 ) 。 C语言中,引用数组中的某一单元,要指出数组名和用括号括起来的数组单元在数组中的位置 ( 顺序号 ) 的下标 。 例如:
a[3] 代表 a数组中顺序号为 3的那个单元。
第 6章 数 组
3,数组的维数下标变量中下标的个数称为数组的维数 。
具有一个下标的下标变量,构成一维数组 。
具有两个下标的下标变量,构成二维数组 。
依次类推,三个下标的下标变量,构成三维数组。有多少个下标的下标变量,就构成多少维的数组。通常把二维以上的数组称为多维数组。
第 6章 数 组返回章目录
6.2 一维数组用一个统一的标识符,即数组名来标识一组变量 ( 也称元素 ),用下标来指示数组中元素的序号 。 当数组中每个元素只带有一个下标时,此数组称为一维数组 。
6.2.1 一维数组的定义,引用,初始化
1,一维数组的定义定义一维数组的格式为:
类型标识符 数组名 [常量表达式 ],… ;
第 6章 数 组
2,一维数组的引用使用数组必须先定义,后引用 。
引用时只能对数组元素引用,如 a[0],a[i],
a[i+1]等,而不能引用整个数组 。
在引用时应注意以下几点:
(1) 由于数组元素本身等价于同一类型的一个变量,因此,对变量的任何操作都适用于数组元素 。
(2) 在引用数组元素时,下标可以是整型常数或表达式,表达式内允许变量存在 。 在定义数组时下标不能使用变量 。
(3) 引用数组元素时下标最大值不能出界。
第 6章 数 组
3,一维数组的初始化前已述及,可利用赋值语句或输入语句给数组元素赋值 。 C语言还允许在定义数组时对各数组元素指定初始值 ——称为数组初始化 。
(1) 数组初始化形式 1
例如:将括号内整型数据 0,1,2,3,4分别赋给整型数组元素 a[0],a[1],a[2],a[3],a[4]。
可以写为下面的形式:
int a[5]={0,1,2,3,4} ;
第 6章 数 组
2) 数组初始化形式 2
例如:对 a数组中所有元素赋初值 0。 可以写作下面的形式:
int a [10]={0} ;
3) 通过赋初值定义数组大小例如,int a[ ]={1,2,3,4,5} ;
等价于,int a[5]={1,2,3,4,5} ;
第 6章 数 组
6.2.2 一维数组程序示例
【 例 6-3】 从键盘输入 20个整数,检查整数 10
是否包含在这些数据中,若是的话,它是第几个被输入的 。
程序如下:
第 6章 数 组
# include "stdio.h"
main(?)
{
int data[20],i ;
for(i=0 ; i<20 ; i++)
scanf("%d",&data[i]) ;
for(i=0 ; i<20 ; i++)
if(data[i]==10)
{
printf("10 is input the postion %d \n",i+1) ;
break ;
}
}
第 6章 数 组程序运行结果为:
输入,20 30 40 50 60 10 70 80 90 100 110 120
130 140 150 160 170 180 190 200
输出,10 is input the position 6
第 6章 数 组
【 例 6-4】 输出字符串 "welcome"。
程序如下:
main(?)
{
int i ;
char str[ ]={'w','e','l','c','o','m','e'} ;
for(i=0 ; i<7 ; i++)
printf("%c",str[i]) ;
}
运行结果,welcome
第 6章 数 组返回章目录
6.3 二维数组
6.3.1 二维数组的定义,引用,初始化
1,二维数组的定义定义二维数组的一般格式为:
类型说明符 数组名 [常量表达式 1][常量表达式 2]
2,二维数组元素的引用二维数组中各个元素可看作具有相同数据类型的一组变量 。 因此,对变量的引用及一切操作,同样适用于二维数元素 。
二维数组元素引用的格式为:
数组名 [下标 ][下标 ]
第 6章 数 组
3,二维数组的初始化在定义二维数组的同时,可使用以下几种方法对二维数组初始化 。
(1) 将所有数据写在一个大括号内,以逗号分隔,按数组元素在内存中的排列顺序对其赋值 。
例如,int a[2][3]={0,1,2,3,4,5 } ;
(2) 分行对数组元素赋值 。
例如,int a[2][3]={{0,1,2},{4,5,6}} ;
第 6章 数 组
(3) 对部分元素赋值 。
例如,int a[2][3]={{1},{4}} ;
(4) 若对全部元素赋初值,则定义时第一维长度可缺省 。 可由第二维长度,即列的数据的个数自动确定第一维长度 ( 即行的个数 ) 。
例如,int a[ ][3]={0,1,2,3,4,5} ;
第 6章 数 组
6.3.2 二维数组应用示例
【 例 6-7】 有一个 3× 4矩阵,要求编写程序求出矩阵中所有元素中的最大值,并找出其所在的位置,即行号和列号 。
程序如下:
# include "stdio.h"
main(?)
{
int i,j,r,c,max ;
int a[3][4]={1,2,3,4,5,6,7,8,9,10,11,12} ;
max=a[0][0] ;
第 6章 数 组
for(i=0 ; i<3 ; i++)
for(j=0 ; j<4 ; j++)
if(a[i][j]>max)
max=a[i][j],r=i,c=j ; /* 用逗号表达式实现对 max,r,c赋值 */
printf("max=%d,r=%d,c=%d",max,r,c);
}
运行结果为:
max = 12 r = 3 c = 4
第 6章 数 组
【 例 6-8】 某班有 40个学生考 5门课程,求每个学生的平均成绩并输出 。
程序如下:
# define M 40
# define N 5
main(?)
{
int i,j ;
float s[M][N],aver[M],sum ;
for(i=0 ; i<M ; i++)
for(j=0 ; j<N ; j++)
第 6章 数 组
scanf("%f",&s[i][j]) ; /* 由键盘输入
40个学生 5门课的成绩 */
for(i=0 ; i<M ; i++)
{
sum=0.0 ;
for(j=0 ; j<N ; j++)
sum+=s[i][j] ;
aver[i]=sum/N ;}
for(i=0 ; i<M ; i++)
printf ("aver[%d]=%f\n",i,aver[i]) ;
}
第 6章 数 组返回章目录
6.4 字符数组字符数组是用来存放字符的数组,字符数组中的一个元素存放一个字符 。
6.4.1 字符数组的定义,引用,初始化对字符数组赋值或数组初始化时,数据使用字符型数据或相应的 ASCII码值。
6.4.2 字符串与字符型数组字符串(也称字符串常量)是用双引号括起来的若干有效字符序列。在 C语言中,字符串可以包含字母、数字、转义字符等。
第 6章 数 组
1,使用字符串时的注意事项
(1) C语言没有专门存放字符串的变量 。
(2) C语言中,系统自动地在每一个字符串的最后加入一个字符 '\0',作为字符串的结束标志 。
(3) C语言中,字符型数据是指单个字符
( 包含转义字符 ),在使用时用单引号括起来 。
而字符串是用双引号括起来的字符序列 。
第 6章 数 组
2,字符数组的初始化
(1) 可以在定义数组的同时对数组中的各个元素赋初值,例如:
char c[5]={'h','e','l','l','o'} ;
(2) 可以在定义数组的同时将字符串赋给一个一维字符型数组 。
例如:
char c[6]={"hello"} ;
第 6章 数 组
6.4.3 字符数组的输入输出可以利用字符数组对单个字符和字符串进行输入输出操作 。
1,逐个字符输入输出用格式符 "%c"输入或输出一个字符 。
2,字符串 —整串输入和输出用 "%s"格式符可输入,输出字符串 。 由于 C
语言中没有专门存放字符串的变量,字符串存放在一个字符型数组中,数组名表示第一个字符的首地址,故在输入或输出字符串时可直接使用数组名 。
第 6章 数 组
6.4.4 字符串处理函数
1,字符串输入,输出函数
1) 输入一个字符串函数 gets( )
gets函数一般调用格式为:
gets(str) ;
gets函数的作用是从终端键盘输入字符串
(字符串可以包括空格),直到遇到回车符为止,
回车符读入后,不作为字符串的内容,系统将自动用 '\0'代替,作为字符串的结束标志。
第 6章 数 组
2) 输出一个字符串函数 puts( )
puts( )函数的一般调用格式为:
puts(str) ;
该函数的作用是从 str指定的地址开始,依次输出存储单元中的字符,直到遇到字符串结束标志第 1个 '\0' 字符为止 。
第 6章 数 组
2,字符串处理函数
1) 字符串复制函数 strcpy( )
strcpy( )函数一般调用格式为:
strcpy(str1,str2)
功能:把 str2所指向的字符串复制到 str1所指的字符数组中 。
2) 字符串连接函数 strcat( )
strcat( )函数一般调用格式为:
strcat(str1,str2) ;
功能:将 str2所指的字符串连接到 str1所指的字符串的后面,并自动覆盖 str1所指的字符串的尾部字符 "\0"。
第 6章 数 组
3) 求字符串长度函数 strlen( )
strlen( )函数一般调用格式为:
strlen(str) ;
功能:计算 str为起始地址的字符串的长度
( 不包含字符串结束标志 '\0'),并作为函数值返回 。
第 6章 数 组
4) 字符串比较函数 strcmp( )
strcmp( )函数一般调用格式为:
strcmp(str1,str2) ;
功能:比较 str1和 str2所指向的两个字符串,并产生以下结果:
str1与 str2相等时,函数值为 0。
str1> str2时,函数值大于 0。
str1< str2时,函数值小于 0。
字符串之间比较的方法是:从第一个字符开始,依次对 str1与 str2对应位置上的字符按 ASCII码值的大小进行比较,
直到出现第一个不相同的字符时,即由这两个字符的大小决定所在串的大小 。
第 6章 数 组
6.4.5 字符串数组应用举例例 6-17】 从终端键盘输入一字符串,并复制到另一字符数组后显示出来。
程序如下:
# include "stdio.h"
main(?)
{
char str1[30],str2[30] ;
int i ;
printf("input a string:") ;
scanf("%s",str1) ;
i=0 ;
第 6章 数 组
while(str1[i]!='\0')
{
str2[i]=str1[i] ;
i++ ;
}
str2[i]='\0' ;
printf("%s",str2) ;
}
运行结果:
input a string,ABC
ABC
第 6章 数 组
【 例 6-18】 由终端键盘输入一字符串,要求从该串中删去一字符 。
main(?)
{
char str1[50],str2[50] ;
char ch ;
int i=0,k=0 ;
gets(str1) ;
printf(" \n delete?") ;
scanf("%c",&ch) ;
第 6章 数 组
for(i=0 ; str1[i] !='\0' ; i++)
{
if(str1[i]!=ch)
str2[i-k]=str1[i] ;
else k=k+1 ;
}
str2[i-k]='\0' ;
printf("\n%s\n",str2) ;
}
该程序运行后,从键盘输入字符串:
I am a boy 〈 回车 〉
屏幕显示,delete?
输入,a
输出为,I m boy
第 6章 数 组返回章目录第 7章 函 数
7.1 模块化程序设计的概念
7.2 库函数
7.3 函数的定义和调用
7.4 函数的返回值及其类型
7.5 函数调用时参数间的传递
7.6 函数的嵌套调用
7.7 函数的递归调用
7.8 局部变量和全局变量
7.9 静态存储变量和动态存储变量
7.10 内部函数和外部函数
7.11 程序举例 返回主目录
7.1 模块化程序设计的概念模块化程序设计,是将一个大型程序按照其功能分解成若干个相对独立的功能模块,然后再分别进行设计,最后把这些功能模块按照层次关系进行组装 。 基本思想是,自顶向下,逐步求精,。
C语言程序是一个函数式的程序结构,即 C
语言程序的全部功能都是由函数实现的,而每个函数对应一个独立的模块,通过函数间调用来实现程序的总体功能 。 如图 7.1所示,是一个程序中函数调用示意图 。
第 7章 函 数在 C语言中,函数分为主函数、库函数、用户自定义函数三种。程序的执行由主函数开始,然后调用其它函数,最终返回主函数结束。
main函数
a函数 b函数
c函数 d函数 e函数图 7.1 函数调用示意图第 7章 函 数返回章目录
7.2 库函数
C语言提供了丰富的标准函数,即库函数 。
7.2.1 C语言常用库函数
1) 数学函数调用数学库函数时,要求程序在调用数学库函数前应包含下面的头文件:
# include "ma
第 7章 函 数
2) 字符函数和字符串函数调用字符函数时,要求程序在调用字符函数前应包含下面的头文件:
# include "ctype.h"
调用字符串函数时,要求在源文件中应包含下面的头文件:
# include "string.h"
第 7章 函 数
3) 输入输出函数调用输入输出函数时,要求在源文件中应包含下面的头文件:
# include "stdio.h"
4) 动态分配函数和随机函数调用动态分配函数和随机函数时,要求在源文件中应包含下面的头文件:
# include "stdlib.h"
第 7章 函 数
7.2.2 标准库函数的调用前面讲到,调用 C语言标准库函数时必须在源程序中用 include命令 。
include命令的格式是:
# include <头文件名 >

# include "头文件名 "
第 7章 函 数返回章目录
7.3 函数的定义和调用由用户编写的函数称为自定义函数 。
7.3.1 函数的定义函数定义的一般格式如下:
类型说明符 函数名 (类型名 形式参数 1,类型名 形式参数 2,… )
/* 函数的首部 */
{ 说明部分 /* 函数体 */
语句部分 }
第 7章 函 数
7.3.2 函数的调用
1,函数调用的一般形式函数调用的一般形式为:
函数名 ([实参表 ]) ;
如果是调用无参函数,则 [实参表 ]可以没有,
但括号不能省略。如果实参表列包含多个实参,
则各实参间用逗号隔开。实参与形参的个数应相等,类型应一致。实参与形参按顺序对应,一一传递数据。
第 7章 函 数
2,函数调用的方式按函数在程序中出现的位置来分,有 3种函数调用方式 。
1) 函数语句函数语句的调用,是指把被调函数作为一个独立的语句直接出现在主调函数中 。
2) 函数表达式被调函数出现在主调函数中的表达式中,这种表达式称为函数表达式。在被调函数中,必须有一个函数返回值,返回主调函数以参加表达式的运算。
第 7章 函 数
3) 函数参数函数参数的调用,是指被调函数作为另一个函数的参数时的调用,而另一个函数则是被调函数的主调函数。嵌套调用,如图 7.2所示。
main函数 printf函数 max函数图 7.2 函数嵌套调用第 7章 函 数
3,调用函数时的注意事项调用函数时,应注意以下几点:
(1) 被调函数必须是已存在的函数,可以是自定义函数,也可以是库函数 。
(2) 在主调函数中,要对被调函数先做声明 。
第 7章 函 数
(3) 如果被调函数的返回值为 int类型,则不管被调函数位置如何均不需要在主调函数中说明 。
关于函数声明的一般形式为:
函数类型 函数名 (参数类型 1,参数类型 2… ) ;
或函数类型 函数名 (参数类型 1,参数名 1,参数类型 2,参数名 2… ) ;
(4) 如果被调用函数的声明放在源文件的开头,
则该声明对整个源文件都有效。
(5) 如果被调用函数的声明是在调用函数定义的内部,则该声明仅对该调用函数有效。
第 7章 函 数
(6) 在函数调用中,有下面几种情况可以省略声明:
a,如果调用函数和被调用函数是在同一个源文件中,而且被调用函数的定义是在调用函数之前 。
b,函数的返回值是整数或字符 。
c,所有被调用函数的声明都是在源文件开头 。
d,如果被调用函数不是在源文件开头,而是在源文件中间且在所有函数之外某处被声明时,则在被声明之后引用它时,不必再声明,但在被声明之前引用它时,需要对其进行声明 。
(7) 如果调用函数和被调用函数的定义是在同一源文件中,应该先说明或定义被调用函数 。
第 7章 函 数返回章目录
7.4 函数的返回值及其类型函数的返回值通过函数体内的 return语句实现 。
return语句的格式如下:
return 表达式 ;

return (表达式 ) ;
如果没有返回值,格式中的左,右圆括号可以省略,即写为:
return ;
第 7章 函 数返回章目录
7.5 函数调用时参数间的传递函数之间的联系,是通过调用函数时参数的传递及函数值的返回 。
在定义函数时,函数名后面圆括号内的参数称形式参数 。
调用函数时,函数名后面圆括号内的参数为实参 。
第 7章 函 数
7.5.1 变量,常量,数组元素作为函数参数在函数调用时,使用变量,常量或数组元素作为函数参数时,将实参的值复制到形参相应的存储单元中,即形参和实参分别占用不同存储单元,这种传递方式称为,值传递,。
值传递的特点是单向传递,即只能把实参的值传递给形参,而形参值的任何变化都不会影响实参 。
第 7章 函 数
7.5.2 数组名作为函数参数数组名作为函数参数时,不是值的单向传递,而是把实参数组的首地址传给形参数组,
这个两个数组共用一段存储单元,即实参数组名和形参数组名共同指向数组的第一个元素 。
第 7章 函 数返回章目录
7.6 函数的嵌套调用
C语言中的函数定义是互相独立的,函数和函数之间没有从属关系,一个函数既可以被其它函数调用,同时它也可以调用别的函数,这就是函数的嵌套调用。
第 7章 函 数
fun1main 返回printf fun2返回调用 调用 调用结束图 7.4 函数嵌套调用过程返回章目录
7.7 函数的递归调用所谓递归,就是自己调用自己 。
函数的递归调用有两种形式:
(1) 直接递归调用,即一个函数可直接调用该函数本身 。
(2) 间接递归调用,即一个函数可间接地调用该函数本身 。
第 7章 函 数返回章目录
7.8 局部变量和全局变量
7.8.1 局部变量在一个函数内定义的变量称为内部变量,
它只在本函数内有效,而在其它函数内不能使用,
故这些变量又称为局部变量 。
7.8.2 全局变量在函数外部定义的变量称为外部变量,外部变量是全局变量 。 全局变量的作用范围为:从定义全局变量位置开始到源程序结束 。
全局变量可以在其作用范围内由其它函数所共用。
第 7章 函 数返回章目录
7.9 静态存储变量和动态存储变量变量从变量值存在的时间 ( 即时域,亦称生存期 ) 角度来分,可分为静态存储变量和动态存储变量 。
7.9.1 静态存储变量所谓静态存储变量是指在程序运行期间分配固定的存储空间的变量 。 静态存储变量的定义格式为:
static 数据类型名 变量名 [=初始化常数表达式 ]
第 7章 函 数
7.9.2 动态存储变量所谓动态存储变量是在程序运行期间根据需要进行动态的分配存储变量,它是在程序执行的某一时刻被动态建立,在另一时刻被动态撤消的一种变量 。
动态存储变量有两种:自动( auto)变量和寄存器( register)变量。
第 7章 函 数
1,自动变量自动变量说明的一般格为:
[auto] 类型名 变量名 [=初始表达式 ],…
auto为自动变量存储类别标识符,[auto]可省略,
系统默认为 auto。以前函数中所定义的变量大都是
auto变量。
2,寄存器变量所谓寄存器变量,是指将变量的值保留在 CPU
( 中央处理器 ) 的寄存器内,它不占用内存单元 。
程序运行时,可以直接访问寄存器内的数据,其速度比访问内存的数据快得多 。
register 类型标识符号 变量名第 7章 函 数返回章目录
7.10 内部函数和外部函数根据函数的使用范围,可分为内部函数和外部函数 。
7.10.1 内部函数在定义函数的前面使用 static关键字,此函数称内部函数 。
7.10.2 外部函数在定义函数的前面加 extern关键字,此函数称为外部函数 。 如:
extern int fun(a,b)
第 7章 函 数
7.11 程序举例
【 例 7-16】 编写函数,要求统计输入文本中单词的个数,
单词之间用空格符,换行符,跳格符隔开 。
程序如下:
# include "stdio.h―
# define IN 1 /* 标志一个单词的内部 */
# define OUT 0 /* 标志一个单词的外部 */
main(?)
{
int n ;
n=countword(?);
printf("n=%d\n",n) ;
}
第 7章 函 数
countword(?)
{
int c,nw,state ;
state=OUT ;
nw=0 ;
while ((c=getchar(?))!=EOF)
{ if (c==? ‘ || c==?\n‘ || c==?\t‘) state=OUT; /* 在一个单词的外部 */
else if (state==OUT) /* 如果遇到单词的第一个字符 */
{ state=IN ; /* 状态变量置成 IN,在单词的内部 */
nw++ ; /* 单词个数增 1 */
}
}
return nw ;
}
第 7章 函 数说明:
(1) 当状态变量 state标志为:在单词内部且读入的字符不是分隔符时,表示 c仍是单词的一部分,因此不作任何操作;如果读入的字符是分隔符,表示一个单词已结束,准备统计下一个单词 。
(2) 在 while循环中,用 EOF作为循环结束的标志,EOF是在 stdio.h文件中定义了的预定义符,在 Turbo C的环境下,输入
﹤ Ctrl﹥ +﹤ Z﹥ 后,回车,即输入了 EOF。
第 7章 函 数
【 例 7-17】 从键盘输入一较大正整数 n( n>=6),
并验证从 6到 n之间的所有偶数都可以分解为两个素数之和的形式 。
程序如下:
# include "stdio.h"
# include "math.h"
int prime(int m)
{
int i,k ;
k=sqrt(m) ;
for (i=2 ; i<=k ; i++)
if (m%i==0) return (0) ;
else return (1) ;
}
第 7章 函 数
main(?)
{
int n,a,b,limit ;
while (1)
{
printf("\nInput a number>=6:") ;
scanf ("%d",&limit) ;
if (limit>=6) break ;
}
第 7章 函 数
for (n=6; n<=limit; n+=2)
for (a=3; a<=n/2; a+=2)
if (prime(a))
{ b=n–a ;
if (prime(b))
{
printf ("%d=%d+%d\n",n,a,b) ;
break ;
}
}
}
第 7章 函 数说明:
(1) prime(m)函数是用于验证 m是不是素数的函数 。
当其返回值为 0时,说明 m不是素数;当其返回值为 1时,
说明 m是素数 。
(2) main(?)函数中有一个双层循环,第一层循环的循环变量 n是一个从开始到 limit为止的连续偶数,此程序的主要功能就是判断这些偶数是否都能表示成两个素数之和的形式;第二层循环的主要目的是寻找 a,b(b=n-a)
两个素数之和,以使 n=a+b成立 。 由于除此之外,其它素数都是奇数,因而 a,b始终取奇数 。
(3) 由此程序不难看出,如果一个偶数能够表示为一组以上的素数之和,则只取一个素数最小、另一个素数最大的一组。
第 7章 函 数
【 例 7-18】 输入 100个整型数,并把其中的最大值和最小值显示出来 。
程序如下:
# include "stdio.h"
int max,min ;
void find (int a[ ],int n)
{
int i ;
max=a[0] ;
min=a[0] ;
for (i=1 ; i<n ; i++)
{
if (a[i]>max) max=a[i] ;
if (a[i]<min) min=a[i] ;
}
}
第 7章 函 数
main(?)
{
int data[10],i ;
for (i=0 ; i<10 ; i++)
scanf ("%d",&data[i]) ;
find (data,10) ;
printf ("max=%d,mim=%d\n",max,min) ;
}
说明,find函数将查找到的最大值和最小值分别存放 在全局变量 max和 min中,并通过 max和 min传递给
main(?)函数。由此可见,利用全局变量可以在函数之间进行多个数据的传递。
第 7章 函 数返回章目录第 8章 指 针
8.1 指针的基本概念
8.2 指针和指针变量
8.3 数组和指针
8.4 函数的指针返回主目录
8.1 指针的基本概念指针就是地址,是一种数据类型 。
,直接访问,方式:按变量地址直接对变量的值进行存取 。
,间接访问,方式:在访问变量时,不直接按变量的地址取其值,而将变量的地址存放在另一个存储单元中,要访问某变量时,先访问存放该变量地址的存储单元,再间接地访问变量,对变量进行存取操作 。
第 8章 指针返回章目录
8.2 指针和指针变量可以用运算符,*” 来定义指针变量,也可以用,*” 表示,指向,关系来使用指针变量 。
8.2.1 指针变量的定义指针变量是专门用于存放地址的变量,C语言将它定义为,指针类型,。 定义指针变量的一般格式为:
类型标识符 * 指针变量名例如:
int i,j,* p1,*p2 ;
第 8章 指针
8.2.2 指针变量的赋值可用运算符,&‖求变量的地址 。
可以用赋值语句使一个指针变量指向一个变量,例如:
p1=&i ;
p2=&j ;
也可以在定义指针变量的同时对其赋值,
例如:
int i=3,j=4,*p1=&i,*p2=&j ;
第 8章 指针
8.2.3 指针变量的引用可以通过指针运算符,*” 引用指针变量,
指针运算符可以理解,指向,的含义 。
8.2.4 指针变量作为函数参数函数的参数是一般变量或常数时,函数实参向形参是单向值传递 。
函数的参数是数组名时,则将实参数组名传递给形参数组名,数组名表示数组中第 1个元素的地址,故这种传递是地址的传递 。
函数参数也可以是指针变量,其作用是将变量的地址传到另一函数中去 。
第 8章 指针返回章目录
8.3 数组和指针
8.3.1 一维数组与指针一维数组中,第 1个元素的地址,即该数组中的起始地址 。 可以用数组名方式,通过指向运算符,*” 引用数组元素,也可以将指针变量指向一维数组,通过指针变量引用数组元素 。 例如:
int a[10],*p ; /* 定义 a数组和指针变量 p */
p=a ; /* a数组首地址 →p */
第 8章 指针
8.3.2 二维数组与指针二维数组中:
a+ i= a[i]= *(a+i)=&a[i]=&a[i][0]
它们都表示地址,且地址值是相等的 。 只是 a
用于指向行,a[i]用于指向列,a[i]表示第 i行第 0列元素地址 。
a+i指向第 i行,即第 i行首地址 。
*(a+i)指向第 i行第 0列元素地址 。
a[i]+j表示第 i行第 j列元素地址,见表 8-1。
第 8章 指针表 8-1 第 i行第 j列元素地址及其元素值第 i行 j列元素地址 第 i行 j列元素值
a[i]+j *(a[i]+j)
*(a+i)+j *(*(a+i)+j)
&a[i][j] a[i][j]
第 8章 指针
8.3.3 指针与字符串
C语言中,一个字符串可以存放在一个字符数组中,数组名表示该字符串第一个字符存放的地址,也可以将字符串的首地址赋给一个字符型指针变量中,该指针变量便指向这个字符串,或者说,指针变量可以指向任一字符串的首地址 。
例如:
char *str ;
str="I love China" ;
第 8章 指针
8.3.4 指向数组的指针作为函数参数数组名作为函数参数,实现函数间地址的传递 。 指向数组的指针也可以作为函数参数,数组名和指针都是地址 。 在作为函数参数时有以下几种情况:
实参 形参数组名 数组名指针变量 指针变量在实参向形参传递中,应保证其类型的一致性 。
第 8章 指针返回章目录
8.4 函数的指针一个函数在编译时被分配给一个入口地址,
这个入口地址称为函数的指针 。 可以定义一个指向函数的指针变量,将函数入口地址赋予指针变量,然后通过指针变量调用此函数 。
指向函数的指针变量定义形式为:
类型标识符 (*指针变量名 )( ) ;

函数返回值的类型例如:
int (*p)( ) ;
第 8章 指针返回章目录第 9章 编译预处理在 C语言中,编译预处理指令是以,﹟ ‖开始的行,其结尾不用分号,;‖作结束符。
C语言提供的编译预处理功能有 3种,即宏定义、文件包含和条件编译。
9.1 宏定义
9.2 文件包含
9.3 条件编译返回主目录
9.1 宏定义
C编译系统的预编译程序提供了宏定义机制,利用这种机制可以定义不带参数的符号常量和带参数的宏。
9.1.1 不带参数的宏定义
1,定义符号常量符号常量用不带参数的宏定义语句定义 。 不带参数的宏定义,其一般格式为:
﹟ define 宏名 字符串该语句是把符号常量名定义为指定的字符串,将程序中出现宏名的地方均用该字符串来替换 。
第 9章 编译预处理在进行预编译处理时,用该字符串替代程序中出现的符号常量名 。 例如
# define TRUE 1
在符号常量定义语句中,字符串可以是一个数值型数据,表达式或字符串 。
如果字符串是一个运算表达式时,一般应该用括号括住它,以便把它视为一个操作对象与其他操作数进行运算 。 例如:
text = A*8 ;
预编译后,该表达式变为:
text = (20-(3*4))*8 ;
第 9章 编译预处理
2,使用符号常量的好处
(1) 增强程序的可读性
(2) 增强程序的可维护性
3,使用符号常量的注意事项
(1) 符号常量名一般用大写字母 ( 也可以用小写字母 ),以便与其他标识符相区别 。
(2) 宏定义语句不是 C语言的语句,因此,不能用分号结尾 。
(3) 替换字符串可以为空 。
第 9章 编译预处理
(4) 宏定义语句应放在函数定义之外,符号常量的有效范围是从定义它的宏定义语句开始至所在源文件的结尾 。 一般宏定义语句都放在源文件的开头,以便使它对整个源文件都有效 。
(5) 为了灵活控制宏定义的作用范围,可用
﹟ undef命令终止宏定义的作用域 。
(6) 在定义符号常量时,可以引用已定义的符号常量 。
(7) 程序中,用双括号括起来的字符串内,
如果有字符时,预编译时并不进行替换。
第 9章 编译预处理
9.1.2 带参数的宏定义
1,定义带参数的宏带参数的宏的一般定义格式为:
﹟ define 宏名 (参数表 ) 字符串字符串中包含参数表中的参数 。 例如:
# define min(a,b) (((a)<(b))? (a),(b))
2,使用带参数的宏的好处
(1) 使程序更加简洁 。
(2) 增强程序的可读性 。
第 9章 编译预处理
3,带参数的宏与函数的区别
(1) 函数调用时,要保留现场和返回点,而后把控制转移给被调用函数 。 当被调用函数执行结束后,又要恢复现场和把控制返回到调用函数 。
而对带参数宏的使用不存在控制的来回转移,它只是表达式的运算 。
(2) 函数有一定的数据类型,且数据类型是不变的。而带参数的宏一般是一个运算表达式,
它没有固定的数据类型,其数据类型就是表达式运算结果的数据类型。
第 9章 编译预处理
(3) 函数定义和调用中使用的形参和实参都受数据类型的限制,而带参数宏的形参和实参可以是任意数据类型 。
(4) 函数调用中存在参数的传递过程,而带参数宏的引用不存在参数传递过程 。
(5) 使用函数可缩短程序占用的内存空间,
但由于控制的来回转移,会使程序的执行效率降低 。 而带参数的宏则相反,多次使用宏会增加程序占用的存储空间,但其执行效率要比函数高 。
第 9章 编译预处理
4,使用带参数的宏时的注意事项
(1) 对宏定义语句中的定义式和形式参数,
要根据需要加上圆括号,以免发生运算错误 。
(2) 在定义带参数的宏时,在宏名和带参数的圆括号间不能有空格,否则,空格之后的字符串都将视为替代字符串。
第 9章 编译预处理返回章目录
9.2 文件包含文件包含语句的一般格式为:
﹟ include "文件名 "
或为:
﹟ include <文件名 >
功能:将 <文件名 >所指文件的全部内容包含在该 # include语句所在的源文件中 。
在 # include语句中:
当文件名用 <>括住时,指示编译系统按系统设定的标准目录搜索文件;
当文件名用 " "括住时,表示按指定的路径搜索;
若未指定路径名时,则在当前目录中搜索 。
第 9章 编译预处理使用 # include语句时,应注意以下两点:
(1) 一个 # include语句只能包含一个包含文件 。 如果需要包含 n个文件时,就需要使用 n个
# include语句 。
(2) 文件包含可以嵌套 。
第 9章 编译预处理返回章目录
9.3 条件编译只对满足一定条件的内容进行编译,这就是条件编译 。
条件编译指令有 3种格式 。
第 9章 编译预处理
1,由 # ifdef … # else … # endif语句实现用 # ifdef … # else … # endif语句进行条件编译的指令格式为:
# ifdef 标识符程序段 1
[# else
程序段 2]
# endif
其作用是:如果标识符已被定义 ( 用 # define
定义 ),则对程序段 1进行编译,而程序段 2被删除;否则,程序段 1被删除,编译程序段 2。
条件编译语句中的 # ifdef和 # endif决定了编译范围,在此范围外的源程序不存在条件编译问题。
第 9章 编译预处理
2,由 # ifndef … # else … # endif语句实现由 # ifndef … # else … # endif语句进行条件编译的指令格式为:
# ifndef 标识符程序段 1
[# else
程序段 2]
# endif
其作用是:如果标识符未被定义过,则对程序段 1进行编译;否则编译程序段 2。
第 9章 编译预处理
3,由 # if … # else … # endif语句实现由 # if … # else … # endif语句进行条件编译的指令格式为:
# if 表达式程序段 1
[# else
程序段 2]
# endif
其作用是:当表达式的值为非 0时,编译程序段 1,不编译程序段 2;否则编译程序段 2。
第 9章 编译预处理返回章目录第 10章 结构体和共用体在程序设计中,把一些关系密切而数据类型不同的数据组织在一起,并为其命名一个名字,这类数据称为结构体 。
共用体是一种类似于结构体的构造型数据类型,它准许不同类型和不同长度的数据共享同一块存储空间。
10.1 结构体类型
10.2 共用体返回主目录
10.1 结构体类型结构体,是将若干个类型相同或不同的数据组合成一个有机的集合 。
10.1.1 结构体类型定义使用结构体变量前,要先定义该结构体类型,再定义结构体变量 。 结构体类型定义的一般格式为:
第 10章 结构体和共用体
struct 结构体名
{
类型标识符 成员名列表 ;
类型标识符 成员名列表 ;

类型标识符 成员名列表 ;
} ;
例如:
struct student
{
int snum ;
char name[10] ;
char sex ;
int age ;
char addr[40] ;
} ;
第 10章 结构体和共用体
10.1.2 结构体变量的定义,引用和初始化
1,结构体变量定义定义结构体变量有三种方法 。
(1) 在定义结构体类型的同时定义结构体变量 。
(2) 先定义结构体类型,再定义结构体变量 。
(3) 直接定义结构体变量。
第 10章 结构体和共用体
2,结构体变量的引用对结构体变量进行操作时,除了可以对相同类型的结构体变量进行整体赋值外,不可以对一个结构体变量整体赋值 。 要对一个结构体变量进行操作,
其引用的方式为:
结构体变量名,成员名
3,结构体变量的初始化与数组的初始化类似,结构体变量只能对外部和静态结构体变量初始化 。 初始化数据之间要用
“,,隔开,不进行初始化的成员项要用,,,跳过 。
第 10章 结构体和共用体
10.1.3 结构体数组有序数据的集合称为数组,结构体变量组合在一起称为结构体数组 。 其定义方式同一般数组一样,例如:
struct student stu[10] ;
这样就定义了一个包含有 10个元素的结构体数组,其每个数组元素都是一个结构体类型的数据 。
第 10章 结构体和共用体
10.1.4 结构体的指针
1,结构体指针的定义及应用定义结构体的指针,使该指针指向某一类型结构体变量或结构体数组的首地址 。 如定义一个 struct student结构类型的指针:
struct student *p1,*p2,stu1,stu[10] ;
要使其指向某一个变量,则必须给它赋值,
例如:
p1=&stu1 ;
p2=stu ;
p1指向结构体变量 stu1的首地址,p2指向结构体数组 stu的首地址 。
第 10章 结构体和共用体如需用结构体的指针访问结构成员,可以采用以下方式:
(*指针名 ),成员名在 C语言中,采用,->‖(减号、大于号)运算符来简化调用。例如,要访问指针 p1指向的结构体变量的成员,可以采用 (*p1).snum,
(*p1).name,(*p1).sex,(*p1).age,(*p1).addr也可以采用 p1->snum,p1->name,p1->sex,p1->age,
p1->addr。
第 10章 结构体和共用体
2,用结构体指针作函数参数可以通过传递结构体变量的成员及传递整个结构体变量或结构体数组的方法来传递数据,
还可以通过结构体指针作为函数参数传递数据。
第 10章 结构体和共用体
10.1.5 利用结构体变量构成链表链表就是利用递归定义,使得由第一个结构体变量可以找到第二个结构体变量,也就是说如果知道链表的首地址,可以获得整个链表 。 由于链表的每一个节点的物理位置不是固定的,所以需要以下函数来动态地分配空间及释放空间 。
(1) malloc(size) 动态申请一个长度为 size的连续空间,此函数返回一个指针,指向该空间的起始地址,如果错误则返回 0。
(2) free(ptr) 释放 ptr所指向的内存区 。
第 10章 结构体和共用体返回章目录
10.2 共用体在程序设计中,采用共用体比使用结构体节省空间,但是访问速度慢 。
10.2.1 共用体类型说明公用体类型的说明与结构体类型的说明类似,
方法如下:
union 公用体名
{
类型标识符 成员名列表;
类型标识符 成员名列表;

类型标识符 成员名列表;
} ;
第 10章 结构体和共用体公用体变量所占内存的长度是成员中最长的长度,在这样一个空间中可以存放不同类型和不同长度的数据,而这些数据都是以同一地址开始存放的。
第 10章 结构体和共用体例如,定义一个公用体其中包括整型,字符型,实型变量,这三种数据类型的成员共享同一块内存空间 。
union unidata
{
int i ;
char ch ;
float f ;
}d1,d2,d3 ;
这样 d1,d2,d3就是一个公用体变量。由于在该结构体类型中实型变量占有内存单元 4个字节,是最长的成员,所以公用体变量 d1,d2,d3
都分配 4个字节的内存单元。
第 10章 结构体和共用体
10.2.2 共用体变量的定义,引用共用体变量的定义同结构体类型变量的定义可以有三种定义方法 。 其引用也同结构体类型变量的引用,是使用运算符,,‖和,->〉 ‖。
在使用共用体变量的时候要注意在程序执行的某一时刻,只有一个共用体成员起作用,而其他的成员不起作用。两个具有相同共用体类型的变量可以互相赋值。可以对共用体变量进行取地址运算。
第 10章 结构体和共用体返回章目录第 11章 位运算
11.1 位运算符
11.2 位运算符的运算功能位运算是指进行二进制位的运算 。
返回主目录
11.1 位运算符计算机中的位运算是针对二进制代码进行的 。
每一个二进制位的取值只有 0或 1。 位运算符的操作对象是一个二进制位的集合,如一个字节
( 8bit) 。
位运算符共有 6种,即 ~,<<,>>,&,^ 和 |,
分别表示按位取反,左移位,右移位,按位与,
按位异或,按位或,见表 11-1。
第 11章 位运算表 11-1 位运算符运算符 名称 使用格式
~ 按位取反 ~ 表达式
<< 左移位 表达式 1 << 表达式 2
>> 右移位 表达式 1 >> 表达式 2
& 按位与 表达式 1 & 表达式 2
^ 按位异或 表达式 1 ^ 表达式 2
| 按位或 表达式 1 | 表达式 2
第 11章 位运算按位操作的情况,见表 11-2,其中 a和 b分别表示一个二进制位 。
表 11-2 按位逻辑运算
a b ~ a a & b a ^ b a | b
0 0 1 0 0 0
0 1 1 0 1 1
1 0 0 0 1 1
1 1 0 1 0 1
第 11章 位运算
11.1.1 按位取反按位取反运算符就是将其操作对象中的所有二进制位全部改变状态,即“逢 0变 1,逢 1变 0‖。
11.1.2 移位移位运算符有左移运算符和右移运算符 。
1,左移运算符左移运算符是将其操作对象向左移动指定的位数,
每左移 1位相当于乘以 2,移 n位相当于乘以 2的 n次方 。
一个二进制位在左移时右边补 0,移几位右边补几个 0。
左移运算符的一般书写格式为:
表达式 1 << 表达式 2
第 11章 位运算
2,右移运算符右移运算符是将其操作对象向右移动指定的位数,每右移 1位相当于除以 2,移 n位相当于除以 2的 n次方 。 在进行右移时,右边移出的二进制位被舍弃 。
右移运算符的一般书写格式为:
表达式 1 >> 表达式 2
第 11章 位运算
11.1.3 按位,与,
按位,与,的一般书写格式为:
表达式 1 & 表达式 2
按位“与”的运算原则为:当两个操作对象的相应二进制位都为 1时,则该位的结果为 1,
否则为 0,即“两 1为 1,其余为 0‖。
11.1.4 按位,或,
按位,或,的一般书写格式为:
表达式 1 | 表达式 2
按位“或”的运算原则为:当两个操作对象的相应二进制位都为 0时,则该位的结果为 0,
否则为 1,即“两 0为 0,其余为 1‖。
第 11章 位运算
11.1.5 按位,异或,
按位,异或,的一般书写格式为:
表达式 1 ^ 表达式 2
按位,或,的运算原则为:当两个操作对象的相应位相同时,则该对应位的结果为 0,否则为 1,即,相同为 0,不同为 1‖。
按位“异或”也可以称不进位加,即两个操作对象执行二进制相加,但不向高位进位。
第 11章 位运算返回章目录
11.2 位运算符的运算功能
【 例 11-9】 将整型数据 n的后 5位数据置为 0,其余各位不变 。
程序如下:
# include <stdio.h>
main(?)
{
int n ;
printf("input n,") ;
scanf("%d",&n) ;
n&=~037 ;
printf("%d\n",n) ;
}
第 11章 位运算
【 例 11-10】 实现向左循环移位 。
程序如下:
# include <stdio.h>
main(?)
{
unsigned a,b,c ;
int n ;
printf("input a,") ;
scanf("%o",&a) ;
printf("input n,") ;
scanf("%d",&n) ;
b=a>>(16-n) ;
c=a<<n ;
a=b | c ;
printf("%o\n",a) ;
}
第 11章 位运算
【 例 11-11】 将一个整型数据的各位倒序输出 。
程序如下:
# include <stdio.h>
main(?)
{
unsigned a,b ;
int i ;
printf("input a,") ;
scanf("%o",&a) ;
b=0 ;
for(i=0 ; i<16 ; i++)
{
b=b<<1 ;
b=(a & (1<<i))>>i | b ;
}
printf("%o\n",b) ;
}
第 11章 位运算
【 例 11-12】 取一个单元 a的某几位到另一个单元 b。
程序如下:
# include <stdio.h>
void yiwei(pa,pb,st1,st2,n1)
unsigned *pa,*pb ;
int st1,st2,n1 ;
{
unsigned c,d ;
int move ;
move=st1-st2 ;
c=~(~0<<n1)<<(17-st1-n1) ;
d=~(~(~0<<n1)<<(17-st2-n1)) ;
if(move>0)
*pb=(c & *pa)<<move | (*pb & d) ;
else
*pb=c & *pa>>(-move) | (*pb & d) ;
}
第 11章 位运算
main(?)
{
int a1,b1,n ;
unsigned a,b ;
printf("input a,\n") ;
scanf("%o",&a) ;
printf("input b:\n") ;
scanf("%o",&b) ;
printf("input the start num a1,\n") ;
scanf("%d",&a1) ;
printf("input the start num b1,\n") ;
scanf("%d",&b1) ;
printf("input number of the bits:\n");
scanf("%d",&n) ;
yiwei(&a,&b,a1,b1,n) ;
printf("%o\n %o\n",a,b) ;
}
第 11章 位运算返回章目录第 12章 文 件
12.1 文件概念
12.2 文件指针
12.3 打开和关闭文件
12.4 常用文件操作函数返回主目录
12.1 文件概念文件是根据特定目的而收集在一起并存储在外部介质上的有关数据的集合 。
C语言把文件看作是一个字符(字节)的序列,即由一个一个字符(字节)的数据顺序组成。
根据数据的组织形式,可分为文本文件和二进制文件两类。
第 12章 文件
1,文本文件本文件是指由字符组成的文件,每个字符用其相应的 ASCII码存储 。
用文本文件形式输出与字符一一对应,一个字节代表一个字符,便于对字符进行逐个处理,
也便于输出字符 。 但一般占存储空间较多,而且要花费转换时间 。
2,二进制文件二进制文件是把内存中的数据按其在内存中的存储形式原样输出到磁盘上存放 。
用二进制形式输出数据,可以节省外存空间和转换时间,但一个字节并不对应一个字符,不能直接输出字符形式。
第 12章 文件返回章目录
12.2 文件指针
C语言对文件的操作是通过文件指针进行的 。
文件指针是一个名为 FILE( 注意:必须是大写 )
的结构体类型,该结构体类型由系统定义,存放在 <stdio.h>头文件中 。
在使用文件前,首先要包含标题文件 stdio.h,
其次要定义 FILE型的文件指针 。 通过该文件类型指针找到被操作文件,对其进行读写等操作 。
文件类型指针的定义格式为:
FILE *fp ;
第 12章 文件返回章目录
12.3 打开和关闭文件
2.3.1 文件的打开 ( fopen函数 )
1,fopen函数的使用格式
fopen函数的使用格式为:
FILE *fp ;
fp=fopen(文件名,打开方式 ) ;
打开方式是指对该文件进行什么操作。其取值见表 12-1。
第 12章 文件表 12-1 文件的打开方式打开方式 含 义 说 明
r 只读 为输入打开一个已存在的文本文件
w 只写 为输出打开一个文本文件
a 追加 为追加打开一个已存在的文本文件
rb 只读 为输入打开一个已存在的二进制文件
wb 只写 为输出打开一个二进制文件
r+ 读写 为既读又写打开一个已存在的文本文件
w+ 读写 为既读又写新建一个的文本文件
a+ 读写 为既读又写打开一个已存在的文本文件,文件指针移至文件末尾第 12章 文件
2,fopen函数的使用说明
(1) 用,r‖方式打开的文件只能用于向计算机输入,而不能用作向该文件输出数据,且该文件应已存在 。
(2) 用,w‖方式打开的文件只能用于向该文件写数据,而不能用来向计算机输入 。 如果原来不存在该文件,则新建一个以指定名字命名的文件 。 如果原来已存在一个以该文件名命名的文件,则在打开时将该文件删除,然后重新建立一个新文件 。
(3) 如果需要向文件尾部添加新的数据 ( 不删除原有数据 ),则应该用,a‖方式打开 。 但此时该文件必须已存在,否则将得到出错信息 。
第 12章 文件
(4) 用,r+‖,,w+‖,,a+‖方式打开的文件可以用来输入和输出数据 。
用,r+‖方式时,该文件应该已经存在,以便能向计算机输入数据 。
用,w+‖方式时,则新建一个文件,先向此文件写数据,然后可以读此文件中的数据 。
用,a+‖方式打开的文件,原来的文件不被删除,位置指针移到文件末尾,可以添加也可以读 。
(5) 如果不能实现“打开”的任务,fopen函数将会带回一个出错信息。
第 12章 文件
(6) 应用同一种缓冲文件系统来处理文本文件和二进制文件 。 但是,目前使用的有些 C编译系统可能不完全提供所有这些功能,在使用时,
应该注意所用的系统 。
(7) 在用文本文件时,向计算机输入时,将回车换行符转换为一个换行符,在输出时把换行符转换成为回车和换行两个字符 。 在用二进制文件时,不进行这种转换,在内存中的数据形式与输出到外部文件中的数据形式完全一致,
一一对应 。
(8) 在程序开始运行时,系统自动打开 3个标准文件:标准输入、标准输出、标准出错输出。通常这 3个文件都与终端相联系。
第 12章 文件
12.3.2 文件的关闭 ( fclose函数 )
,关闭,就是使文件指针变量不指向该文件,也就是文件指针变量与文件,脱钩,,此后不能再通过该指针对其相连的文件进行读写操作 。
关闭文件的使用格式为:
fcolse(文件指针 ) ;
其中文件指针指向要关闭的文件 。 当文件正常关闭时函数返回 0,否则返回 EOF。
第 12章 文件返回章目录
12.4 常用文件操作函数
12.4.1 文件的输入输出
1,以字符方式读写文件 ( fgetc函数和 fputc函数 )
fgetc函数的使用格式为时
ch=fgetc(fp) ;
fgetc函数返回一个读取的字符,当返回 EOF
时表示文件结束或出错,EOF的值为 -1。
fputc函数的使用方法如下:
fputc(ch,fp) ;
fputc函数将 ch的值输出到 fp所指的文件中,并返回该字符,如果输出失败则返回 EOF。
第 12章 文件
2,二进制文件的输入与输出 ( fread函数和 fwrite函数 )
如果文件用二进制形式打开,使用
fread函数和 fwrite函数可以一次读入或写入多组数据 。 它们的使用格式为:
fread(buffer,size,number,fp) ;
fwrite(buffer,size,number,fp) ;
第 12章 文件
3,文件的格式化输入与输出 ( fscanf函数和
fprintf函数 )
fscanf函数和 fprintf函数是按照一定的格式对文件进行读写 。 它们的使用格式为:
fprintf(fp,格式字符串,输出列表 ) ;
fscanf(fp,格式字符串,输入列表 ) ;
该函数把输出 ( 输入 ) 列表中的各项,按照格式字符串中指定的格式输出 ( 输入 ) 到 fp指向的文件中 。
第 12章 文件
12.4.2 文件的定位
1,rewind()函数
rewind函数的作用是使位置指针重新指向文件的开头,该函数无返回值 。 使用格式为:
rewind(fp) ;
2,fseek函数通过调用 fseek函数可对文件进行随机定位,
就可以进行随机读写 。 该函数的返回值为当前指针的位置,出错则为 -1。 使用格式为:
fseek(fp,位移量,起始点 ) ;
其中起始点可取 0,1,2 三个值之一,
ANSIC标准定义的名字,见表 12-2。
第 12章 文件表 12-2 ANSIC标准起始点取值 名字 含义
0 SEEK_SET 文件开始
1 SEEK_CUR 文件当前位置
2 SEEK_END 文件末尾第 12章 文件
3,ftell函数该函数返回当前文件位置指针的位置,用相对于文件开头的位移量来表示 。 如果返回 -1
则表示出错 。 其使用格式为:
ftell(fp) ;
第 12章 文件
12.4.3 出错的检测
1,ferror函数在调用各种输入输出函数时,用 ferror函数可检查上述操作是否有错 。 使用方法如下,
ferror(fp) ;
若返回值为 0表示正常,若为非 0则表示出错 。
2,clearerr函数
clearerr函数的作用是将文件错误标志和文件结束标志置 0,无返回值,其用法为,
clearerr(fp) ;
当文件 I/O发生错误时,其错误标志就一直保留,直到再一次调用 I/O函数,或 clearerr函数或
rewind函数 。
第 12章 文件返回章目录第 13章 程序调试与常见错误分析
13.1 程序调试
13.2 常见错误分析返回主目录
13.1.1 程序调试的步骤所谓程序调试是指对程序的查错和排错 。
调试程序一般应经过以下几个步骤 。
(1) 先进行人工检查,即静态检查 。
(2) 上机调试,即动态检查 。
(3) 运行程序,试验数据。
第 13章 程序调试与常见错误分析
13.1 程序调试
13.1.2 检查和分析错误原因检查和分析采用以下办法:
(1) 如果在程序中没有发现问题,可以检查流程图有无错误,即算法有无问题 。
(2) 如果实在找不到错误,可以采取,分段检查,的方法 。
(3) 用,条件编译,命令来进行程序调试 。
(4) 有的系统还提供 debug( 调试 ) 工具,跟踪流程并给出相应信息 。
第 13章 程序调试与常见错误分析返回章目录
13.2 常见错误分析
(1) 误把,=‖作为,等于,比较符 。
(2) 使用自加 ( + +) 和自减 ( - -) 运算符时出错 。
(3) 混淆字符和字符串的表示形式 。
(4) 语句后面漏分号 。
(5) 输入输出的数据的类型与所用格式说明符不一致 。
(6) 忘记定义变量 。
(7) 未注意 int型数据的数值范围 。
第 13章 程序调试与常见错误分析
(8) 输入时数据的组织与要求不符 。
(9) 在不该加分号的地方加了分号 。
(10) 输入变量时忘记使用地址符 。
(11) 括弧不配对 。
(12) switch语句的各分支中漏写 break语句 。
(13) 引用数组元素时误用了圆括弧 。
(14) 对应该有花括弧的复合语句,忘记加花括弧 。
(15) 在用标识符时,忘记了大写字母和小写字母的区别 。
第 13章 程序调试与常见错误分析
(16) 在定义数组时,将定义的,元素个数,
误认为是,可使用的最大下标值,。
(17) 误以为数组名代表数组中全部元素 。
(18) 对二维或多维数组的定义和引用的方法不对 。
(19) 混淆字符数组与字符指针的区别 。
(20) 用指针变量之前没有赋值 。
(21) 不同类型的指针混用 。
(22) 所调用函数在调用语句之后才定义,而又在调用前未加说明。
第 13章 程序调试与常见错误分析
(23) 将函数的形参和函数中的局部变量一起定义 。
(24) 函数的实参和形参类型不一致 。
(25) 没有注意函数参数的求值顺序 。
(26) 混淆数组名与指针变量的区别 。
(27) 误认为形参值的改变会影响实参的值 。
(28) 混淆结构体类型与结构体变量的区别,
对一个结构体类型赋值 。
(29) 使用文件时忘记打开,或打开方式与使用情况不匹配 。
第 13章 程序调试与常见错误分析返回章目录全书完谢谢使用!