




已阅读5页,还剩46页未读, 继续免费阅读
版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领
文档简介
第6章 函数,结构化程序的模块结构:,第6章 函数,程序结构 :,第6章 函数,根据函数的定义者不同,分为如下两大类: (1)标准函数:系统提供的已定义的函数,一般用户都可以调用。如前面学习过的输入输出函数scanf、printf、getchar、putchar等。Turbo C 2.0的部分常用库函数见附录D。 (2)用户自定义函数:用户自己编写的用来解决具体问题的函数。,第6章 函数,根据函数的参数形式,C语言函数又分为如下两种: (1)无参函数: 主调函数并不将数据传送给被调用函数。 (2)有参函数: 在调用函数时,在主调函数和被调函数之间有参数传递,也就是说,主调函数可以将数据传送给被调用函数使用,被调用函数中的数据也可以带回来供主调函数使用。,第6章 函数,6.1 函数的定义和调用,6.1.1 函数定义,函数定义的一般形式: 类型标识符 函数名(形式参数表列) 说明部分 执行部分 例:,int max(int x,int y) /* 函数首部*/ /*函数体开始*/ int z; /*说明部分*/ if(xy) z=x; /*执行部分*/ else z=y; return(z); /*函数体结束*/,第6章 函数,6.1 函数的定义和调用,6.1.1 函数定义,说明:函数定义包括函数首部和函数体两部分。 (1)函数首部:函数定义的第一行。,1)函数名前面的类型标识符是指函数返回值的类型,简称函数值类型。函数的返回值由函数中的return语句获得,即return后的表达式的值,可以是简单类型、void类型或构造类型等。当return后的表达式的类型与函数名前面的类型标识符不一致时,以函数名前面的类型标识符为函数值类型(即是将return后的表达式的值转换为函数名前面的类型后作为函数值返回)。如果函数中无return语句,将返回一个不确定值;如希望不返回值,可以定义函数类型为void,当函数值类型为int时,可省略其类型的说明。,第6章 函数,6.1 函数的定义和调用,6.1.1 函数定义,说明:函数定义包括函数首部和函数体两部分。 (1)函数首部:函数定义的第一行。,2)函数名是函数的标识符,遵循C语言标识符的命名规则,区分大小写。 3)函数名后的形式参数表列给出函数的形式参数及其类型说明。形式参数简称形参,形式参数及其类型说明放在函数名后的一对圆括号中,要特别注意的是,无论函数是否有形式参数,函数名后的圆括号不可省,并且圆括号之后不能接“;”。形式参数表列的一般形式如下: 形参1类型 形参1,形参2类型 形参2,形参n类型 形参n,第6章 函数,6.1 函数的定义和调用,6.1.1 函数定义,说明:函数定义包括函数首部和函数体两部分。 (1)函数首部:函数定义的第一行。,(2)函数体:函数说明之后的花括号“ ”括起来的部分,包括说明部分和执行部分。 1)声明部分:用来对函数中使用的变量和函数作说明。 2)执行部分:由基本语句组成,函数的功能由函数体内的各个语句的执行来实现。,第6章 函数,6.1 函数的定义和调用,6.1.2 函数调用,一个函数一旦被定义,就可以在程序的其他函数中使用它,这个过程称为函数调用。,1函数调用的一般形式 函数名(实参表列); 2函数调用语句的执行过程 首先计算每个实参表达式的值,并把此值存入所对应的形参单元中,然后把执行流程转入函数体中,执行函数体中的语句,当执行到函数体的右花括号或return语句时,表示函数体执行完成,这时将返回到调用此函数的语句的下一条语句,继续往下执行。,第6章 函数,6.1 函数的定义和调用,6.1.2 函数调用,例: #include int max(int x,int y) int z; z=xy?x:y; return(z); ,main() int a,b,c; scanf(“%d%d“, ,程序结果如下: 输入:10 20 输出:20,一个函数一旦被定义,就可以在程序的其他函数中使用它,这个过程称为函数调用。,第6章 函数,6.1 函数的定义和调用,6.1.2 函数调用,一个函数一旦被定义,就可以在程序的其他函数中使用它,这个过程称为函数调用。,3说明 (1)在定义函数中指定的形参变量,在未出现函数调用时,它们并不占内存中的存储单元;只有发生函数调用时被调用函数中的形参才被分配内存单元。调用结束后,形参所占用的内存单元也同时被释放。 (2)实参可以是常量、变量或表达式,但必须有确定的值。在调用时将实参的值赋给形参变量。 (3)实参与形参的类型应一致。只有字符型和整型可以互相通用。 (4)实参变量对形参变量的数据传递是“值传递”,即单向传递,只由实参传给形参,而不能由形参传回来给实参。在内存中,实参变量与形参变量是不同的单元,即使同名,也是不同的单元。形参的值如果发生改变,并不会改变主调函数的实参值。,第6章 函数,6.1 函数的定义和调用,6.1.2 函数调用,例:,一个函数一旦被定义,就可以在程序的其他函数中使用它,这个过程称为函数调用。,#include swap(int x,int y) int t; printf (“(2)a=%d b=%dn“,x,y); t=x;x=y;y=t; printf (“(3)a=%d b=%dn“,x,y); ,main() int x=10,y=20; printf(“(1)x=%d y=%dn“,x,y); swap(x,y); printf (“(4)x=%d y=%dn“,x,y); ,程序结果如下: (1)x=10 y=20 (2)x=10 y=20 (3)x=20 y=10 (4)x=10 y=20,第6章 函数,6.1 函数的定义和调用,6.1.2 函数调用,一个函数一旦被定义,就可以在程序的其他函数中使用它,这个过程称为函数调用。,4函数调用方式 函数有以下三种调用方式: (1)函数语句:把函数调用作为一个语句, 例如:sort(); 这时不要求函数带回值,只要求函数完成一定的操作。 (2)函数表达式:函数出现在一表达式中,这种表达式称为函数表达式。这时要求函数带回一个确定的值以参加表达式的计算。 例如:c=2*max(a,b); (3)函数参数。函数调用作为一个函数的实参。 例如:m=max(a,max(b,c); 其中max(b,c)是一次函数调用,它的值作为max另一次调用的实参。,第6章 函数,6.1 函数的定义和调用,6.1.3 函数声明,调用用户自定义函数时,一般调用函数和被调用函数应在同一个文件中,在调用函数中对被调用函数返回值的类型、函数名称、函数形式参数的类型进行说明,这种说明称为函数声明。,例:,#include main() int a,b,c; int max(int,int); /*对max函数进行声明*/ scanf(“%d%d“, ,第6章 函数,6.1 函数的定义和调用,6.1.3 函数声明,函数声明有以下三种形式: (1)类型名 函数名(类型1 形参1,类型2 形参2,类型n 形参n); (2)类型名 函数名(类型1,类型2,类型n); (3)类型名 函数名(); 其中,形式(2)是最常用的一种声明形式。,第6章 函数,6.1 函数的定义和调用,6.1.3 函数声明,对被调用函数的声明,在以下几种情况下可以省略: (1)如果函数值是整型或字符型,可以不进行声明。 例:,#include main() int a,b,c; scanf(“%d%d“, ,第6章 函数,6.1 函数的定义和调用,6.1.3 函数声明,对被调用函数的声明,在以下几种情况下可以省略:,(2)如果被调用函数的定义出现在主调函数之前,可以不声明。 例:,int max(int x,int y) int z; z=xy?x:y; return(z); #include main() int a,b,c; scanf(“%d%d“, ,第6章 函数,6.1 函数的定义和调用,6.1.3 函数声明,对被调用函数的声明,在以下几种情况下可以省略:,(3)如果在所有函数定义之前对函数类型进行了声明,则在各个主调函数中不再进行声明。 例:,int max(int,int); #include main() int a,b,c; scanf(“%d%d“,第6章 函数,6.2 函数的嵌套调用和递归调用,6.2.1 函数的嵌套调用,所谓函数的嵌套调用是指一个函数调用另一函数的过程中又出现对其他函数的调用。 函数嵌套调用的调用结构如图所示:,第6章 函数,6.2 函数的嵌套调用和递归调用,6.2.1 函数的嵌套调用,例:,fun1(int a,int b) int c; a+=a;b+=b; c=fun2(a,b); return c*c; ,fun2(int a,int b) int c; c=a*b%3; return c; ,main() int x=11,y=19; printf(“%dn“,fun1(x,y); ,注意:函数的调用可以嵌套,但函数的定义是平行的、相互独立的,不能嵌套定义。,第6章 函数,6.2 函数的嵌套调用和递归调用,6.2.2 函数的递归调用,在调用一个函数的过程中又出现直接或间接地调用该函数本身,称为函数的递归调用。 其调用结构如图所示。,第6章 函数,6.2 函数的嵌套调用和递归调用,6.2.2 函数的递归调用,递归函数的执行包括递推和回归两个过程。,例:求 t=n!,int f (int n) int t; if(n=1|n=0) t=1; else t=n*f (n-1); return t; main() int n,t; scanf(“%d”, ,递推: 回归:,第6章 函数,6.3 变量的作用域及存储类别,6.3.1 局部变量与全局变量,1局部变量,局部变量是在一个函数内部定义的变量,它只在本函数范围内有效。,例: fun1(int a,int b) int c; a+=a;b+=b; c=fun2(a,b); printf(“%d,%dn“, a,b); return c; fun2(int a,int b) int x; a+=a; b+=b; int a=1; a=a+b; x=a+b; printf(“%d, %d,%dn“, a,b,x); return x; main() int x=11,y=19; printf(“%dn“, fun1(x,y); printf(“%d,%dn“, x,y); ,程序运行结果如下: 44,76,120 22,38 120 11,19,第6章 函数,6.3 变量的作用域及存储类别,6.3.1 局部变量与全局变量,1局部变量,说明: (1)主函数main中定义的变量也是局部变量,也只在主函数中有效。 (2)形式参数也是局部变量,其他函数不能调用。 (3)可以在一个函数内部的复合语句中定义变量,这些变量只在复合语句中有效。 (4)不同函数中可以使用相同名字的变量,它们代表不同的对象,互不干扰。,第6章 函数,6.3 变量的作用域及存储类别,6.3.1 局部变量与全局变量,2全局变量,全局变量是在函数之外定义的变量,从定义变量的位置开始到本源文件结束范围内有效。,例: int a, b; fun1() int c; a=2;b=3; c=fun2(); printf(“%d,%dn“, a,b); return c; int x=11,y; fun2() a+=a; b+=b; x=a+b;y=a-b; printf(“%d, %d, %d, %dn“, a,b,x,y); return x; main() int y=19; printf(“%dn“,fun1(); printf(“%d,%dn“, x,y); ,程序运行结果如下: 4,6,10,-2 4,6 10 10,19,第6章 函数,6.3 变量的作用域及存储类别,6.3.1 局部变量与全局变量,2全局变量,说明: (1)全局变量可以在函数间传递数据,增加函数间数据联系的渠道。 (2)全局变量在程序的整个执行过程中都有效。 (3)在同一个源文件中,全局变量与局部变量可以同名,在局部变量的作用范围内,全局变量不起作用。 (4)对于全局变量,如果在定义时不进行初始化,则系统将自动赋予其初值,对数值型变量赋0,对字符型赋变量0。,第6章 函数,6.3 变量的作用域及存储类别,6.3.2 动态变量与静态变量,1动态存储方式和静态存储方式 (1)动态存储方式。是指在程序运行期间根据需要动态分配存储空间的方式。 (2)静态存储方式。是指在程序运行期间分配固定的存储空间的方式。,第6章 函数,6.3 变量的作用域及存储类别,6.3.2 动态变量与静态变量,2动态变量,以动态存储方式分配的变量称为动态变量,包括所有函数的形式参数、用auto和register声明的局部变量。动态变量一般定义在函数内部(包括定义在函数首部的形式参数),只有当程序进入该函数时才分配存储空间,函数执行完后,变量的存储空间被释放,再次调用该函数时,系统重新分配新的存储空间。 动态变量在未被赋初值时,其值为不能确定的随机值。,第6章 函数,6.3 变量的作用域及存储类别,6.3.2 动态变量与静态变量,2动态变量,(1)用auto声明的局部变量。用auto声明的局部变量又称动态的局部变量。其声明形式如下: auto 变量类型 变量名; 其中,auto是可省略项。 例:,int fun(int a) auto int b,c=3; ,int fun(int a) int b,c=3; ,以上定义的b,c都是动态的局部变量。,第6章 函数,6.3 变量的作用域及存储类别,6.3.2 动态变量与静态变量,2动态变量,(2)用register声明的局部变量。用register声明的局部变量又称寄存器变量。寄存器变量的值放在CPU的寄存器中,使用时直接从寄存器取出参加运算,不必再到内存中去存取。为了提高执行效率,把程序中使用频率高的变量定义为寄存器变量。其声明形式如下: register 变量类型 变量名; 例:,fun1() register int i; for(i=1;i=1000;i+) ,说明: (1)只有局部动态变量和形式参数可以说明为寄存器变量。 (2)一个计算机系统中的寄存器的数目是有限的。,第6章 函数,6.3 变量的作用域及存储类别,6.3.2 动态变量与静态变量,3静态变量,以静态存储方式分配的变量称为静态变量,包括所有的全局变量和用static声明的局部变量。动态变量可以定义在函数外部(如:全局变量),也可以定义在函数内部(如用static声明的局部变量),静态变量在程序执行过程中占有固定的存储空间,只在程序执行结束时释放占用的存储单元。 静态变量在未被赋初值时,其值为0。,第6章 函数,6.3 变量的作用域及存储类别,6.3.2 动态变量与静态变量,3静态变量,(1)用static声明的局部变量。用static声明的局部变量又称静态的局部变量。其声明形式如下: static 变量类型 变量名; 静态局部变量的作用域仍然是变量定义所在的函数,即只有当程序进入该函数时,这些变量才可以使用,离开该函数后就不能使用这些变量了,但不能使用并不代表这些变量不存在,静态局部变量在程序第一次进入定义所在函数时被分配存储空间,函数执行完(所在程序并没有执行完)后,变量的存储空间不释放,再次调用该函数时,变量继续使用所占的存储空间,并保持上次调用所得到的结果。,第6章 函数,6.3 变量的作用域及存储类别,6.3.2 动态变量与静态变量,3静态变量,(1)用static声明的局部变量。,例: int fun(int a) auto int b=0; static c=3; b+;c+; return(a+b+c); ,main() int a=2; int i; for(i=0;i3;i+) printf(“%dn“,fun(a); ,程序运行结果如下: 7 8 9,第6章 函数,6.3 变量的作用域及存储类别,6.3.2 动态变量与静态变量,3静态变量,(2)用static声明全局变量。全局变量都是静态存储方式,在一个文件中定义的全局变量,在其他文件中也可以使用,用static声明全局变量是限制其作用域仅为所在的源程序文件,即不能被其他文件使用。其声明形式如下: static 变量类型 变量名; 用static声明全局变量与用static声明局部变量的形式相同,不同的只是定义位置不同,全局变量定义在函数外部,而局部变量定义在函数内部。,第6章 函数,6.3 变量的作用域及存储类别,6.3.2 动态变量与静态变量,3静态变量,(3)用extern声明全局变量。全局变量的作用域从定义变量的位置开始到所在源文件结束,用extern声明全局变量是扩展全局变量的作用域。其声明形式如下: extern 变量类型 变量名; 其中,变量类型是可省略项。 用extern声明全局变量与全局变量的定义是分开的,用extern声明全局变量应放在扩展位置。根据作用域扩展情况的不同,对全局变量进行extern声明的位置也不同。,第6章 函数,6.3 变量的作用域及存储类别,6.3.2 动态变量与静态变量,3静态变量,(3)用extern声明全局变量。,1)在所在源文件的作用域外的某函数内部进行声明,其作用是扩展全局变量的作用域至该函数。,例: fun1() int c; a=2;b=3; c=fun2(); printf(“%d,%dn“, a,b); return c; fun2() extern int x,y; a+=a; b+=b; x=a+b; printf(“%d, %d, %d, %dn“, a,b,x,y); return x; int x=11,y; main() int y=19; printf(“%dn“,fun1(); printf(“%d,%dn“, x,y); int a, b;,第6章 函数,6.3 变量的作用域及存储类别,6.3.2 动态变量与静态变量,3静态变量,(3)用extern声明全局变量。,2)在所在源文件的作用域外的函数外部声明,其作用是扩展全局变量的作用域,从声明位置至文件结束。,例: extern int a,b; fun1() int c; a=2;b=3; c=fun2(); printf(“%d,%dn“, a,b); return c; fun2() extern int x; a+=a; b+=b; x=a+b; printf(“%d, %d, %d, %dn“, a,b,x,y); return x; int x=11,y; main() int y=19; printf(“%dn“,fun1(); printf(“%d,%dn“, x,y); int a, b;,第6章 函数,6.3 变量的作用域及存储类别,6.3.2 动态变量与静态变量,3静态变量,(3)用extern声明全局变量。,3)在多文件程序的另一文件中声明,其作用是扩展全局变量的作用域至声明的文件中。,例:以下C程序由file1.c和file2.c两个文件构成。 file1.c: extern int x; int a, b; fun1() int c; a=2;b=3; c=fun2(); printf(“%d,%dn“, a,b); return c; file2.c: extern int a,b; int x=11,y; main() int y=19; a+; b+; printf(“%dn“,fun1(); printf(“%d,%dn“, a,b); printf(“%d,%dn“, x,y); ,第6章 函数,6.4 内部函数与外部函数,1内部函数 内部函数是只能被本文件中的函数调用的函数。其一般定义形式如下: static 类型标识符 函数名(形参表) 2外部函数 外部函数是可以被其他文件中的函数调用的函数。其一般定义形式如下: extern 类型标识符 函数名(形参表) 其中, extern 是可省略项。 外部函数可以被其他文件中的函数调用,但在主调用函数所在的文件中要对被调用函数进行声明。其一般声明形式如下: extern 类型标识符 函数名(形参表),第6章 函数,6.4 内部函数与外部函数,例: file1.c: extern fun2(); int a, b; fun1() int c; a=2;b=3; c=fun2(); printf(“%d,%dn“, a,b); return c; ,file2.c: extern fun1(); int x=11,y; fun2() extern int x,y; a+=a; b+=b; x=a+b; printf(“%d, %d, %d, %dn“, a,b,x,y); return x; main() int y=19; printf(“%dn“,fun1(); printf(“%d,%dn“, x,y); ,第6章 函数,6.5 本章考点,函数的定义。 函数的声明。 函数的调用。 函数的嵌套调用。 全局变量与局部变量。 动态变量与静态变量。,第6章 函数,6.6 典型试题详解,1以下函数值的类型是_。 fun(float x) float y; y=3*x-4; return y; A)int B)不确定 C)void D)float 正确答案:A(知识点:函数的定义) 试题分析:在函数定义时,函数名前没有函数类型,则默认函数类型为int类型。,第6章 函数,6.6 典型试题详解,2有如下函数调用语句: fun(rec1,rec2+rec3,(rec4,rec5); 该函数调用语句中,含有的实参个数是_。 A)3 B)4 C)5 D)有语法错 正确答案:A(知识点:函数的调用) 试题分析:在该函数调用中,含有的实参个数是3个。其中,第二个实参是rec2+rec3,是一个算术表达式,第三个实参是(rec4,rec5),是一个逗号表达式。如果实参是表达式,则首先计算表达式的结果,再将表达式的值传递给形参。,第6章 函数,6.6 典型试题详解,3请在以下程序第一行的填空处填写适当内容,使程序能正确运行。 _ (double,double) main() double x,y; scanf(“%lf%lf“,第6章 函数,6.6 典型试题详解,4以下程序的输出结果是_。 t(int x,int y,int cp,int dp) cp=x*x+y*y; dp=x*x-y*y; main() int a=4,b=3,c=5,d=6; t(a,b,c,d); printf(“%d %d n“,c,d); 正确答案:5 6(知识点:函数的调用、参数传递) 试题分析:当执行t(a,b,c,d);调用函数t时,将实参a、b、c、d的值传递给形参x、y、cp、dp,在函数t中对cp、dp进行计算,改变了形参cp、dp的值,但并没有改变对应实参c、d的值(即形参的值不带回给实参),因此返回后,实参c、d的值不变。,第6章 函数,6.6 典型试题详解,5有以下函数定义: void fun(int n,double x) 若以下选项中的变量都已经正确定义且赋值,则对函数fun的正确调用语句是_。 A)fun(int y,double m); B)k=fun(10,12.5); C)fun(x,n); D)void fun(n,x); 正确答案:C(知识点:函数的调用) 试题分析:当函数类型为void时,函数不返回值,函数调用只能以函数语句的形式出现,因此,选项B显然是不对的。在函数调用时,只须给出函数名和实际参数,不能再给出函数类型和参数类型,所以选项A和选项D都不对。正确的选项是C。,第6章 函数,6.6 典型试题详解,6有以下程序: int f(int n) if(n= =1) return 1; else return f(n-1)+1; main() int i,j=0; for(i=1;i3;i+) j+=f(i);
温馨提示
- 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
- 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
- 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
- 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
- 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
- 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
- 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。
最新文档
- 阳光家园委托协议书
- 车辆保单转让协议书
- 酒厂股份合作协议书
- 高层年度分红协议书
- 雪糕生意转让协议书
- 餐饮机器转让协议书
- 通讯施工安全协议书
- 车辆有偿借用协议书
- 设备制造技术协议书
- 酒店预订年会协议书
- 安全周例会汇报模板、安全汇报模板
- 矿产资源规划编制工作方案(示范文本)
- GB/T 7159-1987电气技术中的文字符号制订通则
- GB/T 3934-2003普通螺纹量规技术条件
- 尿动力学检查操作指南2023版
- 行政事业单位无形资产管理办法模板
- 建筑施工企业安全生产条件检查表
- 煤化工工艺学教材课件汇总完整版ppt全套课件最全教学教程整本书电子教案全书教案课件合集
- 银行全国科技周活动宣传总结
- SCL-90量表详细
- 公路工程项目环境保护措施及其可行性论证
评论
0/150
提交评论