欢迎来到淘文阁 - 分享文档赚钱的网站! | 帮助中心 好文档才是您的得力助手!
淘文阁 - 分享文档赚钱的网站
全部分类
  • 研究报告>
  • 管理文献>
  • 标准材料>
  • 技术资料>
  • 教育专区>
  • 应用文书>
  • 生活休闲>
  • 考试试题>
  • pptx模板>
  • 工商注册>
  • 期刊短文>
  • 图片设计>
  • ImageVerifierCode 换一换

    C语言 第08章 函数.ppt

    • 资源ID:69347534       资源大小:1.59MB        全文页数:85页
    • 资源格式: PPT        下载积分:16金币
    快捷下载 游客一键下载
    会员登录下载
    微信登录下载
    三方登录下载: 微信开放平台登录   QQ登录  
    二维码
    微信扫一扫登录
    下载资源需要16金币
    邮箱/手机:
    温馨提示:
    快捷下载时,用户名和密码都是您填写的邮箱或者手机号,方便查询和重复下载(系统自动生成)。
    如填写123,账号就是123,密码也是123。
    支付方式: 支付宝    微信支付   
    验证码:   换一换

     
    账号:
    密码:
    验证码:   换一换
      忘记密码?
        
    友情提示
    2、PDF文件下载后,可能会被浏览器默认打开,此种情况可以点击浏览器菜单,保存网页到桌面,就可以正常下载了。
    3、本站不支持迅雷下载,请使用电脑自带的IE浏览器,或者360浏览器、谷歌浏览器下载即可。
    4、本站资源下载后的文档和图纸-无水印,预览文档经过压缩,下载后原文更清晰。
    5、试题试卷类文档,如果标题没有明确说明有答案则都视为没有答案,请知晓。

    C语言 第08章 函数.ppt

    第八章第八章 函数函数 8.1 8.1 概述概述 8.2 8.2 函数的定义函数的定义 8.3 8.3 函数参数和函数值函数参数和函数值 8.4 8.4 函数的调用函数的调用 8.5 8.5 函数的嵌套调用函数的嵌套调用 8.6 8.6 函数的递归调用函数的递归调用 8.7 8.7 数组作为函数参数数组作为函数参数 8.8 8.8 局部变量和全局变量局部变量和全局变量 8.9 8.9 变量的存储类别变量的存储类别第八章第八章 目录目录8.1 8.1 概述概述8.1 8.1 概述概述mainabcdefghhieg8.1 8.1 概述概述#include“stdio.h”void printstar()printf(“*n”);void print_message()printf(“How do you do!n”);void main()printstar();print_message();printstar();例例.简单的函数调用。简单的函数调用。运行结果运行结果*How do you do!*8.1 8.1 概述概述(1)一个一个C 程序由一个或多个源程序文件组成。程序由一个或多个源程序文件组成。说明说明说明说明(2)一个源程序文件由一个或多个函数组成。一个源程序文件由一个或多个函数组成。(3)C 程序的执行从程序的执行从 main 函数开始,调用其他函函数开始,调用其他函 数后返回到数后返回到main 函数,在函数,在main函数中结束整函数中结束整 个程序的运行。个程序的运行。(4)所有函数都是平行的,即在定义函数时是互相所有函数都是平行的,即在定义函数时是互相 独立的,函数不能嵌套定义。函数间可以互相独立的,函数不能嵌套定义。函数间可以互相 调用,但不能调用调用,但不能调用main函数。函数。8.1 8.1 概述概述(5)从函数使用的角度来看,从函数使用的角度来看,C C语言的函数可以分语言的函数可以分 为两类:标准库函数和用户自定义函数。为两类:标准库函数和用户自定义函数。标准库函数与头文件标准库函数与头文件执行效率高,用户需要时,可在程序中直接进执行效率高,用户需要时,可在程序中直接进行调用。行调用。C C语言库函数所用到的常量、外部变量、函数类语言库函数所用到的常量、外部变量、函数类型和参数说明,都在相应的头文件型和参数说明,都在相应的头文件(.h)(.h)中声明,中声明,这些文件通常存放在系统目录这些文件通常存放在系统目录includeinclude。用户自定义函数用户自定义函数 无参函数无参函数 有参函数有参函数8.2 8.2 函数的定义函数的定义8.2 8.2 函数的定义函数的定义有参函数定义有参函数定义有参函数定义有参函数定义形式一形式一形式一形式一函数值类型函数值类型 函数名函数名(形式参数类型及参数说明形式参数类型及参数说明)声明部分声明部分 语句语句 函数返回值的类型,函数返回值的类型,可以是简单类型、可以是简单类型、voidvoid类型或构造类类型或构造类型等。型等。函数名是函数的标识函数名是函数的标识符,遵循符,遵循C C语言标识语言标识符的命名规则,区分符的命名规则,区分大小写。大小写。如如:int max(int a,int b)形式参数简称形参。形式参数简称形参。注意:无论函数是否注意:无论函数是否有形式参数,圆括号有形式参数,圆括号不可省。不可省。8.2 8.2 函数的定义函数的定义有参函数定义有参函数定义有参函数定义有参函数定义形式二形式二形式二形式二函数值类型函数值类型 函数名函数名(形式参数列表形式参数列表)形式参数说明形式参数说明 声明部分声明部分 语句语句 如如:int max(a,b)int a,b;8.2 8.2 函数的定义函数的定义例例.定义符号函数定义符号函数sign。int sign(int x)int y;y=x0?1:(x=0?0:-1);return y;/*函数返回值类型未说明,默认为函数返回值类型未说明,默认为int,建议给出函数类型说明建议给出函数类型说明*/*形式参数说明形式参数说明*/*函数局部变量函数局部变量*/*返回函数值返回函数值*/8.3 8.3 函数参数和函数值函数参数和函数值8.3 8.3 函数参数和函数值函数参数和函数值11.形式参数和实际参数形式参数和实际参数形式参数和实际参数形式参数和实际参数实参实参调用函数使用的参数调用函数使用的参数形参形参定义函数使用的参数定义函数使用的参数单向值单向值传递传递复制复制单向值传递方式是指在函数调用时,将实参单向值传递方式是指在函数调用时,将实参之值传递给对应的形式参数,使形参具有与之值传递给对应的形式参数,使形参具有与实参相同的值。实参相同的值。8.3 8.3 函数参数和函数值函数参数和函数值例例.调用函数时的数据传递。调用函数时的数据传递。#include“stdio.h”int max(int x,int y)/*定义有参函数定义有参函数*/int z;z=xy?x:y;return(z);运行情况运行情况7,8 Max is 8abxyvoid main()int a,b,c;scanf(“%d,%d”,&a,&b);c=max(a,b);printf(“Max is%dn”,c);8.3 8.3 函数参数和函数值函数参数和函数值有关形参与实参的几点说明:有关形参与实参的几点说明:有关形参与实参的几点说明:有关形参与实参的几点说明:实参可以是常量、变量或表达式。不论是何种实参可以是常量、变量或表达式。不论是何种类型,函数调用时,必须有确定的值,以便将类型,函数调用时,必须有确定的值,以便将值传递给形参。值传递给形参。在函数定义中指定的形参,未调用时,它们在函数定义中指定的形参,未调用时,它们不占用存储单元。只有调用该函数时,形参不占用存储单元。只有调用该函数时,形参才被分配空间,函数调用结束后,形参所占才被分配空间,函数调用结束后,形参所占的存储单元被释放。的存储单元被释放。8.3 8.3 函数参数和函数值函数参数和函数值实参与形参的数据传递为单向传递,只可由实实参与形参的数据传递为单向传递,只可由实参向形参传递,不能由形参传回实参。实参与参向形参传递,不能由形参传回实参。实参与形参处在不同的函数中,作用的区域不同,即形参处在不同的函数中,作用的区域不同,即使实参与形参同名,也是不同的变量。使实参与形参同名,也是不同的变量。定义函数时,必须指定形参的类型。调用函定义函数时,必须指定形参的类型。调用函数时,实参类型、个数及排列次序应与形参数时,实参类型、个数及排列次序应与形参一一对应。一一对应。8.3 8.3 函数参数和函数值函数参数和函数值22.函数的返回值函数的返回值函数的返回值函数的返回值功能功能 用于结束函数的执行并返回到调用者。用于结束函数的执行并返回到调用者。用来向主调函数传递一个返回值。用来向主调函数传递一个返回值。return语句的表示形式语句的表示形式 return 表达式表达式;or return(表达式表达式);8.3 8.3 函数参数和函数值函数参数和函数值int sign(int x)int y;return y=x0?1:(x=0?0:-1);if(x0)return(1);else if(xy?x:y;return(z);void main()float a,b,c;scanf(“%f,%f”,&a,&b);c=max(a,b);printf(“Max is%fn”,c);运行情况运行情况1.5,2.5 Max is 2.0000008.3 8.3 函数参数和函数值函数参数和函数值注意注意:为了明确表示为了明确表示“不带返回值不带返回值”,可以用,可以用“void”定义定义“无类型无类型”。此时函数体内不。此时函数体内不得出现得出现return语句。语句。如:如:void main()8.3 8.3 函数参数和函数值函数参数和函数值例例.写出以下程序的运行结果。写出以下程序的运行结果。max()/*函数类型缺省,为函数类型缺省,为int型,型,return语句缺省语句缺省*/运行结果运行结果-256,-256 /*/*返回值不确定,返回值不确定,TC2TC2返回值为返回值为0*/0*/min()/*函数类型缺省,函数类型缺省,return语句缺省语句缺省*/main()printf(%d,%dn,max(),min()););8.4 8.4 函数的调用函数的调用8.4 8.4 函数的调用函数的调用11.函数调用形式函数调用形式函数调用形式函数调用形式 函数名(实参表列)函数名(实参表列)一个函数一旦被定义,就可在程序的一个函数一旦被定义,就可在程序的 其它函数中使用它,这个过程称为函其它函数中使用它,这个过程称为函 数调用。数调用。说明:说明:说明:说明:实际参数之间以实际参数之间以“,”分隔。分隔。实参与形参应保持个数、次序及类型的一致,实参与形参应保持个数、次序及类型的一致,以确保实参与形参之间数据的正确传递。以确保实参与形参之间数据的正确传递。实参一般为表达式,可以是常量、变量(调实参一般为表达式,可以是常量、变量(调用时必须有确定的值或确定的地址)。用时必须有确定的值或确定的地址)。形参必须为变量。形参必须为变量。8.4 8.4 函数的调用函数的调用函数调用的三种形式函数调用的三种形式函数调用的三种形式函数调用的三种形式函数语句函数语句调用调用函数表达式函数表达式调用调用函数参数函数参数调用调用在函数调用后加在函数调用后加“;”;”,构成一个语句。,构成一个语句。目的是执行一个动作或完成特定的目的是执行一个动作或完成特定的功能。功能。函数调用作为表达式的一部分。函数调用作为表达式的一部分。被调用函数执行的结果为主调函数提被调用函数执行的结果为主调函数提供一个值供一个值。主调函数通过表达式接收值。主调函数通过表达式接收值。被调函数作为某个函数的一个参数。被调函数作为某个函数的一个参数。8.4 8.4 函数的调用函数的调用例例.函数语句调用与函数表达式调用。函数语句调用与函数表达式调用。#include“stdio.h”void main()printf(nk1=%d,printf(nk2);运行结果运行结果k2k1=38.4 8.4 函数的调用函数的调用例例.函数参数调用形式调用函数函数参数调用形式调用函数max2 。#include“stdio.h”int max2(int x,int y)/*求两个数中较大的求两个数中较大的*/int z;return(z=xy?x:y);void main()int a,b,c;scanf(“%d,%d,%d”,&a,&b,&c);printf(“Max is%dn”,max2(max2(a,b),c);/*内层函数内层函数max2的值作为外层函数的值作为外层函数max2的实参,整个的实参,整个函数函数max2的值又作函数的值又作函数printf的的实参的的实参*/8.4 8.4 函数的调用函数的调用22.函数声明函数声明函数声明函数声明调用用户自定义函数时,一般在主调函调用用户自定义函数时,一般在主调函数中对被调用函数返回值的类型、函数数中对被调用函数返回值的类型、函数名称、函数形参的类型进行说明,这种名称、函数形参的类型进行说明,这种说明称为函数声明。说明称为函数声明。#include“stdio.h”void main()float add(float x,float y);/*对对被被调调用用函函数数的的声声明明*/float a,b,c;scanf(“%f,%f”,&a,&b);c=add(a,b);printf(“sum is%fn”,c);float add(float x,float y)/*函数首部函数首部*/return(x+y);/*函数体函数体*/8.4 8.4 函数的调用函数的调用函数声明的一般形式:函数声明的一般形式:函数声明的一般形式:函数声明的一般形式:类型类型 函数名函数名(类型类型1 1 形参形参1,1,类型类型2 2 形参形参2,);2,);注意注意:函数声明是以语句形式出现的,因此其后有语句函数声明是以语句形式出现的,因此其后有语句结束标记结束标记“;”。类型类型 函数名函数名(类型类型1,1,类型类型2,);2,);8.4 8.4 函数的调用函数的调用以下两种情况,可以省略对被调用函数的声明:以下两种情况,可以省略对被调用函数的声明:以下两种情况,可以省略对被调用函数的声明:以下两种情况,可以省略对被调用函数的声明:若函数定义放在主调函数之前,若函数定义放在主调函数之前,遵循先定义后调用原则遵循先定义后调用原则,函数声函数声明可以省略。明可以省略。8.4 8.4 函数的调用函数的调用#include“stdio.h”float add(float x,float y)/*函数首部函数首部*/return(x+y);/*函数体函数体*/void main()float a,b,c;scanf(“%f,%f”,&a,&b);c=add(a,b);printf(“sum is%fn”,c);8.4 8.4 函数的调用函数的调用如果已在所有函数定义之前,在函数外如果已在所有函数定义之前,在函数外部已做了函数声明,则在各个主调函数部已做了函数声明,则在各个主调函数中不必对所调用的函数再作声明。中不必对所调用的函数再作声明。8.4 8.4 函数的调用函数的调用例如:例如:char letter(char,char);float f(float,float);void main()char letter(char c1,char c2)float f(float x,float y)8.4 8.4 函数的调用函数的调用例例.判断两个数的大小。判断两个数的大小。#include“stdio.h”void main()int f(int,int);int i=2,p;p=f(i,i+);printf(“%dn”,p);f(int a,int b)int c;if(ab)c=1;else if(a=b)c=0;else c=-1;return(c);运行结果:运行结果:18.4 8.4 函数的调用函数的调用例例.编程求两个整数的阶乘之和。编程求两个整数的阶乘之和。void main()int n1,n2;long sum;long fac(int);/*fac函数声明函数声明*/scanf(%d,%d,&n1,&n2);sum=fac(n1)+fac(n2);printf(%d!+%d!=%ldn,n1,n2,sum);/*定义函数定义函数fac,其功其功能是求能是求n!*/long fac(int n)int i;long r=1;for(i=1;i=n;i+)r=r*i;return r;8.5 8.5 函数的嵌套调用函数的嵌套调用8.5 8.5 函数的嵌套调用函数的嵌套调用定义定义定义定义所谓函数的嵌套调用是指一个函数调用另一函数所谓函数的嵌套调用是指一个函数调用另一函数的过程中又出现对其它的函数调用。的过程中又出现对其它的函数调用。这种嵌套调用的层次原则上不限制。这种嵌套调用的层次原则上不限制。main函数函数1调用函数调用函数12函数函数1调用函数调用函数234函数函数25678结束结束98.5 8.5 函数的嵌套调用函数的嵌套调用例例.用弦截法求方程的根用弦截法求方程的根方法:方法:xy8.5 8.5 函数的嵌套调用函数的嵌套调用N-S流程图流程图输入输入x1、x2,求求f(x1)、f(x2)直到直到f(x1)和和f(x2)异异号号真真假假x1=xy1=yx2=xy2=y直到直到|y|1e-4|y|0)x1=x;y1=y;else x2=x;while(fab(y)=1e-4);return(x);8.5 8.5 函数的嵌套调用函数的嵌套调用/*续上续上*/void main()/*主函数主函数*/float x1,x2,f1,f2,x;do printf(input x1,x2:n);scanf(%f,%f,&x1,&x2);f1=f(x1);f2=f(x2);while(f1*f2=0);x=root(x1,x2);printf(x=%.4fn,x);运行情况运行情况input x1,x2:2,6 x=5.00008.5 8.5 函数的嵌套调用函数的嵌套调用main函数函数调用调用root函数函数root函数函数调用调用xpoint函数函数xpoint函数函数输出根输出根x结束结束调用调用f函数函数f函数函数8.6 8.6 函数的递归调用函数的递归调用8.6 8.6 函数的递归调用函数的递归调用定义定义定义定义在调用一个函数的过程中又出现直接或间接地调在调用一个函数的过程中又出现直接或间接地调用该函数本身。用该函数本身。直接调用直接调用间接调用间接调用f函数函数调用调用f函数函数f1函数函数调用调用f2函数函数f2函数函数调用调用f1函数函数8.6 8.6 函数的递归调用函数的递归调用无论是直接还是间接递归,两者都是无终止的调无论是直接还是间接递归,两者都是无终止的调用自身。要避免这种情况的发生,使用递归解决用自身。要避免这种情况的发生,使用递归解决的问题应满足两个基本条件:的问题应满足两个基本条件:问题的转化。有些问题不能直接求解或难以问题的转化。有些问题不能直接求解或难以求解,但可以转化为一个新问题,这个新问求解,但可以转化为一个新问题,这个新问题相对较原问题简单或更接近解决方法。这题相对较原问题简单或更接近解决方法。这个新问题的解决与原问题一样,可以转化为个新问题的解决与原问题一样,可以转化为下一个新问题,下一个新问题,。转化的终止条件。原问题到新问题的转化是转化的终止条件。原问题到新问题的转化是有条件的、次数是有限的,不能无限次数地有条件的、次数是有限的,不能无限次数地转化下去。这个终止条件也称为边界条件。转化下去。这个终止条件也称为边界条件。8.6 8.6 函数的递归调用函数的递归调用分析:分析:例例.有有5个人,问第个人,问第5个人多少岁?他说比第个人多少岁?他说比第4个人大个人大 2岁,第岁,第4个人说比第个人说比第3个人大个人大2岁,第岁,第3个人说比个人说比 第第2个人大个人大2岁,第岁,第2个人说比第个人说比第1个人大个人大2岁,第岁,第 1个人说他个人说他10岁。请问第岁。请问第5个多大。个多大。8.6 8.6 函数的递归调用函数的递归调用age(5)=age(4)+2age(4)=age(3)+2age(3)=age(2)+2age(2)=age(1)+2age(1)=10age(2)=12age(3)=14age(4)=16age(5)=18回推回推递推递推8.6 8.6 函数的递归调用函数的递归调用参考程序:参考程序:int age(int n)/*求年龄的递归函数求年龄的递归函数*/int c;if(n=1)c=10;else c=age(n-1)+2;return(c);#include“stdio.h”void main()/*主函数主函数*/printf(%dn,age(5);age(5)c=age(4)+2c=age(1)+2c=10输出输出age(5)age函数函数n=5age函数函数n=2age函数函数n=1age(5)=18age(1)=10age(2)=12main8.6 8.6 函数的递归调用函数的递归调用分析:分析:(1)用用递推法递推法,123n。(2)用用递归法:递归法:例例.用递归法求用递归法求n!。8.6 8.6 函数的递归调用函数的递归调用参考程序:参考程序:float fac(int n)float k;if(n=1)k=1;else k=n*fac(n-1);return(k);void main()int n;float y;scanf(%d,&n);y=fac(n);printf(%d!=%.0fn,n,y);fac(5)k=fac(4)*5k=fac(1)*2k=1输出输出fac(5)fac函数函数n=5fac函数函数n=2fac函数函数n=1fac(5)=120fac(1)=1fac(2)=2main8.6 8.6 函数的递归调用函数的递归调用例例.汉诺(汉诺(Hanoi)塔问题。塔问题。这是一个古典的数学问题,只能用递归方法解决。这是一个古典的数学问题,只能用递归方法解决。问题是这样的:有三个底座,问题是这样的:有三个底座,A A座上放着座上放着6464个盘子,个盘子,小的在上,大的在下,目标是把小的在上,大的在下,目标是把6464个盘子从个盘子从A A座移座移到到C C座上,座上,B B座作为中间过渡。每次只能移动一个盘座作为中间过渡。每次只能移动一个盘子,并且大的盘子不能放在小的上面。子,并且大的盘子不能放在小的上面。ABC8.6 8.6 函数的递归调用函数的递归调用分析:分析:把把3个盘子从个盘子从A座移到座移到C座的过程:座的过程:(1)将将A上的上的2个盘子移到个盘子移到B(借助借助C)。(2)将将A上的上的1个盘子移到个盘子移到C。(3)将将B上的上的2个盘子移到个盘子移到C(借助借助A)。ACABCBACBBABCAC8.6 8.6 函数的递归调用函数的递归调用分析:分析:对于把对于把n(n1)个盘子从个盘子从A座移到座移到C座的问题可以座的问题可以分解成如下步骤:分解成如下步骤:(1)将将n-1个盘子从个盘子从A经过经过C移动到移动到B。(2)将第将第n个个(最底下的最底下的)盘子移动到盘子移动到C。(3)再将再将n-1个盘子从个盘子从B经过经过A移动到移动到C。这样就把移动这样就把移动n n个个盘子盘子的问题转化为移动的问题转化为移动n-1n-1个个盘子盘子的问题,即移动的问题,即移动n n个个盘子盘子的问题可用移动的问题可用移动n-1n-1个个盘子盘子的问题递归描述,以此类推,可转化的问题递归描述,以此类推,可转化为移动一个为移动一个盘子盘子的问题。显然,一个盘子就可以的问题。显然,一个盘子就可以直接移动。直接移动。8.6 8.6 函数的递归调用函数的递归调用#include“stdio.h”void main()int n;void hanoi(int,char,char,char);void move(char,char);printf(Input n:);scanf(%d,&n);hanoi(n,A,B,C);/*n个个盘子从盘子从A座经过座经过B座移动座移动C座座*/参考程序:参考程序:int i=0;/*i/*i为移动的次数,为全局变量为移动的次数,为全局变量*/void move(char from,char to)i+;printf(%d=%c-%cn,i,from,to);8.6 8.6 函数的递归调用函数的递归调用void hanoi(int n,char src,char t,char dest)/*将将n个盘子从个盘子从src借助借助t移到移到dest*/if(n=0)return;if(n=1)move(src,dest);else hanoi(n-1,src,dest,t);/*将将n-1个盘子从个盘子从src经经t移到移到dest*/move(src,dest);/*将最底下的盘子从将最底下的盘子从src移到移到dest*/hanoi(n-1,t,src,dest);/*将将n-1个盘子从个盘子从t经经src移到移到dest*/8.7 8.7 数组作为函数参数数组作为函数参数8.7 8.7 数组作为函数参数数组作为函数参数11.数组元素作函数实参数组元素作函数实参数组元素作函数实参数组元素作函数实参单向值传递单向值传递使用时与普通变量一样。使用时与普通变量一样。在函数调用时将值传递给在函数调用时将值传递给实参实参形参形参8.7 8.7 数组作为函数参数数组作为函数参数例例.数组中有数组中有1010个整型元素,求数组中所有素数之和。个整型元素,求数组中所有素数之和。#include math.h#include stdio.hvoid main()int a10,i,s=0;int prime(int);printf(请输入请输入1010个整数个整数:n);for(i=0;i10;i+)scanf(%d,&ai);if(prime(ai)s+=ai;printf(sum=%dn,s);int prime(int x)int f=1,k;if(x=1)f=0;els for(k=2;k=sqrt(x);k+)if(x%k=0)f=0;break;return(f);8.7 8.7 数组作为函数参数数组作为函数参数22.数组名作函数参数数组名作函数参数数组名作函数参数数组名作函数参数地址传递方式地址传递方式,实参与形参共地址,实参与形参共地址,相当于对同一对象的两个不同名字。相当于对同一对象的两个不同名字。实参与形参都应用数组名实参与形参都应用数组名(或指针或指针变量变量)。在函数调用时将在函数调用时将其其地址值地址值传递给传递给实参实参形参形参8.7 8.7 数组作为函数参数数组作为函数参数例例.分析下面程序的运行结果。分析下面程序的运行结果。#include“stdio.h”int f(int b,int m,int n)int i,s=0;for(i=m-1;in;i+)s=s+bi;return s;void main()int x,a=1,2,3,4,5,6,7,8,9;x=f(a,3,7);printf(%dn,x);运行结果运行结果253a24a35a46a57a68a79a82a11a0起始起始地址地址1000b2 b3 b4 b5 b6 b7 b8b1b08.7 8.7 数组作为函数参数数组作为函数参数例例.用选择法对数组中的用选择法对数组中的1010个整数从小到大排序。个整数从小到大排序。#include“stdio.h”void sort(int b,int n)int i,j,k,t;for(i=0;in-1;i+)min=i;for(j=i+1;jn;j+)if(bjbmin)min=j;t=bi;bi=bmin;bmin=t;void main()int a10,i;printf(请输入请输入10个整数个整数:n);for(i=0;i10;i+)scanf(%d,&ai);sort(a,10);printf(排序后为排序后为:n);for(i=0;i10;i+)printf(%6d,ai);printf(n);8.7 8.7 数组作为函数参数数组作为函数参数说明说明说明说明实参数组与形参数组类型应一致。实参数组与形参数组类型应一致。C C编译对形参数组的大小不做检查,所以形参编译对形参数组的大小不做检查,所以形参数组可以不指定大小。数组可以不指定大小。数组名作函数参数时,是把实参数组的首地数组名作函数参数时,是把实参数组的首地址传递给形参数组,这样两个数组共用一段址传递给形参数组,这样两个数组共用一段内存单元。内存单元。在主调函数和被调用函数中要分别定义数组。在主调函数和被调用函数中要分别定义数组。8.7 8.7 数组作为函数参数数组作为函数参数33.多维数组名作函数参数多维数组名作函数参数多维数组名作函数参数多维数组名作函数参数多维数组名可以作为实参和形参,在多维数组名可以作为实参和形参,在被调用函数中对形参数组定义时可以被调用函数中对形参数组定义时可以省略第一维的大小。省略第一维的大小。多维数组元素可以作为实参,使用多维数组元素可以作为实参,使用时与普通变量一样。时与普通变量一样。在函数调用时将在函数调用时将其地址值传递给其地址值传递给实参实参形参形参8.7 8.7 数组作为函数参数数组作为函数参数例例.求求34矩阵中的最大值矩阵中的最大值。#include“stdio.h”int max(int array4)int i,j,m=array00;for(i=0;i3;i+)for(j=0;j4;j+)if(mb?a:b;int z;z=a*a;return z;8.9 8.9 变量的存储类别变量的存储类别随函数的调用而存在,随函数的返回而消失,随函数的调用而存在,随函数的返回而消失,它们在一次调用结束到下一次调用开始之间它们在一次调用结束到下一次调用开始之间不再占有存储空间。不再占有存储空间。作用域局限于所定义的函数,其生存期就是作用域局限于所定义的函数,其生存期就是函数的生存期。函数的生存期。如果不初始化,其值是不确定的;如果初始化,如果不初始化,其值是不确定的;如果初始化,则赋值操作是在调用时进行的则赋值操作是在调用时进行的(不是编译时不是编译时),且每次调用都要重新赋一次初值。且每次调用都要重新赋一次初值。2.2.静态静态(static)局部局部变量变量8.9 8.9 变量的存储类别变量的存储类别定义格式:定义格式:static 数据类型数据类型 变量表;变量表;函数内部定义的静态变量。函数内部定义的静态变量。作用域与自动型变量相同作用域与自动型变量相同。当所在的函数执行结束后,静态变量当所在的函数执行结束后,静态变量所占内存单元并不释放,其值仍然保所占内存单元并不释放,其值仍然保留。留。注意注意:把局部变量改变为静态局部变量后,改变了把局部变量改变为静态局部变量后,改变了它的生存期。它的生存期。8.9 8.9 变量的存储类别变量的存储类别例例.考察静态局部变量的值。考察静态局部变量的值。#include“stdio.h”int f(int a)int b=0;static int c=3;b+;c+;printf(%d%d%d,a,b,c);return(a+b+c);void main()int a=2,k;for(k=0;k3;k+)printf(%5dn,f(a);运行结果运行结果2 1 4 72 1 5 82 1 6 9结论:结论:局部静态变量只赋初值局部静态变量只赋初值一次,以后每次调用函一次,以后每次调用函数时不再重新赋初值,数时不再重新赋初值,而是保留上次函数调用而是保留上次函数调用结束时的值。结束时的值。8.9 8.9 变量的存储类别变量的存储类别例例.考察静态局部变量的值。考察静态局部变量的值。#include“stdio.h”int fun(int n)static int f=1;f=f*n;return(f);void main()int k;for(k=1;ky?x:y;return(z);void main()extern int A,B;/*声明外部变量声明外部变量*/printf(“%dn”,max(A,B);int A=13,B=-8;/*定义外部变量定义外部变量*/8.9 8.9 变量的存储类别变量的存储类别(2)(2)在多文件的程序中声明外部变量在多文件的程序中声明外部变量在多文件的程序中声明外部变量在多文件的程序中声明外部变量若变量的定义与引用处于不同的源文件中,则若变量的定义与引用处于不同的源文件中,则需要在引用该变量的源文件中对它进行声明,需要在引用该变量的源文件中对它进行声明,然后源文件或文件中的函数才能引用它,即将然后源文件或文件中的函数才能引用它,即将变量的作用域延伸到其他的源文件。变量的作用域延伸到其他的源文件。在引用外部变量的在引用外部变量的 文件中不会为其分配内存文件中不会为其分配内存空间。空间。8.9 8.9 变量的存储类别变量的存储类别例例.用用extern将外部变量的作用域扩展到其他文件。将外部变量的作用域扩展到其他文件。#include“stdio.h”int A=1;/在在s.c文件定义了全局变量文件定义了全局变量A*/void fun()/*在函数在函数fun中引用变量中引用变量A不必声明不必声明*/void main()/*在函数在函数main中引用变量中引用变量A不必声明不必声明*/extern A;/*声明变量声明变量A为一个已定义的外部变量为一个已定义的外部变量*/void fac(int n)A=A*n;/*在函数在函数fac外已声明外已声明A为外部变量,函数为外部变量,函数fac可以引用可以引用A*/*源文件源文件s.c*/*源文件源文件d.c*/8.9 8.9 变量的存储类别变量的存储类别5.用用static声明外部变量声明外部变量在程序设计中如果希望某些外部变量只限于在程序设计中如果希望某些外部变量只限于被本文件引用,而不能其他文件引用。可以被本文件引用,而不能其他文件引用。可以在定义外部变量时加一个在定义外部变量时加一个static声明。声明。file1.cstatic int A;void main()file2.cextern int A;void fun(int n)A=A*n;8.9 8.9 变量的存储类别变量的存储类别注意注意:对局部变量用对局部变量用static声明,则改变了该变量声明,则改变了该变量的生存期,使它在整个程序执行期间不释的生存期,使它在整个程序执行期间不释放,为其分配的空间始终存在。放,为其分配的空间始终存在。对全局变量用对全局变量用static声明,则改变了该变量声明,则改变了该变量的作用域,即只限于本文件模块使用。的作用域,即只限于本文件模块使用。静态静态外部变量外部变量函数外部定义的静态变量。函数外部定义的静态变量。作用域仅限所在的源程序文件。作用域仅限所在的源程序文件。关于变量的声明和定义关于变量的声明和定义8.9 8.9 变量的存储类别变量的存储类别定义:建立存储空间的声明定义:建立存储空间的声明 声明:不建立存储空间的声明声明:不建立存储空间的声明注意注意:外部变量的定义和声明外部变量的定义和声明 外部型变量的定义只有一次,它在所有函数外部型变量的定义只有一次,它在所有函数之外,而同一文件中的外部变量的声明可以有之外,而同一文件中的外部变量的声明可以有多次,它可以在函数内也可在函数外。多次,它可以在函数内也可在函数外。例如:例如:void main()extern A;/*声明声明A是一个已定义的外部变量是一个已定义的外部变量*/int A;/*定义外部变量定义外部变量*/对外部型变量的初始化只能在定义时进行,对外部型变量的初始化只能在定义时进行,而不能在声明时进行。而不能在声明时进行。存储类别小结存储类别小结8.9 8.9 变量的存储类别变量的存储类别局部变量局部变量全局变量全局变量自动变量自动变量,即动态局部变量即动态局部变量(离开函数离开函数,值就消失值就消失)静态外部变量静态外部变量(只限本文件引用只限本文件引用)静态局部变量静态局部变量(离开函数,值仍保留离开函数,值仍保留)寄存器变量寄存器变量(离开函数离开函数,值就消失值就消失)外部变量外部变量(即非即非静态外部变量,允许其他文件引用静态外部变量,允许其他文件引用)(1)从作用域角度分为从作用域角度分为(形式参数可以定义为自动变量或寄存器变量形式参数可以定义为自动变量或寄存器变量)8.9 8.9 变量的存储类别变量的存储类别动态存储动态存储静态存储静态存储自动变量自动变量 (本函数内有效本函数内有效)静态局部变量静态局部变量(函数内有效函数内有效)寄存器变量寄存器变量(本函数内有效本函数内有效)静态外部变量静态外部变量(本文件内有效本文件内有效)(2)从生存期角度分为从生存期角度分为形式参数形式参数(本函数内有效本函数内有效)外部变量外部变量(其他文件可以引用其他文件可以引用)8.9 8.9 变量的存储类别变量的存储类别内存中内存中静态存储区静态存储区内存中内存中动态存取区动态存取区静态局部变量静态局部变量自动变量和形式参数自动变量和形式参数静态外部变量静态外部变量(函数外部静态变量函数外部静态变量)(3)从变量值存放的位置分为从变量值存放的位置分为外部变量外部变量(其他文件可以引用其他文件可以引用)寄存器变量寄存器变量CPUCPU中的中的寄存器寄存器课堂练习课堂练习 课堂练习课堂练习写出程序运行结果写出程序运行结果:#in

    注意事项

    本文(C语言 第08章 函数.ppt)为本站会员(s****8)主动上传,淘文阁 - 分享文档赚钱的网站仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对上载内容本身不做任何修改或编辑。 若此文所含内容侵犯了您的版权或隐私,请立即通知淘文阁 - 分享文档赚钱的网站(点击联系客服),我们立即给予删除!

    温馨提示:如果因为网速或其他原因下载失败请重新下载,重复下载不扣分。




    关于淘文阁 - 版权申诉 - 用户使用规则 - 积分规则 - 联系我们

    本站为文档C TO C交易模式,本站只提供存储空间、用户上传的文档直接被用户下载,本站只是中间服务平台,本站所有文档下载所得的收益归上传人(含作者)所有。本站仅对用户上传内容的表现方式做保护处理,对上载内容本身不做任何修改或编辑。若文档所含内容侵犯了您的版权或隐私,请立即通知淘文阁网,我们立即给予删除!客服QQ:136780468 微信:18945177775 电话:18904686070

    工信部备案号:黑ICP备15003705号 © 2020-2023 www.taowenge.com 淘文阁 

    收起
    展开