第一章 概述
★ 内容提要:
C 语言概貌程序设计思想和程序结构程序设计方法与要点算法描述应用基本输入输出程序方式
绪论
C语言的特点
库函数应用
自定义函数
C程序的组成
C编程方式
C 语言是目前世界上最流行和实用的一种计算机高级程序设计语言。最初的 C 语言只是为描述和实现 UNIX
操作系统提供一种工作语言而设计的,后随其宿 主系统 UNIX 的普及而被引起注意,又因其本身的高效、灵活、功能丰富、表达力强、移植性好等特出优点 受到广泛的重视并普及应用。
编写应用软件,数据处理,科学工程数值计算等领域。
编写系统软件,操作系统,编译系统,系统实用程序。
高校开设程序设计课程的必修首选语言。
1.1 绪论
(1) C 语言在软件、硬件系统与用户中所处的位置汇编语言机器语言低级语言:具有面 向硬件系统便于直接访问硬件的特 点功能,但没有数据类型,不易阅读、记忆,推广。
……
FORTRAN 语言
pascal 语言
BASIC 语言高级语言:具有丰富的数据类型和运算符,便于描述数据结构,
既具有强有力的表达力,可加快开发 速度,提高工作效率,面 向用户、便于记忆、书写和阅读等。用户、便于记忆、书写和阅读等。
系统软件硬件用户
1.2 C 语言的特点
C 语言 吸取了高低级语言优点,兼而有之。
( 2 ) C 语言是一种结构化程序设计语言便于模块化软件设计。结构化程序设计思想和目的是使程序具有结构合理,正确性高易验证。而且规定总结了一套程序设计准则。可以简单归纳为以下几点:
基于自顶向下,逐步求精的设计方法;
程序书写遵循一定的格式,使结构清晰;
程序中只包含三种基本的结构:顺序、分支、循环。
程序由模块构成,每个模块具有独力的功能。模 块之间的数据联系要简单,每个模块只能有一个入口和一个出口;
三种最基本的结构:顺序、分支、循环。
语句组顺序结构语句 1
Y N
条件语句 2
分支结构
N
条件语句组循环结构
Y
程序 = 数据结构 + 算法数据结构:
逻辑结构,计算机外部的数据及其数据之间的关系。
存储结构,外部数据及其数据之间的关系在计算机内部的实现。(一般通过类型来表达)
运算,定义在逻辑结构之上的操作,通过算法描述算法,是对问题求解过程的一种描述,是为解决一个或一类问题给出的一个确定的有限长的操作序列。
有输入,算法加工的对象;
有穷性,对于任意一组合法的输入值,在执行有穷步骤之后一定能结束;
确定性,对于每种情况下所应执行的操作,在算法中都有确切的规定(不存在二义性);
可行性,算法中的所有操作都必须足够基本,都可以通过已经实现的基本操作运算有限次实现之;
有输出,它是一组与,输入,有确定关系的量值,是算法进行信息加工后得到的结果。
(3) 用函数作为程序模块以实现程序的模块化结构
# include <stdio.h>
# include <math.h>
# define PI 3.14159
main(){
d o u b l e a r e a ( d o u b l e x ) ;
double r,a;
scanf("%lf",&r);
r=pow(r,2.0);
a=area(r);
printf("area=%f \ n",a);
return(0);
}
以? #? 打头的预处理命令用以包含相关文件,
及定义符号常数。
以令用以包含相关文件,
求解园面积的编程示例
C 程序中的函数、
变量、符号常数必须先定义后使用,否则应作预先声明。
程序中的函数、
变量、符号常数必须先定义后使用,否则
(3) 用函数作为程序模块以实现程序的模块化结构
# include <stdio.h>
# include <math.h>
# define PI 3.14159
main(){
d o u b l e a r e a ( d o u b l e x ) ;
double r,a;
scanf("%lf",&r);
r=pow(r,2.0);
a=area(r);
printf("area=%f \ n",a);
return(0);
}
以 main() 标识的主函数是 C 程序运行开始时由系统调用的一个特殊 函数,
不管其所在位置是 程序中的前或后,执行总 是从它开始。
C 程序可由一个或多个函数构成,但必须存 在一个主函数,执行语句 中可以调用其它函数,但 它不能被其它函数调用,也不能自己调用自己。
其它函数指,C 编译系统提供的库函数;用 户自定义函数。
求解园面积的编程示例
函数的基本形式:
函数类型 函数名(形参表 列 ) {
数据说明部分;
执行语句部分;
}
说明:
如果没有参数,则可以省略形参表列和形参说明,
但括号不能省略;
规定有序求解园面积的编程示例
void main(){
d o u b l e a r e a ( d o u b l e x ) ;
double r,a;
scanf("%lf",&r);
r=pow(r,2.0);
a=area(r);
printf("area=%f \ n",a);
}
double area(double x){
double y;
y=PI*x;
return(y);
}
void main(){
d o u b l e a r e a ( d o u b l e x ) ;
double r,a;
scanf("%lf",&r);
r=pow(r,2.0);
a=area(r);
printf("area=%f \ n",a);
}
double area(double x){
double y;
y=PI*x;
return(y);
}
求解园面积的编程示例
如果函数不需要返回值,则可将该函数 定义为
void 类型函数,并去除
return 语句。
分号是语句的结束标志,
是语句必要的组成 部分,
不可少,因此可以 一行写几个语句。
void main(){
d o u b l e a r e a ( d o u b l e x ) ;
double r,a;
scanf("%lf",&r);
r=pow(r,2.0);
a=area(r);
printf("area=%f \ n",a);
}
double area(double x){
double y;
y=PI*x;
return(y);
}
求解园面积的编程示例
函数:函数在程序设计中,是指有一定 结构形式构成的,能完成 某种特定运算功能的程序 模块,
被调用时根据自变 量(形参)的值,作运算 后,返回相应的结果(数 据)或实现某项特定的功能操作。
预处理命令、外部变量定义等函数类型 main( ){
数据说明部分;
执行语句部分;
}
函数类型 fun_1( 形参表 ){
数据说明部分;
执行语句部分;
}
……
函数类型 fun_n( 形参表 ){
数据说明部分;
执行语句部分;
}
C
程序的一般形式:
1.3 库函数应用简介
C 的两个基本系统函数库及其相配套的说明性预处理文件。
库函数的说明性预处理文件,,stdio.h,,
,math.h,它们是系统与用户的接口文件,称
,头文件,,其中包含库函数原型的说明、类型和全局变量及符号常数等的说明。
数值计算函数库
sqrt(X) 求平方根函数;
sin(x) 返回以弧度表示的 x 的正弦值;
cos(x) 返回以弧度表示的 x 的余弦值;
pow(x,y) 返回 x
y
的值的幂指数函数
exp(x) 返回 e
x
的指数函数
……
用户程序要调用这些函数,必须在有关函数前用以下预处理命令把,math.h,标头文件包含进来。
1.3 用库函数 组装 C 程序
# include,math.h,

# include < math.h>
双引号定界表示以当前目录为起点寻找包含文件,
若不在,再按系统规定的标准路径找
尖括号定界表示按系统规定的标准路径设置检索包含文件。
预处理命令包含,math.h,标头文件 格式如下:
因为 ma th,h 中包含提供了数值计算函数库中的每一个函数原型的说明。
………
double sqrt( double x );
double sin( double x );
double pow( double x,double y ); ……
函数原型中提供了函数类型、函数名称、形参表中形参的个数、形参的类型、形参的顺序等信息,它们将在程序中作为 C 编译程序编译用户程序时检验用户调用库函数准确性的判断依据。
函数类型 函数名称 形参的个数、类型、顺序等信息所以,调用库函数时必须注意,函数参数的个数、类型,顺序及返回值的类型。
对于三角函数还应注意自变量的单位是弧度。
基本 I/O ( 输入 / 输出)库,用户程序若要使用其中的函数,必 须用预处理命令将
,stdio.h,标头文件包含进来。 意义同上!
# includ e,std io.h,或 # includ e <st dio.h >
常用字符输入输出函数:
getchar( )
pu tchar( C )
gets( 字符数组 )
pu ts ( 字符串地址 )
从标准输入文件 stdin( 键盘 ) 读入一个字符。
把字符串输出到标准输出文件,并加上换行符。
从标准输入文件读入一个字符串到字符数组中。
将字符 c 写到标准输出文件 stdout( 显示屏 ) 中去。
格式输入输出函数:
sc anf(,格式字符串,,输入参数表列 ) ;
printf(,格式字符串,,输出参数表列 ) ;
特例,最常用的输入输出函数,因此可省略
stdio.h文件包含例 [2] 计算一个正弦值。
# include <mat h.h >
void m ain() {
dou ble x ; //declar e variable
x =sin(0.1 9 199);
print f(" sin0,19199= % f \ n",x );
}
/*
运行结果:
sin0.19199=0.190813
*/
//? 注释本行其后的内容为注释信息;
/* … */? 表示两符号之间为注释信息;
注释信息对程序运行不发生影响,也不被编译,合理地使用注释可以提高程序的可阅读性。
例 [2] 计算一个正弦值。
C 规定每一个语句以分号结束,分号是语句不可缺少的部分,是语句的结束标志。因此,
一行可以写多个语句,
一个语句也可以分多行书写。
# include <mat h.h >
void m ain() {
dou ble x ; //declar e variable
x =sin(0.1 9 199);
print f(" sin0,19199= % f \ n",x );
}
/*
运行结果:
sin0.19199=0.190813
*/
函数调用时,必须注意实参与形参在参数的个数,类型,顺序及单位上一一对应匹配 !
C的文件包含和编译过程。
目标模块可执行程序库函数其它目标程序模块 A
模块 B
模块 A
# incl ude <math.h >
模块 B
math.h
fi le1.c
预编译编译链接运行执行结果
格式输出函数 p r i n tf ( ),
一般形式:
prin tf (,输出格式串,,输出参数项表列 ) ;
输出格式串中可以使用三种不同的字符成分,
格式符
转义字符
一般字符功能,按规定的格式把输出项输出到显示屏上格式符的基本形式:
% [< 域宽 > ]< 格式字符 >
如,%6 d,% 1 0.2f,% 1 6s,…
格式符,? %? 打头后跟一个字母部分,
组成特定格式以规定相应输出项的输出形式。
转义字符,? \? 打头后跟一个字母或数字部分,作用是输出控制代码和特殊字母。如? \ n? 为回车换行控制代码。
一般字符,除了格式符和转义字符以外的其它字符,
原样输出,以增加运行结果的可读性。
% d 按十进制整数形式输出
% x 按十六进制整数形式输出
% f 按浮点数 ( 实数 ) 形式输出
% c 按单一字符形式输出
% s 按字符串形式输出
# include <mat h.h >
void m ain() {
dou ble x ; //declar e variable
x =sin(0.1 9 199);
print f(" sin0,19199= % f \ n",x );
}
/*
运行结果:
sin0,19199=0.190 813
*/
三种字符成分可在输出格式串中不同位置上配合使用,
以实现不同的显示效果。
例 [2] 计算一个正弦值。
输出参数可以由一个以上的输出项组成
prin tf (,… %d … %x … %f …”,a,b,c );
printf() 亦可以没有输出项,利用它可输出提示信息。如:
prin tf (,test!,);
要求,输出格式中的格式符与输出项的个数必须相同,
它们按各自的先后顺序一一对应,且符合类型匹配的要求。
整型整型实型
# include <mat h.h >
void m ain() {
print f( " sin0,19199=% f \ n",sin ( 0.19199 ) );
}
C 语言允许函数嵌套调用函数间的调用关系及其称
main ( )
print f( )
sin( )
主调程序被调程序主调程序被调程序
1.4 自定义函数的编写例 [3] 计算

!7!5!3
)sin (
753
xxx
xx
直到最后一项的绝对值小于 时,停止计算。 x 键盘输入。
7
10
讨论,
计算 sin(x) 本来可以利用系统提供的库函数直接求出。但是库函数是如何计算 sin(x) 的呢?如计算公式所指出的那样,这是一个级数求和的问题。其项数决定于最后一项的绝对值是否小于 。如果它大于,继续求下一项,累加到和上,否则结束求和。
7
10
7
10

求出。但是库函数是如何计算决定于最后一项的绝对值是否小于于,继续求下一项,累加到和上,否则结束求和。

!7!5!3
)sin (
753
xxx
xx
设变量为 x,和为 sum,每一项为 term,其类型都说明为双精度 double 。 另外定义一符号常量 EPS 表示误差,
其值为 。
7
10
,,每一项为,
。 另外定义一符号常量

算法描述,( 一级算法 )
1   累加器 sum,term 的初值为 x,n=1;
2   w hile(fa bs (term) >EPS){
3   计算下一项 term;
4   将下一项加到 sum 中。
}
5   输出和 sum 。
数据描述,
其中第 3步需要继续求精 。 每一项单独计算较麻烦,也浪费机时,可以利用前一项求下一项的办法 ( 称递推计算方法 ) 计算 。
由计算公式 。可知
!7!5!3
)s i n (
753
xxx
xx
这对于所有的 n ( n>1 ) 都是成立的。
第 n 项为:
)!12(
)1(
)12(
1
n
x
n
n
第第 n - 1 项为:
)!32(
)1(
)32(
n
x
n
n
第前一项与后一项之间差一个因子:
)12)(22(
2

nn
x
二级求精,
第 3 步,计算下一项 term
3 - 1,n=n+1;
3 - 2,term=term*( - x * x)/(( 2*n - 2)*( 2*n - 1))
1 累加器 sum,term 的初值为 x,n =1;
2 w hile(fab s( term)>EPS) {
3 计算下一项 term;
4 将下一项加到 sum 中。
  }
5 输出和 sum 。
较完整的算法
3-1 n=n+1;
3-2 term=term*(-x*x)
/((2*n-2)*(2*n-1))
计算 ud f_s in(x) 函数和完整的程序如下,
# include <st dio.h >
#includ e <math,h>
#defin e EPS 1e - 7
void m ain() {
  dou ble ud f_s in( d oub le x ); // 用户自定义函数原型说明
  dou ble a;
  scan f(" % lf",&a );
  print f(" % f % f \ n",ud f_s in(a),sin (a) );
}
dou ble ud f_s in( d oub le x ){ // 用户自定义函数
dou ble su m,t erm,n=1;
su m=term=x ;
w hile( fab s( term) > EPS ){
n=n+1;
term=term*( - x * x )/( (2*n - 2)*( 2*n - 1)) ;
su m=su m+term;
}
return( su m) ;
}
运行结果:
input,0.19199
output,0.190813 0.190813
说明:
C 规定变量、符号常数、函数必须先定义后使用:
* 给变量定义就是为变量在内存中分配存储空间,确定其存储形式和规定可 执行的操作
(运算);
* 给函数定义就是确定函数求解问题的功能和过程,及其数据传递的方式等。
说明:
数据传递是程序设计中重要的概念,C 中的数据传递方法可归纳为:
* 参数传递:传值方式和传地址方式;
* 外部变量(全局变量)传递;
* 由 return ( 表达式 ) 语句将表达式的值返回到主调函数的调用处。
本程序的数据传递形态:
采用传值方式,
可理解为简单的将实参 a 的值复制给形参 x
ud f_s in() 0.19199 0.19199 0.19199 1
2000 2004 2008 2012
x sum term n
main () 0.19199
3000

a
dou ble ud f_s in(d oub le x){
dou ble su m,t erm,n=1; s um =term=x ; …… }
void m ain() {
dou ble a; … print f(,% f % f \ n",ud f_s in( a ),s in( a )); }
scanf () 格式函数的形式与使用,格式为:
scanf (,输入格式串,,输入项地址表列);
* 输入格式串的组成同 printf(),一般只使用格式符;
* C 规定输入项必须由地址构成,项与项之间逗号分隔 ;
*? &? 为地址运算符或称取地址符; & a 表示取 a 变量的地址,为地址表达式,运算结果为 3000 。

为地址运算符或称取地址符;

0.19199
3000 a
……
……
scanf() ; 语句的含义为,按指定的格式,将由键盘输入的数据存放到相应地址的存储单元之中去。
scanf( "%lf",&a );
输入格式符的 常 用 方式 与注意事项:
1,三种形式说明,设有 float a,b,c;
scanf(,%f%f%f,,&a,&b,&c );
紧凑无其他字符,按系统规定需 用一个或多个空格分隔输入数据项,亦可用回车键分隔。
输入形式,3.5 4.6 7.9 ↙ 或分行输入,3.5 ↙
4.6 ↙
7.9 ↙
scanf(,%f,%f,%f,,&a,&b,&c );
逗号作为一般字符,原样输入,且可作为数据项之间的分隔符使用;
输入形式,3.5,4.6,7.9 ↙
scanf(,%f%f%f \ n,,&a,&b,&c );
输入形式,3.5 4.6 7.9 \ n ↙
注意,不恰当得使用? \ n? 符,多余。 scanf() 格式串除,%,带头的格式符外,其余字符都要求原样输入,
因为其操作的对象为键盘。
输入 scanf() 函数的格式符必须与输入参 数项的类型一一对应,否则将引起计算 结果的错误。 可参照下表,
shotchar
字符数组
dou blefl oatLon g intint
参数类型
% h% c% s
% l f
% l e
% f % e% ld
% d
% o
%x
格式符参数类型格式符
1.5 C 程序的组成方式:
C 程序组成方式一一个 C 程序由一个源文件组成,运行前只需一次编译,即可生成可执行程序。
C 程序
……
函数 1 函数 n标头文件
C 程序
file.c
一个 C 程序由若干源文件组成,运行前必须分别编译,
并经链接组装后方可运行。 main() 函数只能一个。
C 程序
……
源程序文件 2 源程序文件 n源程序文件 1
函数 2 函数 n函数 1
……
……
……
file1.c file2.c filen.c
C 程序组成方式二
1.6 程序的现代方式与传统方式
#incl ude <math.h > // 现代方式编程示例
#define EP S 1e - 7
void main() {
dou ble udf_si n(dou ble x ); // 现代方式的函数原型说明
dou ble a; scanf(" % lf ",&a); printf(" % f % f \ n",udf_sin (a),si n(a));
}
dou ble udf_si n(dou ble x ){ // 现代方式的函数定义与形参说明形式
dou ble s um,term,n=1; sum=t erm=x ;
w hil e(fabs(t e rm)>EPS ){
n=n+1; term=term*( - x * x)/( (2*n - 2)*(2*n - 1)); s um=sum+term;
}
return(sum);
}
#incl ude <math.h > // 传统方式 编程示例
#define EP S 1e - 7
void main()
{ dou ble a,udf_si n(); // 传统方式的函数原型说明
scanf(" % lf ",&a); pri ntf("% f % f \ n",udf _si n(a),si n(a));
}
dou ble udf_si n( x ) // 传统方式的函数定义与形参说明形式
dou ble x ;
{ doub le s um,term,n=1; sum=t erm=x ;
w hil e(fabs(t e rm)>EPS )
{ n=n+1; term=term*( - x * x)/( (2*n - 2)*(2*n - 1)); s um=sum+term; }
return(sum);
}
# include <stdio.h>
#include <math.h>
#define EPS 1e - 7
void main(){
double udf_sin(double x); // 用户自定义函数原型说明
double a; scanf("%lf",&a);
printf("%f %f \ n",udf_sin(a),sin(a));
}
double udf_sin( double x ){ // 用户自定义函数
double sum,term,n=1; sum=term=x;
while( fabs(term) > EPS ){
n=n+1;
term=term*( - x*x)/((2*n - 2)*(2*n - 1));The end
培 育 英 才 钻 研 科 学书山有径勤为路学海无边苦作舟书山有径勤为路书山有径勤为路学海无边苦作舟学海无边苦作舟