结构化程序设计的思想是将一个问题分解为若干个小问题

  • 格式:pdf
  • 大小:174.97 KB
  • 文档页数:13

下载文档原格式

  / 13
  1. 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
  2. 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
  3. 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
for(j=i+1;j<n;j++) if (array[j]<array[k]) k=j;
if (k!=i) {temp=array[k]; array[k]=array[i]; array[i]=temp; } } } main() { float a[10]; int i; for(i=0;i<10;i++)
c=max(a,b);
printf(“max is :%d\n”,c);
}
max (int x,int y)
{int z;
if (x>=y) z=x;
else z=y;
return z;
} 说明:
(1) (2) (3) (4) (5)
形参只有在函数调用时才分配单元,调用结束后形参所占的单元随即释放 实参可以是常量、变量或表达式 定义函数时,必须指定形参的类型 实参与形参的类型相同或赋值兼容,整型可对应实型形参(低对高) C 语言中,实参对形参的数据传递是值传递,所以形参的值不会反过来影响实参
个主调函数中不必对所调用的函数再作说明
char letter(char,char); float f(float,float); int i(float,float); main() {…..} char letter(char c1,char c2) {……} …… 声明函数不同于定义函数,只给出函数类型,名字及参数,这种形式称为函数原型。 函数原型的一般形式: (1) 函数类型 函数名(参数类型 1,参数类型 2……); (2) 函数类型 函数名(参数类型 1 参数名 1,参数类型 2 参数名 2,……); 例,float add(float a,float b); 或 float add(float ,float );
8.6 函数的递归调用
函数直接或间接地调用自己,称为递归调用,且分别称为直接递归和间接递归。 例 1,有 5 个人坐在一起,问第 5 个人多少岁,他说比第 4 个大 2 岁。……问最后一个人, 他说 10 岁。请问第 5 个人多大
10 age(n)= age(n-1)+2
(n=1) (n>1)
int age(int n) {int c; if (n==1) c=10; else c=age(n-1)+2; return c;} main() { printf(“%d”,age(5)); } 例 2,求 n! 可以用递推和递归两种方法求解。 float fac(int n)
{float x,y,y1; y1=f(x1); do {x=xpoint(x1,x2); y=f(x); if (y*y1>0) {x1=x;y1=y;} else x2=x; }while(fabs(y)>=1e-6); return x; } /*主函数*/ main() {float x1,x2,x,f1,f2;
8.8 局部变量和全局变量
8.8.1 局部变量
在函数内部定义并使用的变量称为局部变量。 (1) 主函数中定义的变量也只有在主函数中有效。 (2) 不同函数内定义的变量可以用相同的名字 (3) 形参是局部变量 (4) 函数中的复合语句内可以定义变量,只在复合语句内有效 main() {int a,b=1;
20
8.3.2 函数的返回值
(1) (2) (3)
return 语句向主调函数返回值 当 return 返回的值的类型与函数定义的类型不同时,以函数类型为准 定义函数时应给出函数类型,如果没有给定,C 语言按整型处理,如果不需要函数 返回值,可用 void 明确标识
8.4 函数的调用
8.4.1 函数调用的一般形式
8.5 函数的嵌套调用
C 语言不允许嵌套定义函数,但允许嵌套调用
main 函数


a 函数


b 函数
调用 a 函数
调用 b 函数

⑨ ⑧
结束


例,用弦截法求方程f(x)=x3-5x2+16x-80=0 的根。 #include<stdio.h> #include<math.h> /*定义函数 f(x)*/ float f(float x) {float y; y=x*x*x-5*x*x+16*x-80; return y; } /*求(x1,f(x1))和(x2,f(x2))所构成的直线与 x 轴的交点*/ float xpoint(float x1,float x2) {float x; x=(x1*f(x2)-x2*f(x1))/(f(x2)-f(x1)); return x; } /*用弦解法求方程的根*/ float root(float x1,float x2)
用。 (3) C 程序从 main()开始执行和结束执行 (4) 所有函数是平行的,不可以嵌套定义,但可以嵌套调用 (5) 从用户的角度看,函数分为标准函数(库函数)和用户自定义函数 (6) 从函数形式看,分为有参函数和无参函数
8.2 函数定义的一般形式
类型标识符 函数名(形式参数列表) {声明部分; 语句部分; } 说明: (1) 当函数不需要返回值时,可以没有类型说明符 (2) 可以没有形参 (3) 函数体可以为空,只有一个大括号
8.7 数组做为函数参数
8.7.1 数组元素做为参数(实参)
同一般的变量,也是值传递。
8.7.2 数组名作参数(形参、实参)
形参和实参都用数组名,是地址传递。有以下几种形式处理形参: (1) float aver(float array[10]) 实参数组的大小不起作用,只是用数组名来接收地址 (2) float aver(float array[]) 同(1) (3) float aver(float array[],int n) 如果函数中需要数组的大小,则别设一参数 n 来动态表
第八章 函数
8.1 概述
结构化程序设计的思想是将一个问题分解为若干个小问题,小问题由单独的模块来实 现。C 语言用函数来实现模块,所以 C 语言是函数式的语言。一个 C 程序有一个由 main 开 头的主函数,由主函数调用其他函数,同一个函数可以被多次调用。 main() /*主函数*/ {printstar(); printmess(); printstar(); } printstar() /*自定义函数*/ {printf("************************\n"); } printmess() /*自定义函数*/ {printf("This is an example!\n"); } 函数说明: (1) 一个源程序文件由一个或多个函数构成,一个源程序文件是一个编译单位。 (2) 一个 C 程序由一个或多个源程序文件组成,可以分别编译;一个程序可以多次被调
8.4.3 对被调用函数的声明和函数原型
在一个函数中调用另一个函数的条件: (1) 被调用函数已经存在 (2) 使用库函数,用#include 命令将有关库函数包含进来 (3) 如果是用户自定义的函数,则被调函数应与主调函数在同一文件,一般情况下在主
调函数中对被调函数进行声明;如果对函数没有声明,编译系统会把第一次遇到该 函数(定义或调用)作为函数声明,并将函数类型默认为 int 型,但最好做声明,便 于编译程序进行全面合法性检查。所以可以有以下几种处理方法: ¾ 先定义被调函数 ¾ 后定义被调函数,且被调函数为整型 ¾ 后定义非整型被调函数,有主调函数中声明 ¾ 在所有函数(包括 main 函数)定义之前,在函数的外部已做了函数声明,则在各
swap(int x,int y)
{int temp;
temp=x;
x=y;
y=temp;
}
main()
{
int a=10,b=20;
swap(a.b);
printf(“a=%d, b=%d\n”,a,b);
} 输出:a=10,b=20 实参与形参的结合过程:用 FLASH 实现
a
b
10
20
x
y
10
函数名(实际参数);
8.4.2 函数调用的方式
(1) 函数语句,如 printstar(); (2) 函数表达式:出现在表达式可以出现的地方,如赋值号的右侧或打印语 句 中
c=max(a,b); (3) 函数参数:做为另一个函数的实际参数
m=max(a,max(b,c)); 所以,函数不可以嵌套定义,但可以嵌套调用
scanf(“%d”,&a); {int c;
c=a+b; } printf(“%d”,c);//出错,因为 c 是复合语句内定义的,在外面是无效的 } main() {int a,b=1; scanf("%d",&a); { int a; a=10; printf("inner a=%d\n",a); } printf("exter a=%d\n",a); } 输入:100 输出: inner a=10 exter a=100
8.3 函数参数和函数值
8.3.1 函数的形式参数和实际参数
调用函数时,主调函数和被调函数之间有数据传递关系。定义函数时括号内的参数称为 形式参数,形参是变量;调用时给定的参数称为实际参数,实参可以是变量,也可以是表达
式。
main()
{int a,b,c;
scanf(“%d,%d”,&a,&b);
{ int i; float t=1; if (n<0) {printf("error"); exit(0);} else for (i=1;i<=n;i++) t=t*i; return t; } float fac(int n) {float t; if (n<0) {printf("error");exit(0);} else if (n==0||n==1) t=1; else t=n*fac(n-1); return t; } 用图进行跟踪求解 3!的过程 例 3,Hanoi 塔问题 有三个柱子 A,B,C,开始柱子 A 上有若干个大小不等的盘子,且大盘子在下,小盘子在上。 要把柱子 A 上的盘子全部移到柱子 C 上,但一次只能移一个盘子,且不能出现大盘子压小盘 子。以两个盘子为例,移动过程如下: 用 FLASH 实现 /* 将盘子从柱子 x 移到柱子 y 上*/ void move(char x,char y) {printf("%c->%c\n",x,y); } /*递归函数*/ void hanio(int n,char x,char y,char z) { if (n==1) move(x,z); else {hanio(n-1,x,z,y); move(x,z); hanio(n-1,y,x,z); } } main() {int m; printf("pls input the number of disks:\n"); scanf("%d",&m); hanio(m,'A','B','C'); }
scanf("%f",&a[i]); sort(a,10); for(i=0;i<10;i++)
printf("%6.2f",a[i]); }
8.7.3 用多维数组名作函数参数
多维数组作为形参时,可以省略第一维的大小,其余的不可以省略。 int array[3][10];
int array [][10]; 二维数组是由若干个一维数组构成,而形参数组的类型应与实参数组相同,所以它们必须由 具有相同长度的一维数组所组成。不能只指定第一维而省略第二维。 int array [3][];是错误的 在第二维相同的情况下,第一维可以不同, 实参:int score[5][10]; 形参可以是:int array[3][10]; 或 int array[8][10];
示元素多少,这种方式最常用 由于数组是地址传递,所以形参的变化反过来影响实参 例 1,用简单选择排序对数组中的元素进行从小到大排序。用 FLASH 演示(地址传递,排 序过程) void sort(float array[],int n) {int i,j,k; float temp; for(i=0;i<n-1;i++) {k=i;
do {printf("input x1 and x2:\n"); scanf("%f%f",&x1,&x2); f1=f(x1); f2=f(x2); }while(f1*f2>=0Biblioteka Baidu; x=root(x1,x2); printf("the root of equation is: %f\n",x); }