欢迎来到三一文库! | 帮助中心 三一文库31doc.com 一个上传文档投稿赚钱的网站
三一文库
全部分类
  • 研究报告>
  • 工作总结>
  • 合同范本>
  • 心得体会>
  • 工作报告>
  • 党团相关>
  • 幼儿/小学教育>
  • 高等教育>
  • 经济/贸易/财会>
  • 建筑/环境>
  • 金融/证券>
  • 医学/心理学>
  • ImageVerifierCode 换一换
    首页 三一文库 > 资源分类 > PPT文档下载  

    c编程自定义函数.ppt

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

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

    c编程自定义函数.ppt

    1,第2-4讲 自定义函数,函数的基本知识 函数的定义 函数的参数 函数的返回值 函数的调用 函数调用的一般形式 调用的方式 嵌套调用 递归调用 函数与数组 局部变量和全局变量 变量的动态存储方式和静态存储方式,2,4.1 概述,C语言函数分为两类: 库函数 scanf printf sqrt cos strcmp 自定义函数 main 每个程序必须有一个main函数 表明程序运行的起始点 只用一个main编程,可能使程序太大、太复杂 例4-1,输出如图所示内容:,3,4,在面向过程的程序设计中,一个较为复杂的程序一般通过模块化,分解成主模块与若干子模块的组合,即一个主函数与若干子函数。 “分”的优点: 便于自上而下的模块化编程; 通过在适当的地方使用函数,可以减短源程序的长度; 更容易定位和隔离有错误的函数,便于进一步的检查; 函数可以被其他多个程序使用。 模块化程序设计 可以把大型程序组织成小而独立的程序段(模块),它们单独命名,是单个的可调用的程序单元。 在C语言中,每个模块就是一个函数,负责完成单个任务。 C语言程序一般都由许多小的函数组成。,5,模块化程序设计的特征: 每个模块只做一件事情。 模块之间的通信只允许通过调用模块来实现。 某个模块只能被更高一级的模块调用。 如果不存在调用与被调用关系,模块之间是不能直接通信的。 所有模块都是使用控制结构设计成单入口、单出口的系统。,6,例4-2,将例4-1中重复执行的部分改写成函数,/ 函数声明(原型),/ 函数调用,/ 函数定义(函数体),函数派生数据类型 函数名标识符 函数具有与之相关的类型 使用之前,函数名及其类型必须已经声明和定义。,7,多函数程序 函数就是含有执行某个特定任务的代码块。 函数一旦设计和封装后,就可以看作是一个“黑盒子”,它从主程序中获得一些数据,并返回一个值。 函数操作的内部细节对程序的其他部分是不可见的。 程序所知道的函数就是:输入什么数据以及输出什么数据。 每个C程序至少包含一个函数,即main函数(主函数)。由主函数调用其它函数,其它函数也可以互相调用。同一个函数可以被一个或多个函数调用任意多次。 一个程序可以保存在一个或多个源文件中。各个文件可以单独编译,并可以与库中已编译过的函数一起加载。,8,4.2 函数的基本知识,一、函数的定义 包括以下元素 函数名 函数类型 参数列表 局部变量声明 函数语句 返回语句,函数头,函数体,9,函数定义的一般格式: 函数类型 函数名(形式参数列表)/函数头,末尾没有; 局部变量声明; 语句1; 语句2; return 语句; 函数类型,即函数带回来的值的类型。 缺省为int。 如不返回任何值,则函数类型应指定为void(也是C的基本类型之一),10,形参,以接收从调用函数发送来的数据。 形参列表包含了变量的声明,变量之间用逗号分隔开;一般格式为: type1 name1, type2 name2, , type n name n 其中: type1 , type2 , type n 是类型标识符,表示形参的类型; name1, name2, , name n 是形参名。 float quadratic(int a, int b, intc) double power(double x, int n) float mul(float x, float y) int sum(int a, int b) int sum(int a, b) ×错 形参可以没有,即“无参函数”。可以在参数列表的括号中使用关键字void void PrintLine(void) 函数在没被调用时,形参只是一个符号。只有函数在被调用时,才由主调函数将实际参数(实参)赋予形参。,11,函数体,包含了函数声明及完成任务所需的语句。依次为: 1) 局部变量,即本函数所需的变量; 2) 完成函数任务的语句; 3) return 语句,返回函数所得的值。 不返回函数值可以省略return语句,但要注意把函数的返回类型声明为void。 函数体可以为空,即“空函数”。此函数不作任何工作,没有任何实际作业。(可先占位,再补充) 几种典型的示例:,12,13,函数的类型和返回值 函数的返回值类型应当属于某个确定的类型。如果在定义函数时不指定函数类型,系统会隐含指定函数类型为int,函数结束也需返回一个int型值。 函数的返回值由 return 语句给出。 return(表达式); 或 return 表达式; 如果函数没有返回值,函数名前的类型标识符为void,return 语句可省略不写。 如果return中的值与函数值的类型不一致,则以函数类型为准。即在返回时先作隐含的类型转换,然后再返回。,/ 3.5 被转换成 3 后返回给主函数,14,例4-3,编写一个函数用于获取三个整数的最大值。,15,二、函数的调用 函数的调用一般格式: 函数名 (实参列表); 实参列表中的参数应与函数原型中形参的个数相同、类型相符 一一对应。 主调函数向被调函数以值传递的方式传递。,16,17,函数调用的执行过程,18,函数调用的方式 函数调用可以作为一条语句出现,这时函数可以没有返回值。 PrintLine(); 函数调用也可以出现在表达式中,这时必须有一个明确的返回值。 a=mul(10,5); printf(“%dn“, mul(a, b) ); If( mul(m, n) total ) printf(“Large“); 函数不能用在赋值语句的左边。 mul(a, b) 15; × 错,19,函数的嵌套调用 C语言 不允许函数嵌套定义,即:在函数定义中再定义一个函数是非法的。 C语言的函数定义都是互相平行、独立的。 C语言可以嵌套调用函数,即在调用函数的过程中,又调用另一个函数。,调fun( ),20,例4-4,用函数实现,21,三、函数的声明(函数原型) 返回类型 函数名(形式参数表); 函数原型是一条程序语句,必须以分号结束。 C程序中的所有函数在使用之前都必须声明,即先声明后使用。如果被调函数的定义出现在主调函数之前,可以不必声明。 函数原型声明可在所有函数(包括main)之前。全局原型,该函数对程序中的所有函数都是可用的。 函数原型声明位于某函数定义之中。局部原型,该函数主要是被包含它们的函数使用。 标准库函数的函数原型都在头文件中提供,可用 # include 包含这些原型文件。 函数原型和函数定义在返回类型、函数名和参数表上必须完全一致。 函数原型的参数表可不必包含参数名称,而只要包含参数类型即可。,例如: int max(int, int,int); 等价于:int max(int a, int b,int c);,22,例4-5,随机函数rand 和srand的使用 rand(),返回一个0RAND_MAX(32767)之间的随机整数。 RAND_MAX和rand定义在头文件stdlib.h中 计算机产生的是一个伪随机数,即这个随机数序列有一个长度,会出现重复 用srand(int seed),其参数称为随机数序列种子。即不同的伪随机数序列种子,可以得到不同的伪随机数序列。一般采用系统时间作为随机数序列种子,例如: srand(unsigned int) time(NULL);,23,24,4.3 函数的类型,根据是否有参数,是否有返回值,可以将函数分为以下几种类型: 类型1:无参数、无返回值的函数。 类型2:有参数、无返回值的函数。 类型3:有参数、有返回值的函数。 类型4:无参数、有返回值的函数。,25,一、无参数、无返回值的函数 当函数没有参数时,不用从调用函数接收任何数据。同样,它也不返回值,调用函数不会从被调用函数中接收任何数据。,26,例4-6,请编写一个含有多个函数的程序,这些函数之间不进行任何数据通信。,27,28,二、有参数、无返回值的函数 调用函数和被调用函数之间的数据通信情况:,29,实参和形参在数量、类型和顺序上必须匹配。实参的值被逐个赋给形参,30,必须保证函数调用有匹配的参数。 实参形参,多余的实参将被丢弃; 实参形参,未匹配的形参将被初始化为垃圾值; 数据类型的任何不匹配情况都将导致传递垃圾值。 形参必须是有效的变量名,而实参可以是变量名、表达式或常量 实参到形参的传递实现的是值的传递。被调函数中发生的一切不会影响到实参中的变量。 例4-7,修改例4-6,使得在调用函数中包含参数。 void PrintLine(char ch); void value(float p, float r, int n);,31,32,33,三、有参数、有返回值的函数 为确保程序间更高的可移植性,函数编码中往往不包含任何I/O操作。 调用函数与被调用函数之间具有双向通信。,34,例4-8,修改例4-7中的value函数,使其能将计算的sum值返回给main函数,由main函数按要求实现输出。同时扩展PrintLine函数,可将显示字符的长度作为参数传递。,35,36,四、无参数但有一个返回值的函数 例4-9,设计一个与getchar 类似的函数来获取一个整数。,37,4.4 函数调用时参数的传递,在函数未被调用时,函数的形参并不占有实际的内存空间,也没有实际的值。 只有在函数被调用时才为形参分配存储单元,并将实参与形参结合。 实参类型必须与形参相符。 函数的参数传递指的就是形参与实参结合的过程。 一、值调用 传值调用 直接将实参的值传递给形参。 单向传递。 形参的改变不会影响到实参。,38,例4-10,传值调用,将两个数的值换位。,39,执行主函数中的函数调用语句:swap(x,y);,在swap 子函数中:,temp = a;,a = b;,b = temp;,返回主函数后:,40,例4-11,从键盘上输入字符,要求输入字符为0-9十个数字。,41,二、 数组作为函数参数 数组元素可以作为调用函数时的实参,用法同单个变量,是单向传递 数组名做函数的参数 函数调用时只需传递数组名。 在函数定义中,形参的类型必须与实参数组的相同,数组的大小不必指定。 函数原型中的参数也必须定义为一个数组。 例4-12:调用一个函数求数组元素之和,42,43,44,例4-13, 请编写一个程序,使用一个函数来把有10个整数元素的数组按升序排列,45,46,例4-14:调用一个函数求二维数组元素的最大值,47,例4-15:矩阵乘法,48,49,50,三、结构体作为函数的参数 分别传递各个结构成员 像普通变量一样来处理; 如果结构很大,该方法就变得难以控制,效率也不高。 传递整个结构 将整个结构的副本传递给被调函数,函数对结构成员的任何修改都不会影响实参。,51,例,编写几个对点和矩形操作的函数。 定义点的结构类型 定义矩形的结构类型,52,1. 定义函数makepoint,它带有两个整型参数,并返回一个point类型的结构,53,2. addpoint函数:将两个点相加,54,注意要点: 当函数的参数是一个结构类型时,主调、被调函数中相对应的实参、形参必须为相同的结构类型。 当函数的返回值是一个结构时,必须将返回值赋给调用函数中的相同类型的结构变量。 和其它类型的参数一样,结构类型的参数也是通过“值”传递的。 例4-16,以将3个学生按成绩由高到低排序为例,55,56,4.5 函数的递归调用,函数可以直接或间接地调用自身,称为递归调用。 直接调用: 间接调用:,void fun1(void) fun1( ); / 调用fun1自身 ,57,递归的条件 1)须有完成函数任务的语句。 2)有一个确定是否能避免无限的递归调用的测试。 3)一个递归调用语句。该语句的参数应该逐渐逼近不满足条件,以致最后断绝递归。 4)先测试,后递归调用。,#include void count(int val) / 递归函数可以没有返回值 if (val 1) count(val -1); printf(“ok:“, val); / 显示:“ok:整数值” printf(“n“); ,58,例4-17,有5个人坐在一起,问第5个人多少岁?他说比第4个人大2岁。问第4个人岁数,他说比第3个人大2岁。问第3个人岁数,他又说比第2个人大2岁。问第2个人岁数,他说比第1个人大2岁。最后问第1个人,他说是10岁。请问第5个人多大? “推理” age(5) = age(4) + 2 age(4) = age(3) + 2 age(3) = age(2) + 2 age(2) = age(1) + 2 age(1) = 1 “总结” 由此计算出各年龄,59,递归的过程: 第一阶段:回归。 第二阶段:递推。,60,例4-18, 计算n! 以5!为例,求值过程:5!5*4*3*2*15*(4!),61,62,63,例4-19:汉诺塔问题 有三根针A ,B,C。A针上有n个盘子,盘子大小不等,大的在下,小的在上,如图示。要求把这n个盘子从A针移到C针,在移动过程中可以借助B针,每次只允许移动一个盘子,且在移动过程中在三根针上都保持大盘在下,小盘在上。,将n个盘子从A针移到C针可以分解为下面三个步骤: 1)将A上n-1个盘子移到B针上(借助C针); 2)把A针上剩下的一个盘子移到C针上; 3)将n-1个盘子从B针移到C针上(借助A针);,64,65,递归并不节省存储器的开销,因为递归调用过程中必须在某个地方维护一个存储处理值的栈。 递归的执行速度并不快,但递归代码比较紧凑,并且比相应的非递归代码更易于编写与理解。 在描述树等递归定义的数据结构时,使用递归尤其方便。,66,4.6 局部变量和全局变量,一、局部变量 在函数内部定义的变量,仅在该函数内有效。 不同函数中可以使用相同名字的变量,互不干扰。 局部变量在定义时没有明确的初始化值。 在函数开始运行时,局部变量在栈区中被分配空间,函数退出时,局部变量随之消失。 形式参数也是局部变量。,例: void main( ) void func( ) int s; int s; ,67,二、全局变量 在任何函数之外定义的变量,也称为外部变量。 可以被本文件中其它函数所共用。 它的有效范围是从定义变量的位置开始一直到本源文件结束。 存放在内存的全局数据区。 由编译器建立,默认初始化为0。,int n=5; / 全局变量 void func( ) void main( ) int s; int m = n; n = s; ,68,说明 全局变量的作用是增加了函数之间数据联系的渠道。 若在一个函数中改变了全局变量的值,就能影响到其它函数。 不成文的规定:全局变量的第一个字母用大写表示。 不在特别必要时,尽量不要使用全局变量 全局变量在程序的全部执行过程中都占用存储单元。 降低了函数的通用性。若外部变量与其它文件的变量同名,移植时就会出现问题,降低了程序的可靠性和通用性。 降低程序的清晰性。 一般要求把C程序中的函数做成一个封闭体,除了可以通过“实参形参”的渠道与外界发生联系外,没有其它渠道移植性好,可读性强。,69,4.7 作用域与可见性,作用域又称作用范围,它指的是标识符的有效范围 可见性指的是标识符是否可以被引用。 一、作用域分类 函数原型作用域 是C 程序中最小的作用域 开始于函数原型声明的左括号,结束于函数原型声明的右括号。 double area ( double width, double length);,70,块作用域局部作用域 块是一对大括号括起来的一段程序 块语句 在块中声明的标识符,其作用域从声明处开始,一直到块结束的大括号为止。 具有块作用域的标识符称作局部标识符。,void fun( int y ) / y 的作用域从此开始 int a,b; / a, b的作用域从此开始 if ( y0 ) int x; / x 的作用域从此开始 x = a + b; / x 的作用域到此结束 / a, b, y 的作用域到此结束,71,void fun( int n) if( n5) int i; i=n; printf(“%dn“, i); else double i; i=n; printf(“%fn“, i); printf(“%dn“, i); ,/ int i 的作用域从此开始,/ int i 的作用域到此结束,/ double i 的作用域从此开始,/ double i 的作用域到此结束,/ error! i 无定义,72,文件作用域全局作用域 在所有函数定义之外说明; 开始于声明点,结束于文件尾(全局变量)。 在头文件的文件作用域中所进行的声明,若该头文件被一个源文件嵌入,则声明的作用域也扩展到该源文件中,直到源文件结束。,int number; int value; void main( ) a = 1; / error! a 无定义 number = 0; value = number + 1; printf(“%dn”, i); int a;,73,二、可见性 程序运行到某一点,能够引用到的标识符,就是该处可见的标识符。 作用域可见性的一般规则: 标识符要声明在前,引用在后。 在同一作用域中,不能声明同名的标识符。 在没有互相包含关系的不同的作用域中声明的同名标识符互不影响。 如果在两个或多个具有包含关系的作用域中声明了同名标识符,则外层标识符在内层不可见。,74,例4-20,作用域可见性实例1,75,例4-21,作用域可见性实例2,76,4.8 变量的存储类型,一、动态存储方式与静态存储方式 程序的内存区域: 静态存储方式:在程序的运行期间分配固定的存储空间 动态存储方式:在程序的运行期间根据需要进行动态的分配存储空间。,77,动态存储区存放的数据有: 函数的形式参数 自动变量 函数调用时的现场保护和返回地址 在程序执行过程中,如果在同一个程序中两次调用同一函数,分配给此函数中局部变量的存储空间地址可能是不相同的。 C语言中,变量和函数的属性除了具有数据类型外,还具有存储类型: auto(自动的):采用堆栈方式分配内存空间,属于暂时性存储,其存储空间可以被若干变量多次覆盖使用。 static(静态的):在内存中是以固定地址存放的,在整个程序运行期间都有效。 register(寄存器的):存放在通用寄存器中。 extern(外部的):在所有函数和程序段中都可引用。,78,二、auto变量 函数的形参、其中定义的局部变量等,如不专门声明为static,都是动态地分配存储空间的,数据存储在动态存储区中。 自动变量 “auto”关键字可以省略。若在定义变量时不写auto,则隐含确定为“自动存储类型”。 程序中大多数变量属于自动变量。 auto int a=3, b; int a=3, b;,79,三、用static声明局部变量 静态局部变量,在静态存储区内分配存储单元。 变量在程序的整个运行期间都不释放。 static int i; static char bufBUFSIZE; 静态存储变量,若无显式初始化,则在程序编译时自动初始化为 0。即只初始化一次,以后每次调用函数时不再重新赋初值,而只是保留上次函数调用结束时的值。 虽然静态局部变量在函数调用结束后仍然存在,但其它函数是不能引用它的。,80,例4-22,静态存储变量举例,81,82,四、register变量 局部变量的值直接存放在CPU中的寄存器中。 只有局部自动变量和形式参数可以作为寄存器变量,其它(如全局变量、局部静态变量)不行。 register int x; register char c; f(register unsigned m, register long n) register int I; register static int a, b; ×错! 一个计算机系统中的寄存器数目是有限的,不能定义任意多个寄存器变量。,83,五、外部变量 即全局变量,是在函数的外部定义的,它的作用域为从变量的定义处开始,到本程序文件的末尾。 在此作用域中,全局变量可以被程序中的各个函数所引用。 编译时分配的静态存储区。 有时需要用extern来声明外部变量,用以扩展外部变量的作用域。,84,1. 在一个文件内声明外部变量 如果不在文件的开头定义外部变量,其有效的作用范围只限于从定义处开始到文件结束。 如果在定义点之前的函数想引用该外部变量,则应在引用之前用extern 作“外部变量声明”。 例4-23,外部变量举例,85,86,2. 在多个文件的程序中声明外部变量 一个C程序可以由一个或多个包含若干函数定义的源文件组成。 其中只有一个源文件具有主函数 main( ),而其他的文件不能含有 main( )。 C的编译器和连接器把构成一个程序的若干源文件有机地联络在一起,最终产生可执行程序。 C语言中,通过建立一个工程文件( .prj) ,将多个源文件构成一个程序。 构成一个程序的多个源文件之间,如需要用到同一个外部变量或函数,不能分别在两个文件中各自定义,而是要通过声明数据或函数为外部的(extern)来进行沟通。,87,例4-24,由两个文件构成的一个程序。,88,带 extern 的变量说明只是一个变量声明,不是变量定义。它表示所声明的变量在程序的其它文件中定义(分配空间)。 如果共同的变量一次都没有定义,或在各个文件中分别定义(多次定义),或声明的类型不一致,都会造成直接或间接的错误。,89,4.9 内部函数和外部函数,一、内部函数 只能被本文件中其它函数所调用。 在定义内部函数时,在函数类型的声明前面加static。即: static 类型标识符 函数名(形参表) 内部函数又称为静态函数。 通常将只能由同一个文件使用的函数和外部变量放在一个文件中,在它们前面加上static。,90,二、外部函数 在定义函数时,如果在函数声明或定义的最左端加上extern,表示该函数是外部函数。 外部函数可以供其它文件调用。 C语言规定,如果在定义函数时省略extern,则隐含为外部函数。 默认的函数声明或定义总是extern 的。 所有函数声明一般都放在源文件的开始位置。,91,例4-25,从字符串中删除给定的字符。要求用外部函数实现删除字符的功能。 main.c,用来实现字符串及字符的输入、输出功能 DeleteChar函数,用来实现从字符串中删除字符 在main.c中将DeleteChar定义为外部函数 extern DeleteChar(char str , char ch);,92,

    注意事项

    本文(c编程自定义函数.ppt)为本站会员(本田雅阁)主动上传,三一文库仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对上载内容本身不做任何修改或编辑。 若此文所含内容侵犯了您的版权或隐私,请立即通知三一文库(点击联系客服),我们立即给予删除!

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




    经营许可证编号:宁ICP备18001539号-1

    三一文库
    收起
    展开