当前位置:首页 >> 其它课程 >> C语言函数复习

C语言函数复习


函 数
1 函数的定义 2 函数的返回值 3 函数的调用 4 函数参数及其传递方式 5 函数的嵌套与递归调用 6 数组作为函数参数 7 变量的存储属性

– 模块化程序设计
? 基本思想:将一个大的程序按功能分割成一些小模块, ? 特点: – 各模块相对独立、功能单一、结构清晰、接口简单 – 控制了程序设计的复杂性 – 提高元件的可靠性

– 缩短开发周期 – 避免程序开发的重复劳动 – 易于维护和功能扩充 ? 开发方法: 自上向下,逐步分解,分而治之

C程序

源程序文件1

源程序文件i

源程序文件n

预编译命令

函数1

函数n

说明部分

执行部分

C程序结构

?C是函数式语言 ?必须有且只能有一个名为main的主函数 ?C程序的执行总是从main函数开始,在main中结束 ?函数不能嵌套定义,可以嵌套调用

函数分类
? 从用户角度 – 标准函数(库函数):由系统提供 – 用户自定义函数 ? 从函数形式 – 无参函数 – 有参函数
使用库函数应注意: 1、函数功能 2、函数参数的数目和顺序,及各参数意义和类型 3、函数返回值意义和类型 4、需要使用的包含文件

函数的定义
–一般格式 合法标识符 函数类型 函数名(形参类型说明表) 现代风格: { 说明部分 语句部分 } 函数体 函数返回 值类型 缺省int型 无返回值 void

例例 有参函数(现代风格) 有参函数(现代风格) 例 无参函数 int max(int x,x,int y) y) 例 空函数 int max(int printstar( ) { int z;z; dummy( ) int { {printf( “**********\n”); z=x>y?x:y; { z=x>y?x:y; } 或 return(z); return(z); 函数体为空 printstar(void ) } } { printf(“**********\n”);

}

}

函数传统风格和例子
传统风格: 函数类型 函数名(形参表) 形参类型说明 { 说明部分 语句部分 } 例 有参函数(传统风格) int max(x,y) int x,y; { int z; z=x>y?x:y; return(z); }

例 无返回值函数 void swap(int x,int y ) { int temp; ? 返回语句 temp=x; – 形式: return(表达式); x=y; – 或 return 表达式; y=temp; } – 或 return; – 功能:使程序控制从被调用函数返回到调用函数中, 同时把返值带给调用函数 – 说明: – 函数中可有多个return语句 – 若无return语句,遇}时,自动返回调用函数 – 若函数类型与return语句中表达式值的类型不一 致,按前者为准,自动转换------函数调用转换 – void型函数

函数的返回值

函数的调用
? 调用形式 – 函数名(实参表); – 说明: – 实参与形参个数相等,类型一致,按顺序一 一对应

–函数的调用方式
– 函数语句: – 例 printstar(); – printf(“Hello,World!\n”); – 函数表达式: – 例 m=max(a,b)*2; – 函数参数: – 例 printf(“%d”,max(a,b)); – m=max(a,max(b,c));

函数 声明
? 对被调用函数要求: – 必须是已存在的函数 – 库函数: #include <*.h> – 用户自定义函数: 函数的定义在主调函数之 后,应在主调函数中对被调用函数作声明 ? 函数声明 – 一般形式: 函数类型 函数名(形参类型 [形参名],….. ); 或 函数类型 函数名(); – 作用:告诉编译系统函数类型、参数个数及 类型,以便检验(所以形参名可以不写)

– 函数定义与函数声明不同 – 函数声明位臵:程序的数据说明部分(函数 内或外) – 下列情况下,可不作函数说明 ?被调用函数定义出现在主调函数之前 ?如果已在文件的开头(在所有函数之前) 已对文件中所调用的函数进行了声明,则 在各函数中不必对其所调用的函数再做声 明。

函数参数及其传递方式
– 形参与实参 ?形式参数:定义函数时函数名后面括号中的变量名 ?实际参数:调用函数时函数名后面括号中的表达式

–例 比较两个数并输出大者
main() { int a,b,c; scanf("%d,%d",&a,&b); c=max(a,b); (main 函数) 实参 c=max(a,b); max(int x, int y)(max 函数) printf("Max is %d",c); { int z; } z=x>y?x:y; 形参 max(int x, int y) return(z); } { int z; z=x>y?x:y; return(z); }

–说明: ? 实参必须有确定的值 ? 形参必须指定类型 ? 形参与实参类型一致,个数相同 ? 若形参与实参类型不一致,自动按形参类 型转换———函数调用转换 ? 形参在函数被调用前不占内存;函数调用时 为形参分配内存;调用结束,内存释放

参数传递方式

? 值传递方式
– 方式:函数调用时,为形参分配单元,并将实参的值 复制到形参中;调用结束,形参单元被释放,实参 单元仍保留并维持原值 – 特点: ?形参与实参占用不同的内存单元 ?单向传递

例 交换两个数 /*ch7_2.c*/ 调用前: #include <stdio.h> main() { int x=7,y=11; printf("x=%d,\ty=%d\n",x,y); 调用: printf("swapped:\n"); swap(x,y); swap: printf("x=%d,\ty=%d\n",x,y); } swap(int a,int b) { int temp; temp=a; a=b; b=temp; 调用结束: }
x: x: a: x: a: 7 7 7 7 11 temp x: 7 y: 11 y: y: b: y: b: 11 11 11 11 7

?函数的地址传递
– 方式:函数调用时,将数据的存储地址作为参数 传递给形参 – 特点: ?形参与实参占用同样的存储单元 ?“双向”传递 ?实参和形参必须是地址常量或变量

/*ch9_3.c*/

swap(p1,p2) int *p1,*p2; { int p; p=*p1; *p1=*p2; *p2=p; } main() {int a,b; scanf("%d,%d",&a,&b); printf(“a=%d,b=%d\n”,a,b); printf(“swapped:\n”); swap(&a,&b); printf(”a=%d,b=%d\n",a,b); }

例 交换两个数

例子图解 调前: a 5 p1 &a 调swap: p2 &b b 9 a 5 b 9 a 9 b 5 b 5

p1
&a 交换: p2 &b a 9

返回:

#include <stdio.h> 文件包含编译预处理命令 long sum(int a, int b); 函数类型说明 long factorial(int n); main() { int n1,n2; long a; long factorial(int n) long sum(int a, int b); { long rtn=1; scanf("%d,%d",&n1,&n2); int i; 函数调用 a=sum(n1,n2); 实参 for(i=1;i<=n;i++) printf("a=%1d",a); rtn*=i; } 函数定义 return(rtn); long sum(int a,int b) } { long factorial(int n); 形参 long c1,c2; c1=factorial(a); 函数调用 c2=factorial(b); 例子解析 return(c1+c2); 函数返回值 }

函数的嵌套与递归调用
– 嵌套调用 C规定:函数定义不可嵌套,但可以嵌套调用 函数 main( ) a函数 b函数
? ? ? ?
?

调用函数a
? ?

调用函数b
?

结束

?

例 求三个数中最大数和最小数的差值
#include <stdio.h> int dif(int x,int y,int z); int max(int x,int y,int z); int min(int x,int y,int z); void main() { int a,b,c,d; scanf("%d%d%d",&a,&b,&c); d=dif(a,b,c); printf("Max-Min=%d\n",d); } int dif(int x,int y,int z) { return max(x,y,z)-min(x,y,z); int max(int x,int y,int z) { int r; r=x>y?x:y; return(r>z?r:z); } int min(int x,int y,int z) { int r; r=x<y?x:y; return(r<z?r:z); }

main( ) 调用函数dif 输出 结束

dif函数 调用函数max 调用函数min

max函数

min函数 Ch7_202.c

递归调用
定义:函数直接或间接的调用自身叫函数的递 归调用
int f(int x) { int y,z; …… z=f(y); ……. return(2*z); } f( )

int f1(int x) { int y,z; …… z=f2(y); ……. return(2*z); } f1( )

int f2(int t) { int a,c; …… c=f1(a); ……. return(3+c); }

f2( )

调f

调f2

调f1

说明 C编译系统对递归函数的自调用次数没有限制 每调用函数一次,在内存堆栈区分配空间,用 于存放函数变量、返回地址及返回值等信息, 所以递归次数过多,可能引起堆栈溢出

例 求n的阶乘

?1 n!? ? ? n ? (n ? 1)!

(n ? 0,1) (n ? 1)

/*ch7_8.c*/ #include <stdio.h> int fac(int n) { int f; if(n<0) printf("n<0,data error!"); else if(n==0||n==1) f=1; else f=fac(n-1)*n; return(f); } main() { int n, y; printf("Input a integer number:"); scanf("%d",&n); y=fac(n); printf("%d! =%15d",n,y); }

? 数组作为函数参数
– 数组元素作函数实参——值传递 #include <stdio.h> main() {例 int a[10],b[10],i,n=0,m=0,k=0; 两个数组大小比较 int large(int x,int y) printf("Enter array a:\n"); { int flag; a b for(i=0;i<10;i++) a和b为有10个元素的整型数组 if(x>y) flag=1; 0 12 i 43 0 scanf("%d",&a[i]); 比较两数组对应元素 else if(x<y) flag=-1; 1 array 23 b:\n"); i 1 else flag=0; 23 printf("Enter 变量 n,m,k 记录a[i]>b[i], a[i]==b[i], 2 56 的个数 i for(i=0;i<10;i++) 2 return(flag); 21 a[i]<b[i] i 3 10 scanf("%d",&b[i]); 98 3 最后 若n>k,认为数组 a>b } i 76 for(i=0;i<10;i++) 4 66 若n<k,认为数组 a<b 4 { if(large(a[i],b[i])==1) n=n+1; i 88 若n==k,认为数组 a==b 5 54 5 else if(large(a[i],b[i])==0) m=m+1; n=0 n=0 n=0 n=1 n=1 n=2 n=3 else k=k+1; m=0 m=0 m=1 m=1 m=1 m=1 m=1 } k=0 k=1 k=1 k=1 k=2 k=2 k=2 /* Output */ }

数组名作函数参数

地址传递 在主调函数与被调函数分别定义数组,且类型应 一致 形参数组大小(多维数组第一维)可不指定 形参数组名是地址变量

#include <stdio.h> void swap2(int x[]) 例 数组元素与 数组名 { int z; 作函数参数比较 z=x[0]; x[0]=x[1]; x[1]=z; } main() 地址传递 { int a[2]={1,2}; swap2(a); printf("a[0]=%d\na[1]=%d\n",a[0],a[1]); }
a
1 2 调用前

a x

1 2

a x

a
2 1 2 1 返回

调用

交换



数组排序----简单选择排序

void sort(int array[],int n) { int i,j,k,t; for(i=0;i<n-1;i++) { k=i; for(j=i+1;j<n;j++) if(array[j]<array[k]) k=j; if(k!=i) a { t=array[i]; array array[i]=array[k]; array[k]=t; i=0 } } }

main() { int a[10],i; for(i=0;i<10;i++) scanf("%d",&a[i]); sort(a,10); for(i=0;i<10;i++) printf("%d ",a[i]); printf("\n"); }
49 9 68 57 32 9 49 99 27 13 76 88 0 1 2 3 4 5 6 7 8 9

k j j j j j j j j j

k k

数组排序----简单选择排序main() { int a[10],i; for(i=0;i<10;i++) void sort(int array[],int n) scanf("%d",&a[i]); { int i,j,k,t; sort(a,10); for(i=0;i<n-1;i++) for(i=0;i<10;i++) { k=i; printf("%d ",a[i]); for(j=i+1;j<n;j++) printf("\n"); if(array[j]<array[k]) k=j; } if(k!=i) a { t=array[i]; 49 0 9 array array[i]=array[k]; 68 1 13 k 57 2 array[k]=t; j i=1 32 3 } j 9 4 49 j } 99 5 j } 例
27 13 68 76 88 6 7 8 9

k k k k

j j j j

数组排序----简单选择排序 main() { int a[10],i; for(i=0;i<10;i++) void sort(int array[],int n) scanf("%d",&a[i]); { int i,j,k,t; sort(a,10); for(i=0;i<n-1;i++) for(i=0;i<10;i++) { k=i; printf("%d ",a[i]); for(j=i+1;j<n;j++) printf("\n"); if(array[j]<array[k]) k=j; } if(k!=i) a { t=array[i]; 9 0 array array[i]=array[k]; 13 1 27 2 array[k]=t; i=8 32 3 } 49 4 } 57 5 } 例
68 76 88 99 6 7 8 9

变量的存储属性
– 概述
? 变量是对程序中数据的存储空间的抽象 main() { int a; a=10; printf(“%d”,a); }
内存

2000 2001

10

程序中使用变量名对内存操作

…….

变量的存储属性
概述 变量是对程序中数据的存储空间的抽象 变量的属性 数据类型:变量所持有的数据的性质(操作属性) 存储属性 存储器类型:寄存器、静态存储区、动态存储区 生存期:静态变量与动态变量 作用域:局部变量与全局变量 变量的存储类型 auto -----自动型 如: int sum; register-----寄存器型 auto int a,b,c; static ------静态型 register int i; extern -----外部型 static float x,y; 变量定义格式: [存储类型] 数据类型 变量表 ;

局部变量与全局变量 例例 不同函数中同名变量 不同函数中同名变量
例 复合语句中变量 例 复合语句中变量 main() main() ? 局部变量---内部变量 float f1(int a) N 5 #define { int a,b; { int a,b; #define N 5 –定义:在函数内定义,只在本函数内有效 { int b,c; main() a=3; a=3; main() a,b,c有效 ……. –说明: { i;int i; b=4; b=4; { int }

? main中定义的变量只在 main 中有效 int a[N]={1,2,3,4,5}; printf("main:a=%d,b=%d\n",a,b); printf("main:a=%d,b=%d\n",a,b); int a[N]={1,2,3,4,5}; ? 不同函数中同名变量,占不同内存单元 char f2(int x,int y) for(i=0;i<N/2;i++) sub(); sub(); for(i=0;i<N/2;i++) { int i,j; { temp; int temp; printf("main:a=%d,b=%d\n",a,b); ? 形参属于局部变量 printf("main:a=%d,b=%d\n",a,b); { int x,y,i,j有效 …… temp=a[i]; } } } temp=a[i]; ? 可定义在复合语句中有效的变量 运行结果: a[i]=a[N-i-1]; sub() sub() main:a=3,b=4 ? 局部变量可用存储类型:auto a[i]=a[N-i-1]; register a[N-i-1]=temp; { {intint a,b; a,b; a[N-i-1]=temp; main() sub:a=6,b=7 static (默认为 auto) { } int m,n; } a=6; main:a=3,b=4 a=6; m,n 有效 ……. for(i=0;i<N;i++) b=7; b=7; for(i=0;i<N;i++) } printf("%d ",a[i]); printf("sub:a=%d,b=%d\n",a,b); printf("sub:a=%d,b=%d\n",a,b); printf("%d ",a[i]); } } } }
运行结果:5 4 3 2 1

全局变量

---外部变量 定义:在函数外定义,可为本文件所有函数共用 有效范围:从定义变量的位臵开始到本源文件结 束,及有extern说明的其它源文件 extern 数据类型 变量表;

外部变量说明:

外部变量定义与外部变量说明不同
若外部变量与局部变量同名,则外部变量被屏蔽 外部变量可用存储类型:缺省 或 static

>

应尽量少使用全局变量,因为: ?全局变量在程序全部执行过程中占用存储单元 定义 说明 ?降低了函数的通用性、可靠性,可移植性 ?次数: ?降低程序清晰性,容易出错 只能1次 可说明多次 ?位臵: 所有函数之外 函数内或函数外 ?分配内存: 分配内存,可初始化 不分配内存,不可初始化

例子解析(1)

float max,min; float average(float array[], int n) { int i; float sum=array[0]; max=min=array[0]; for(i=1;i<n;i++) { if(array[i]>max) max=array[i]; else if(array[i]<min) min=array[i]; sum+=array[i]; max } min return(sum/n); } 作 main() 用 域 { int i; float ave,score[10]; /*Input */ ave=average(score,10); printf("max=%6.2f\nmin=%6.2f\n average=%6.2f\n",max,min,ave); }

例子解析(2)

扩 扩 展 展 后 后 c1,c2 c1,c2 的 的 作 作 用 用 范 范 围 围

int p=1,q=5; extern char c1,c2; float f1(int a) { int b,c; extern char c1,c2; ……. } int f3() {….. } char c1,c2; char f2(int x,int y) { int i,j; …… } main() { int m,n; ……. }

p,q的作用范围

c1,c2的作用范围



外部变量定义与说明

int max(int x, int y) extern int a,b; { int z; int max() z=x>y?x:y; { int z; return(z); z=a>b?a:b; } return(z); main() } { extern int a,b; main() printf("max=%d",max(a,b)); { printf("max=%d",max()); } } int a=13,b=-8; int a=13,b=-8;

运行结果:max=13



外部变量与局部变量

/*ch7_17.c*/ int a=3,b=5; max(int a, int b) { int c; c=a>b?a:b; return(c); } main() { int a=8; printf("max=%d",max(a,b)); }

运行结果:max=8

动态变量与静态变量
? 存储方式
– 静态存储:程序运行期间分配固定存储空间 – 动态存储:程序运行期间根据需要动态分配存储空间 ? 内存用户区 生存期 静态变量:从程序开始执行到程序结束 动态变量:从包含该变量定义的函数开始执行至函数执行结束

程序区
静态存储区 动态存储区 全局变量、局部静态变量 形参变量 局部动态变量(auto register) 函数调用现场保护和返回地址等

局部变量

变量存储类型

外部变量

register 局部static 外部static 外部 存储类别 auto 动态 静态 存储方式 静态存储区 寄存器 存储区 动态区 生存期 函数调用开始至结束 程序整个运行期间 作用域 定义变量的函数或复合语句内 本文件 其它文件 赋初值 每次函数调用时 编译时赋初值,只赋一次 未赋初值 不确定 自动赋初值0或空字符 ?局部变量默认为auto型 ?register型变量个数受限,且不能为long, double, float型 ?局部static变量具有全局寿命和局部可见性 ?局部static变量具有可继承性 ?extern不是变量定义,可扩展外部变量作用域

-------Main-----例 变量的寿命与可见性 33 75 43 全局i 1 i:1 a:0 b:-10 c:0 0 main: a #include <stdio.h> ------Other-----6 4 2 other: a int i=1; i:33 a:4 b:0 c:15 other: b 0 6 4 main() -------Main----i:33 a:0 b:-10 c:8 { static int a; -------Other------register int b=-10; i:75 a:6 b:4 c:15 int c=0; 15 10 other: c 0 main:c printf("-----MAIN------\n"); 8 other() printf("i:%d a:%d \ b:-10 register { static int a=2; b:%d c:%d\n",i,a,b,c); static int b; c=c+8; int c=10; other(); a=a+2; i=i+32; c=c+5; printf("-----MAIN------\n"); printf("-----OTHER------\n"); printf("i:%d a:%d \ printf("i:%d a:%d \ b:%d c:%d\n",i,a,b,c); b:%d c:%d\n",i,a,b,c); i=i+10; b=a; other(); } }

静态 存储区

动态 存储区

#include <stdio.h> #define NULL 0 Struct student { long num; Float score; Struct student *next; };

Void main() { struct student a,b,c,*head,*p; a.num=10101;a.score=89.5; b.num=10103;b.score=90; c.num=10107;b.score=85; Head=&a; a.next=&b; b.next=&c;c.next-null; P=head; Do { printf(“%ld%5.1lf\n”,p>num,p->score); p=p->next; }while(p!=NULL);

}

? ? ? ?

For语句 Malloc函数 Realloc 函数 Free函数

上机实践题
? 有10个学生,每个学生的数据包括学号, 姓名,3门课程的成绩,从键盘输入10个学 生数据,要求输出3门课程总平均成绩,以 及最高分的学生的数据(包括学号、姓名、 3门课程成绩、平均分数)。 (书上318页习题11.5)


更多相关文档:

C语言函数知识点总结

9。定义有参函数的一般形式为: 类型标识符 函数名(形式参数表列) { 声明部分; 语句; } 10.在 C 语言中,可以用以下几种方式调用函数 (1)函数表达式 函数...

C语言函数复习题答案

C语言函数复习题答案_理学_高等教育_教育专区。C 语言函数复习题答案 1、 /*编写程序, AB(A 的 B 次幂)。求 要求:实现求 AB 的功能用函数实 现,在主...

C语言复习题函数

C语言复习函数_IT/计算机_专业资料。C语言(谭浩强)复习题库(五)C程序函数专题 C 语言复习题_函数 一、选择 1、当调用函数时,实参是一个数组名,则向函数...

C语言编程练习题绝对经典!

C语言编程练习题绝对经典!_IT认证_资格考试/认证_教育专区。C语言编程练习 ...子函数 2,验证和是否为回数, 是则主函数打印“经过 n 次计算,得到回数”,...

C语言函数练习题

设计一个函数,使输入的一个字符串按反序存放,在主函数中输入和输 出字符串。...C语言函数复习题答案 2页 免费 C语言函数练习题 6页 1下载券©...

C语言函数练习题

C语言函数练习题_院校资料_高等教育_教育专区。C语言函数练习题 C 语言函数练习题 一、选择题 1.一个完整的 C 源程序是【】。 A)要由一个主函数或一个以上...

C语言函数编程练习

C语言函数编程练习_工学_高等教育_教育专区。c语言函数编程练习,适合初学者和考二级c的童鞋 函数编程练习 1、编写两个函数,分别求最大公约数(greatest common ...

C语言函数习题及答案

若函数调用时的实参为变量时,以下关于函数形参和实参的叙述中正确的是【 】。 ...C语言函数复习题答案 2页 免费 C语言函数复习题答案 2页 免费 c语言函数习...

C语言练习题调用函数

C语言练习题调用函数_IT认证_资格考试/认证_教育专区。C语言练习题调用函数 Problem A: 判断素数的函数 Time Limit: 1 Sec Memory Limit: 64 MB Submit: 7305...

c语言函数练习题附答案

下列函数中,能够从键盘上获得一个字符数据的函数是( A、 puts( ) B、 put...C语言函数练习题 15页 1下载券 C语言练习题(复习题) 函... 3页 1下载券...
更多相关标签:
网站地图

文档资料共享网 nexoncn.com copyright ©right 2010-2020。
文档资料共享网内容来自网络,如有侵犯请联系客服。email:zhit325@126.com