第7章 函 数 为什么要使用函数? 函数定义、调用、声明 局部变量和全局变量 变量的存储类别 内部函数和外部函数 函数的嵌套调用和递归调用

Slides:



Advertisements
Similar presentations
第 8 章 数组 计算机科学学院 李淮 Tel QQ
Advertisements

第8章 函数 信息管理系.
第一章 C语言概述 计算机公共教学部.
C语言程序设计.
C语言程序设计 第八章 函数.
第5章 函数与模块化设计 学习目的与要求: 掌握函数的定义及调用方法 理解并掌握参数的传递方法 理解函数的嵌套与递归调用
4.3函数 4.3.1函数的概念及定义 1、函数的概念: 可以被其它程序调用具有 特定功能的一段相对独立的 程序(模块),称函数。
第六章 数 组 主讲教师 贾月乐 联系电话:
第5章 函数与预处理 《 C语言程序设计》 (Visual C++ 6.0环境) 本章导读
第5章 函数及变量的存储类别 5.0 概述 5.1函数的定义 5.2函数调用 5.3变量的作用域和存储类别 5.4内部函数和外部函数
第一章 C语言概述.
由C程序结构所知,一个完整的C语言程序是由一个且只能有一个main()函数(又称主函数)和若干个其他函数组合而成的。而前面各章仅学习main()函数的编程,本章将介绍其他函数的编程,包括其他函数的定义、调用、参数传递及变量的作用域等。
第八章 函数 §8.1 概述 一个较大程序一般分为若干个程序模块,每一个模块实现一个特定的功能。所有的高级语言中都有子程序的概念,在C中子程序就是函数。 一个C程序可由一个主函数和若干个函数构成,由主函数调用其它函数,其它函数也可以相互调用.
循环结构又称为重复结构:用来处理需要重复处理的问题,它是程序中一种很重要的结构。
第3章 顺序结构程序设计 本章要点: 格式化输出函数──printf() 格式输入函数——scanf() 字符输出函数——putchar()
第4章 函数与预处理 4.1 概述 4.2 定义函数的一般形式 4.3 函数参数和函数的值 4.4 函数的调用 *4.5 内置函数
C语言程序设计基础 刘新国.
目录 第八章 数组 1 简单学生成绩管理系统的开发 2 一维数组 3 多维数组 4 字符数组 5 数组作函数参数.
第七章 函数 目录 有参的加法函数的开发 函数定义的一般形式 函数参数和函数的值 函数的调用
第7章 函 数 本章要点: C语言程序结构和特点 函数的定义 函数的返回值与函数的类型 函数的调用及参数的传递关系 函数的嵌套与递归
C程序设计 谭浩强 著 清华大学出版社.
第八章 函数.
辅导课程六.
第6章 函数 学习的意义.
第一单元 初识C程序与C程序开发平台搭建 ---观其大略
6.4.1指针与二维数组 1、二维数组结构的分析 设有数组定义为:int a[3][4]; 则有: a表示数组在内存中的首地址。
Chap 5 函数 5.1 计算圆柱体积 5.2 使用函数编写程序 5.3 变量与函数.
第7章 用函数实现模块化程序设计 7.1为什么要用函数 7.2怎样定义函数 7.3调用函数 7.4对被调用函数的声明和函数原型
第八章 使用指针.
谭浩强 编著 中国高等院校计算机基础教育课程体系规划教材 C++程序设计.
第七章 函数 西安工程大学.
第五章 习题课 电子信息与计算机科学系 曾庆尚.
第七章 函数及变量存贮类型 7.1 函数基础与C程序结构 7.2 函数的定义和声明 7.3 函数的调用 7.4 函数的嵌套与递归
第0章作业: 教材P12-练习与实践 1.写出用符号’*’输出描绘汉字”大”的流程图。
数组 梁春燕 华电信息管理教研室.
第1章 概述 本章要点: C语言程序结构和特点 C语言程序的基本符号与关键字 C语言程序的编辑及运行 学习方法建议:
C++语言程序设计 C++语言程序设计 第七章 类与对象 第十一组 C++语言程序设计.
C语言大学实用教程 第5章 函数与程序结构 西南财经大学经济信息工程学院 刘家芬
THE C PROGRAMMING LANGUAGE
第 二 章 数据类型、运算符与表达式.
C语言复习2----函数.
第一章 程序设计和C语言 主讲人:高晓娟 计算机学院.
C语言程序示例: 1.输入10个数,按从小到大的顺序排序。 2.汉诺塔问题。.
C程序设计.
C语言大学实用教程 第6章 数组 西南财经大学经济信息工程学院 刘家芬
第7章 函 数 7.1 函数的定义与调用 7.2 函数的嵌套调用与递归调用 7.3 数组作为函数参数 7.4 内部变量与外部变量
Main() { Dfas Asdfasf fasdfa } #include <stdio.h> void main( ) {
函数 概述 模块化程序设计 基本思想:将一个大的程序按功能分割成一些小模块, 特点: 开发方法: 自上向下,逐步分解,分而治之
C语言程序设计.
目录 7.1 用户自定义函数的种类 7.2 函数的定义 7.3 被调函数的声明 7.4 函数的调用 7.5 函数的嵌套调用
7.1 C程序的结构 7.2 作用域和作用域规则 7.3 存储属性和生存期 7.4 变量的初始化
第五章 函 数 要点:掌握函数的定义,函数的原形,函数的返回值,函数的调用,函数的形式参数和实际参数之间的关系;掌握函数重载的使用方法,关键字inline的含义与使用,掌握变量的作用域与生存期,了解函数的作用域。
第十章 指针 指针是C语言的重要概念,是C语言的特色,是C语言的精华。 10.1 地址和指针的概念 内存中的每一个字节都有一个地址。
C程序设计.
第5章 函 数.
第一章 C语言概述 教师:周芸.
第4章 Excel电子表格制作软件 4.4 函数(一).
C语言程序设计 李祥 QQ:
第九节 赋值运算符和赋值表达式.
第2章 数据类型、运算符与表达式 本章要点: 基本数据类型 常量和变量 算术运算符和算术表达式 关系运算符和关系表达式
第二章 类型、对象、运算符和表达式.
多层循环 Private Sub Command1_Click() Dim i As Integer, j As Integer
第7章 模板 陈哲 副教授 南京航空航天大学 计算机科学与技术学院.
第7章 用函数实现模块化程序设计 7.1为什么要用函数 7.2怎样定义函数 7.3调用函数 7.4对被调用函数的声明和函数原型
本节内容 C语言的汇编表示 视频提供:昆山爱达人信息技术有限公司 官网地址: 联系QQ: QQ交流群 : 联系电话:
C++语言程序设计 C++语言程序设计 第一章 C++语言概述 第十一组 C++语言程序设计.
第三章 流程控制 程序的运行流程 选择结构语句 循环结构语句 主讲:李祥 时间:2015年10月.
C程序设计 复习 1、计算机系统的组成 外部设备:输入、输出设备(同人打交道《十进制》)
C语言基础学习 从外行到入门.
计算机编程 信息管理与工程学院 2014年9月.
Presentation transcript:

第7章 函 数 为什么要使用函数? 函数定义、调用、声明 局部变量和全局变量 变量的存储类别 内部函数和外部函数 函数的嵌套调用和递归调用 第7章 函 数 为什么要使用函数? 函数定义、调用、声明 形参和实参 返回值 数组作为函数参数 局部变量和全局变量 变量的存储类别 内部函数和外部函数 函数的嵌套调用和递归调用 小 结 习 题 游 戏

哪个程序扩展性更好? 例:求a、b两个数中的最大数 a=5; b=10; else m=b; void main() void main() { int a,b,m; a=5; b=10; if (a>b) m=a; else m=b; printf("max=%d",m); } void main() { int a,b,m; a=5; b=10; m=max(a,b); printf("max=%d",m); } int max ( int x, int y ) { int z; if (x>y) z=x; else z=y; return(z);

哪个程序扩展性更好? 例:求a、b、c、d四个数中的最大数 void main() { int a=1,b=3,c=2,d=5,m; if (a>b) m=a; else m=b; if (c>m) m=c; if ( d>m) m=d; printf("%d",m); } void main() { int a=1,b=3,c=2,d=5,m,e,f; e=max(a,b); f=max(c,d) m=max(e,f); printf("%d",m); } int max ( int x, int y ) { int z; if (x>y) z=x; else z=y; return(z);

怎样让程序看起来简单明了? aver=average(a,n); 例 数组求平均数 例 冒泡排序 void main() 例 数组求平均数 例 冒泡排序 void main() { int a[10], i,t; float aver; for(i=0;i<10;i++) scanf("%d",&a[i]); for(i=0;i<9;i++) aver +=a[i]; aver=aver/10; printf("aver=%f",aver); for(i=0;i<=9;i++) printf("%d ",a[i]); } #include <stdio.h> void main() { int i,j,a[10]; printf("input 10 numbers:\n"); for(i=0;i<10;i++) scanf("%d",&a[i]); printf("\n"); for(j=0;j<9;j++) for(i=0;i<9-j;i++) if(a[i]>a[i+1]) {t=a[i]; a[i]=a[i+1]; a[i+1]=t;} printf("%d ",a[i]); } 输 入 核 心 输 出 //输入数组a[n]函数 inputarray(a,n); inputarray(a,10); //求数组平均数函数 aver=average(a,n); //求数组冒泡排序函数 sort(a,10); //输出数组a[n]函数 outputarray(a,n); outputarray(a,10);

函数的定义 (1)C语言源程序,由若干个函数函数组成,至少包含一个main函数。程序总是从main函数开始执行。 (2)函数结构 #include<stdio.h> void main() {int max(int x, int y); int a,b,c; scanf("%d,%d",&a,&b); c=max(a,b); printf("max=%d",c); } int max ( int x, int y ) { int z; if (x>y) z=x; else z=y; return(z); (1)C语言源程序,由若干个函数函数组成,至少包含一个main函数。程序总是从main函数开始执行。 (2)函数结构 [函数类型] 函数名([函数参数表]) { [说明语句部分] [执行语句部分] [return ] }

函数分类 用户使用角度: (1) 库函数-----C语言提供的函数 (2) 自定义函数:完成特殊功能 函数参数: (1) 无参数的函数。 (2)有参数的函数,主调函数与被调函数之间有数据传递。 函数返回值: (1) 无返回值的函数。 void (2)有返回值,带回一个值到主函数 能否被其它源文件调用: (1) 内部函数; (2) 外部函数(如库函数) #include<stdio.h> void main( ) { int max(int x, int y); int a,b,c; scanf("%d,%d",&a,&b); c=max(a,b); printf("max=%d",c); } int max ( int x, int y ) { int z; if (x>y) z=x; else z=y; return(z);

函数 函数声明 函数调用 函数参数 函数返回值 #include<stdio.h> void main() { int max ( int x, int y ); int a,b,c; scanf("%d,%d",&a,&b); c=max(a,b); printf("max=%d",c); } /*求最大值函数*/ int max ( int x, int y ) { int z; if (x>y) z=x; else z=y; return(z); 函数声明 函数调用 函数参数 函数返回值

函数参数:形参和实参1/4 void main() { int max(int x, int y); int a,b,c; scanf("%d,%d",&a,&b); c=max(a, b); printf("max=%d",c); } int max (int x, int y ) { int z; if (x>y) z=x; else z=y; return(z); a b c 10 5 10,5 10 函数返回 函数调用 x y 10 5 10 5 实参:调用函数时实际使用的变量或表达式 z 10 形参:函数定义时参数表中的变量名

函数参数:形参和实参2/4 void main() { int a,b,c; scanf("%d,%d",&a,&b); c=max(a, b); printf("max=%d",c); } int max (int x, int y ) { int z; if (x>y) z=x; else z=y; return(z); 说明:1.形参和实参 必须相同:个数相等 次序相同 类型一致 (否则自动转换) 不必相同: 变量名 实参 例:形参和实参类型不同 int max (int x,int y) { return(x>y?x:y); } main(){ printf("%d",max(4.7,9.6)); } /*输出结果9*/ 形参

函数参数:形参和实参3/4 void main() { int a,b,c; scanf("%d,%d",&a,&b); c=max(a, b); printf("max=%d",c); } int max (int x, int y ) { int z; if (x>y) z=x; else z=y; return(z); 说明:2.形参存储空间 (1)函数被调用时才给形参分配存储单元 (2)实参和形参占用不同的内存单元,同名也互不影响。 (3)函数返回时释放形参所占空间 函数返回 函数调用 10 5 实参 a b c 10 5 int max (int a, int b ) 形参 10 a b 10 5 x y z 10

函数参数:形参和实参4/4 练习:程序运行结果是什么 void main() { int a=5; fun(a); printf("a=%d",a); } void fun(int a) { a=a+5; 1.实参和形参有不同的存储单元 2.实参给形参仅仅是"值传递" 3. 对形参的任何改变不会影响实参 因此:主函数中a不变 实参 5 a 值传递 形参 5 a 10 运行结果: a=5

函数的返回值 void main() { int a,b,c; scanf("%d,%d",&a,&b); c=max(a, b); return ( 返回值表达式 ); (1) 将流程返回给主调用函数 (2) 将"返回值表达式"的值通过函数名带回主调函数。 (3) void: 明确表示不返回值 void main() { int a,b,c; scanf("%d,%d",&a,&b); c=max(a, b); printf("max=%d",c); } int max (int x, int y ) { int z; if (x>y) z=x; else z=y; return(z); 函数返回 函数调用 10 5 实参 a b c 10 5 10 形参 10 5 x y z 10

函数调用 main() { int a,b,c,m; a=5;b=10;c=15; m=max(a, b); printf("max=%d",m); } int max (int x, int y ) { int z; if (x>y) z=x; else z=y; return(z); 函数调用的一般形式: 函数名([实际参数表]) (1)函数表达式。 函数作为表达式的一项, 以函数返回值参与相关的运算 c=2*max(a,b); (2)函数实参。 把函数的返回值作为另一个 函数调用的实际参数出现。 m=max(max(a,b),c) (3)函数语句。 多用于无返回值的函数。 m=max(max(a,b),c); m=2*max(a,b); 函数返回 函数调用 10 5 实参 形参

函数的声明 例:void main() { float a,b,c,s; scanf("%f %f %f",&a,&b,&c); s=sum(sum(a,b),c); /*函数的调用*/ printf("sum=%f",s); } float sum(float x,float y) /*函数的定义*/ { return(x+y); float sum(float x,float y); /*函数的声明*/

函数的声明 错!不能省略参数类型 函数声明: 在主调函数中对被调函数做声明 格式1: 函数类型 函数名( 参数列表); 函数类型 函数名( 参数列表); 格式2: 省略参数的名称,只指定参数的类型 函数类型 函数名(数据类型1 ,数据类型2,…); #include<stdio.h> void main() { float a,b,c,s; scanf("%f %f %f",&a,&b,&c); s=sum(sum(a,b),c); printf("sum=%f",s); } float sum(float x,float y) { return(x+y); float sum(float x,float y); /*声明*/ float sum(float ,float ); /*声明*/ float sum( x , y ); /*声明*/ 错误案例法 float sum(float x ,float y ); 正确 float sum(float , float ); 正确 float sum( x , y ); 错误

函数 练习1 (1) 有以下程序  void f(int x,int y)  { int t;  if(x<y){ t=x; x=y; y=t; }  }  main()  { int a=4,b=3,c=5;  f(a,b);  f(a,c);  f(b,c);  printf("%d,%d,%d\n",a,b,c);  }  执行后输出的结果是  A) 3,4,5  B) 5,3,4  C) 5,4,3  D) 4,3,5  不带回返回值 1.实参和形参有不同的存储单元 2.实参给形参仅仅是"值传递" 3. 对形参的任何改变不会影响实参 因此:函数f中不改变abc的值 函数 语句

函数 练习2 函数嵌套 F(3,4) = 3 F(3,5)=6 F(3,6)=9 (2) 若有以下程序  int f(int x,int y)  { return (y-x)*x; }  main()  { int a=3,b=4,c=5,d;  d=f(f(3,4),f(3,5));  printf("%d\n",d);  }  执行后输出结果是 。  函数嵌套 F(3,4) = 3 F(3,5)=6 F(3,6)=9 函数实参 9

函数 练习3 (3) 若程序中定义了以下函数 double myadd(double a,double b) (3) 若程序中定义了以下函数 double myadd(double a,double b) { return (a+b);} 并将其放在调用语句之后,则在调用之前应该对该函数进行说明,以下选项中错误的说明是() A) double myadd(double a,b); B) double myadd(double,double); C) double myadd(double b,double a); D) double myadd(double x,double y);  不能省略形参类型 可以省略形参名 完整版 形参名可以和定义时不同

A0701 求N! (变量参数,有返回值) 及累加和 long factorial ( int n) { int i; //函数:阶乘 long factorial ( int n) { int i; long int k; return k; } void main() { long int k; int i,n; printf("input a int number<15: "); scanf("%d",&n); printf("%d!=%ld\n",n,k); } long factorial ( int n); //函数: 累加和 int sum ( int n) { long int a=0; for(i=1;i<=n;i++) a += i; return a; } k=factorial(n); for(i=1,k=1;i<=n;i++) k *= i; printf("1+...+%d=%ld\n",n,sum(n));

A0702 求数组平均值(数组参数,有/无返回值) inputarray(a,10); //函数:输入数组a[n] void inputarray(int a[], int n) { int i; } #define N 10 void main() { int i, a[10]; float aver=0; printf("average = %.2f\n",aver); } void inputarray(int a[], int n) float average(int a[], int n) n n printf("input %d num:\n",N ); for(i=0;i<N ;i++) scanf("%d",&a[i]); printf("\n"); 输 入 核 心 inputarray(a,10); //函数:数组a[n]的平均值 float average(int a[], int n) { int i; float aver=0; return aver; } for(i=0;i<N ;i++) aver+=a[i]; aver=aver/N; n aver=average(a,N); n

A0703 冒泡排序1 (数组参数, 无返回值) inputarray(a,10); outputarray(a,10); //函数:输入数组a[n] void inputarray(int a[], int n) { int i; } void main() { int i,j,a[10]; printf("input 10 numbers:\n"); for(j=0;j<9;j++) for(i=0;i<9-j;i++) if(a[i]>a[i+1]) {t=a[i]; a[i]=a[i+1];a[i+1]=t;} } n 输 入 核 心 输 出 for(i=0;i<10;i++) scanf("%d",&a[i]); printf("\n"); inputarray(a,10); //函数:输出数组a[n] void outputarray(int a[], int n) { int i; } n for(i=0;i<10;i++) printf("%d ",a[i]); outputarray(a,10);

A0703 冒泡排序2 (数组参数, 无返回值) sort(a,10); void sort(int a[], int n) //函数:输入数组a[n] void sort(int a[], int n) { int i,j; } void main() { int i,j,a[10]; printf("input 10 numbers:\n"); inputarray(a,10); outputarray(a,10); } n-1; n-1-j; 输 入 核 心 输 出 for(j=0;j<9;j++) for(i=0;i< 9-j ;i++) if(a[i]>a[i+1]) { t=a[i]; a[i]=a[i+1]; a[i+1]=t; } //函数:对数组a[n] 排序 sort(a,10);

A0704 大小写转换 (数组参数,无返回值) A0704 用函数重做A0608:键盘输入一串字符,将其中的大写字母转换成小写字母后输出 void main() { int i; char str[80]; printf("input string:\n"); gets(string); puts(string); } /*函数:将str字符数组中大写字母转为小写字母*/ void lowercase(char str[]) { int i; } for(i=0;str[i]!='\0';i++) if( str[i]>='A' && str[i]<='Z') str[i] += 32; 核 心 //函数:大写转小写 lowercase(str);

A0705 数组名 做函数参数 #include "stdio.h" f(int array[],int n) { array[n]++; 数组名作参数表示地址传递 实参数组—地址传递—形参数组 f和main在对同一个存储单元操作 f中对数组的改变影响main 中数组的值 #include "stdio.h" f(int array[],int n) { array[n]++; } void main() { int a[]={1,2,3,4,5 }; f(a,2); printf("%d\n",a[2]); a[0]a[1] a[2] a[3] a[4] array[0] array[1] array[2] array[3] array[4] 1 2 3 4 5 4 程序运行结果:4

数组元素 做函数参数 #include <stdio.h> void f(int n) { n++; } void main() 数组元素使用时与普通变量一样 实参——值传递——形参 a[2]和普通变量一样为值传递 (f和main对不同的存储单元操作, f中n改变不影响main函数中a[2]值 #include <stdio.h> void f(int n) { n++; } void main() { int a[]={1,2,3,4,5 }; f(a[2]); printf("%d\n",a[2]); 函数调用 函数返回 a[0]a[1] a[2] a[3] a[4] 1 2 3 4 5 程序运行结果:3 3 n 4

数组名 做函数参数 数组名作参数表示地址 传递,(即函数f中的改变 影响main函数中的值,f和main在对同一个存储单元操作) 练习: 下面程序运行结果 #include "stdio.h" f(int b[],int m,int n) { int i; for(i=m;i<n;i++) b[i]++; } void main() { int x,a[]={1,2,3,4,5,6,7,8,9}; f(a,3,7); for(i=0;i<9;i++) printf("%d\n",a[i]); 数组名作参数表示地址 传递,(即函数f中的改变 影响main函数中的值,f和main在对同一个存储单元操作) 1,2,3,5,6,7,8,8,9

变量的生存期 例: void main() { int a,b,c; scanf("%d,%d",&a,&b); c=max(a, b); printf("max=%d",c); } int max (int x, int y ) { int z; if (x>y) z=x; else z=y; return(z); 生存期 (时间) 不同的变量"出现"和"消失"的时间不同 10,5 函数返回 函数调用 实参 a b c 10 5 10 形参 x y 10 5 z 10

变量的作用域 例: void main() { void add(); //函数声明 a=5; int a; add(); //函数调用 作用域(空间): 不同位置的变量"有效"范围不同 生存期 (时间) 不同的变量"出现"和"消失"的时间不同 例: void main() { void add(); //函数声明 a=5; add(); //函数调用 printf("a=%d",a); } void add ( ) //函数定义 { a=a+5; 变量a的有效范围 int a; a有效范围 a 10 5 错!此处变量a未定义 运行结果:a=10

全局变量和局部变量 (1) 局部变量 作用域:某函数内定义的变量 ,只在该函数内有效。 生存期:与定义它的函数相同。 (2) 全局 变量 (1) 局部变量 作用域:某函数内定义的变量 ,只在该函数内有效。 生存期:与定义它的函数相同。 (2) 全局 变量 作用域:在函数之外说明的变量从定义点到本文结束都有效 生存期:生存到本文结束 void main() { int a,b,c; //局部变量 scanf("%d,%d",&a,&b); c=max(a, b); printf("max=%d",c); } int max (int x, int y ) { int z; //形参也是局部变量 if (x>y) z=x; else z=y; return(z); int a; //全局变量 void main() { void add(); a=5; add(); printf("a=%d",a); } void add ( ) { a=a+5;

全局变量和局部变量 void inputarray(int a[],int n) { int i; A0706 求数组的平均数 printf("input %d matrix:\n",n); for(i=0;i<n ;i++) scanf("%d",&a[i]); } A0706 求数组的平均数 全局变量能被所有函数使用 #define N 10 float aver; void main() { int a[N]; void input( int a[], int); //函数声明 void average(int a[],int); //函数声明 input(a,N); //函数调用 average(a,N); //函数调用 printf("%f",aver); } 局部变量在main中有效,可作为参数被其他函数使用 局部变量在average函数中有效 void average(int a[],int n) { int i,s=0; for(i=0;i< n ;i++) s+=a[i]; aver=(float)(s)/n; }

全局变量和局部变量 练习 #include <stdio.h> int a,b; /*a,b为全局变量*/ void f1( ) 全局变量和局部变量 练习 #include <stdio.h> void f1( ) { int t1,t2; t1 = a * 2; t2 = b * 3; b = 100; printf ("t1=%d,t2=%d\n", t1, t2); } main() { int a=2; b=4; f1( ); printf ("a=%d,b=%d", a, b); int a,b; /*a,b为全局变量*/ 全局变量ab的值可在任何一个函数中改变。 程序输出结果为: t1=4,t2=12 a=2,b=100 a=2; b=4; 错! main中的局部变量a、b不能被函数f使用

C语言内存分配 数据在程序运行期间,根据需要分配空间,用完之后即释放所占据的空间,故其的生命期相比整个程序的运行期要短。如: 内部变量 1 代码区: 存放程序的指令 1 代码 2 静态数据 3 动态数据(栈stack) 4 自由空间(堆heap) 2 静态数据区: 数据在程序运行过程中一直存在,程序结束后,静态数据所占据的空间被释放。如:全局变量 3 动态数据区: 数据在程序运行期间,根据需要分配空间,用完之后即释放所占据的空间,故其的生命期相比整个程序的运行期要短。如: 内部变量

变量的存储类别 变量都有不同的存储属性,对应不同的作用域和生存期。 自动类[auto] 静态类[static] 自动变量,只在该函数内有效 前面所学变量默认为:auto 静态类[static] 寄存器类[register] (了解) 外部类[extern]

static(静态变量) 静态存储 生存期:从定义开始到本文件结束(函数调用结束也不释放) 作用域:在定义的函数内有效,其它函数不能引用它们 初始化: 在编译时只初始化一次 定义时若无初始化则自动赋为"0" A0707-1例: main( ) { int i; for(i=0;i<3;i++) fa(); } void fa( ) { int a=0; a=a+1; printf("%d\n",a); A0707-2例: main ( ) { int i; for(i=0;i<3;i++) fs(); } void fs( ) { static int b=0; b=b+1; printf("%d\n",b); 输出结果 1 输出结果 1 2 3 static b在函数每次调用时其值都被保留。

static(静态变量) 静态变量 自动变量 全局变量 生命期 从定义开始到文件结束 从定义开始到本函数结束 作用域 限于本函数

外部变量extern (在同一个文件中) 例:给出长l、宽w、高h,计算体积 int vs(int l,int w) { int v; v=l*w*h; /*使用外部变量h的值*/ return v; } main() { int l=5,w=2; /*内部变量的定义*/ printf("v=%d",vs(l,w)); int h=5; /*定义外部变量h*/ extern int h; /*说明外部变量h*/

外部变量extern (在多个文件中) //源文件一:f1.c 求数组和 #define N 5 float sum; void main() { int i; int a[N]={1,2,3,4,5}; for(i=0;i<N;i++) sum +=a[i]; printf("sum=%f",sum); } //源文件二:f2.c 求数组平均值 extern float sum; void average() { float aver; aver=sum/5; printf("aver=%f",aver); } 运行结果:sum=15.000000

外部函数extern /*源文件一:f1.c*/ #define N 5 float sum; void main() { int i; int a[N]={1,2,3,4,5}; for(i=0;i<N;i++) sum +=a[i]; printf("sum=%f",sum); } /*源文件二:f2.c*/ extern float sum; void average() { float aver; aver=sum/5; printf("aver=%f",aver); } extern //外部函数声明 extern void average(); average(); //外部函数调用 运行结果:sum=15.000000 aver=3.000000

外部函数 A0708 外部函数extern:可以被其他文件调用的函数 为什么没有外部说明? //文件sort.c : 主函数完成冒泡程序 #include<stdio.h> void main() { void input(int a[],int n); void output(int a[],int n); int a[10],i,j,t; input(a,10); //外部函数调用 for(j=0;j<9;j++) for(i=0;i<9-j;i++) if(a[i]>a[i+1]) {t=a[i]; a[i]=a[i+1];a[i+1]=t;} output(a,10); //外部函数调用 } // 文件inout.c :数组输入输出函数文件 #include<stdio.h> //外部函数定义 extern void input(int a[],int n) { int i; printf("input %d number:\n",n); for(i=0;i<n;i++) scanf("%d",&a[i]); } extern void output(int a[],int n) printf("%5d",a[i]); //外部函数声明 extern 为什么没有外部说明? 本页结束后,思考问题 " printf和scanf" 也是外部函数,但是没有显式的外部说明,如何使用?

定义头文件 (1)保存为 inout.h :头文件 (2)保存路径: VC/include 文件夹下 或 当前C程序文件夹下 // 文件inout.c :数组输入输出函数文件#include<stdio.h> extern void input(int a[],int n) //数组输入 { ……. } extern void output(int a[],int n) //数组输出 { ……. } (1)保存为 inout.h :头文件 (2)保存路径: VC/include 文件夹下 或 当前C程序文件夹下 例:程序二:冒泡排序 #include " inout.h" void main() { int a[10],i,j,t; input(a,10); //外部函数调用 for(j=0;j<9;j++) for(i=0;i<9-j;i++) if(a[i]>a[i+1]) { t=a[i]; a[i]=a[i+1]; a[i+1]=t; } output(a,10); //外部函数调用 } 例:程序一:求数组累加和 void main() { int a[10], i,sum=0; input(a,10); //外部函数调用 for(i=0;i<10;i++) sum += a[i]; output(a,10); //外部函数调用 printf("sum=%d",sum); } #include< inout.h>

函 数 嵌 套 例:求 N! A0709例:求1!+2!+3!+…+N! void main() { long factorial ( int n); long int k; int i,n; printf("int num: "); scanf("%d",&n); printf("%ld\n",k); } long fsum(int num) { int n; long k, sum=0; for(n=1;n<=num;n++) { k=factorial(n); sum +=k; } return sum; #include<stdio.h> void main() { long fsum(int n); long sum; int n; scanf("%d",n) sum=fsum(n); printf("%ld",sum); } long factorial ( int n); //函数:阶乘 long factorial ( int n) { int i; long int k=1; return k; } k=factorial(n); for(i=1;i<=n;i++) k *= i;

函数嵌套 函数的嵌套调用是指,在执行被调用函数时,被调用函数又调用了其它函数。 函数调用可以嵌套,但定义只能是平行关系。

用递归算法计算n! A0710采用递归的方法计算n! 的递归定义形式的: 编程: 1 n=0; n!= n* (n-1)! n>0 if (初始条件) 表达式; else 递推表达式;

用递归算法计算n! #include <stdio.h> long fac(unsigned n) { long f ; if (n==0) f=1; /*递归结束条件*/ else f=n*fac(n-1); return f; } 1 n=0; n!= n* (n-1)! n>0 main( ) { long y; int n; long fac(unsigned n); scanf("%d", &n); y = fac(n); printf("%d=%ld\n", n, y); }

用递归算法计算n!----输入3 fac(3) fac(3) = 3 *fac(2) = 3 *2=6 fac(2) fac(2) if (n==0) f=1; /*递归结束条件*/ else f=n*fac(n-1); fac(3) = 3 *fac(2) fac(3) = 3 *2=6 fac(2) = 2 *fac(1) fac(2) = 2*1=2 递推 回归 fac(1) = 1 *fac(0) fac(1) = 1*1=1 fac(0)=1

函数的递归调用 所谓递归调用,就是指定义的函数自己直接或间接调用自己。 直接递归调用 间接递归调用 函数直接在自身的函数 体中调用函数本身。 f(a,b,c){ . f(x,y,z); } 间接递归调用 函数之间在自己的函数体中 相互交叉调用。 g(x,y); g(t,b){

小结——函 数 函数——功能相对独立的一段程序 优点:1. 优化程序结构,增强代码复用 2. 使主函数简单明了,含义清晰,增强程序的可读性 主控模块 模块1_1 模块1_n 模块2_1 模块2_n 模块n_1 模块n_n 模块1 模块2 模块n

小结——函数 函数声明 函数调用 函数定义 函数参数 函数返回值 不能省略参数类型 #include<stdio.h> void main() { int max ( int x, int y ); int a,b,c; scanf("%d,%d",&a,&b); c=max(a,b); printf("max=%d",c); } /*求最大值函数*/ int max ( int x, int y ) { int z; if (x>y) z=x; else z=y; return(z); 函数调用 调用时参数必须匹配 可作为表达式一部分或者单独语句调用 函数定义 参数 返回值 函数参数 形参和实参 数组名作为参数 值传递、地址传递 函数返回值 只能返回一个值 遇到 return回到主调函数

函数 习题 B0701 :键盘输入10个数,找最大数、最小数。要求写出数组输入函数,找最大最小数函数。 C0701:用菜单结构编程完成以下任务: 键盘输入某班30人C语言成绩,要求 1. 求平均成绩 2. 统计各分数段人数,并输出 3. 输出最高分及学号 4. 输出最低分及学号 5. 打印成绩优秀(90~100)的学生学号及成绩 6. 打印成绩不及格(0~59)的学生学号及成绩

函数 作业 #include<stdio.h> #define N 30 void input(int a[],int n) void main() { void f1(int a[],int); void f2(int a[],int); void f3(int a[],int); void f4(int a[],int); void f5(int a[],int); void f6(int a[],int); void input(int a[],int); int a[N+1]; input(a,N); f1(a,N); ..... } void input(int a[],int n) { int i; for(i=1;i<=n;i++) scanf("%d",&a[i]); } void f1(int a[],int n) float aver=0; aver+=a[i]; aver= aver/n; printf("aver=%8.2f",aver); 键盘输入某班30人C语言成绩,要求 1. 求平均成绩 2. 统计各分数段人数,并输出 3. 输出最高分及学号 4. 输出最低分及学号 5. 打印优秀(90~100)的学生学号及成绩 6. 打印不及格(0~59)的学生学号及成绩 数组输入

游戏扩展 C0702 游戏集