辽宁石油化工大学《C语言程序设计》第四章 函数和变量

  • 格式:pdf
  • 大小:124.48 KB
  • 文档页数:27

第4章
函数与变量
· 91 ·
句起作用。如可把例 4.3 中的 max 函数改写成如下形式: max(int x, int y) { if(x>y) return x; else return y; } return 语句中也可以没有选择项 “表达式” , 甚至函数中可以没有 return 语句。 没有 “表 达式”的 return 语句只是将程序的流程返回到调用该函数处;没有 return 语句的函数被调 用用时,程序执行中遇到函数体的结束标志“}”也会将流程返回到调用函数中。 注意(Note) return 语句中没有 “表达式” 或者函数中没有 return 语句并不是说函数就没有返回值, 而是返回一个不确定的函数值。例如将例 4.4 中的 main 函数改写成如下形式: main( ) { int a, b, c; a=function1( ); b=function2( ); c=function1( ); printf("%d, %d, %d\n", a, b, c); } 运行程序时,除了得到和例 4.4 一样的结果外,还可以输出变量 a、b、c 的值,但这 些值不一定有什么实际意义。 为了明确表示函数不返回函数值, 可以用 void 作为该函数的类型说明符, viod 是 C 语 言的关键字,表示“空类型” (或“无类型” ) 。 例如可以将例 4.4 中的 function1 和 function2 函数改为: void function1( ) { printf("********************\n"); } void function2( ) { printf(" This is a C program!\n"); } 这样定义后,系统将禁止 function1 和 function2 函数返回任何值,如果再出现下面的 用法: a=function1( ); b=function2( ); c=function1( ); 编译时系统会给出错误信息。
4.1 函数(Function)
根据结构化程序设计的要求,往往把一个较大的复杂程序分解成若干个较小的、能实 现特定功能的子程序(又称子模块) ,通过对这些子程序的设计来实现整个程序的功能。 C 语言是一种结构化的程序设计语言,在 C 语言中,子程序是由函数来实现的。一个 较为复杂的 C 程序,通常由一个 main 函数和其它若干个函数构成。程序执行时,总是从 main 函数开始,通过 main 函数调用其它函数来实现程序的功能,除 main 函数之外,其它 函数之间也可以相互调用。调用其它函数的函数称调用函数,被其它函数调用的函数称被 调用函数。 C 语言程序中,函数调用的关系可用下图示意。 main
第4章
函数与变量
· 87 ·
的,我们可以直接使用。因此从用户使用的角度来看,C 语言的函数分为两种:库函数和 用户自定义函数。C 语言系统提供了丰富的库函数,对于库函数,用户只要能正确调用就 行了; 用户自定义函数则是用户根据编程的需要, 自行编写的、 用以实现特定功能的函数, 它必须先定义,然后才能使用。C 语言鼓励人们将一些常用的功能模块编写成函数,放到 函数库中供人们公共调用。 采用函数的方法可以简化程序结构, 减少程序重复书写的现象。 比如求 n! ,如果不用函数的方法,则每次求一个数的阶乘都要重新编写相应的程序段;而 采用函数的方法,可以把求 n!的过程定义成一个函数,随时调用。 例 4.1 计算 s=
m =0
∑ m! 并输出每个 m!的值。
n
main( ) { long factorial(int n); /*对要调用的函数 factorial 进行声明*/ int m,n; /*定义局部变量 m、n*/ long s=0; /*定义局部变量 s*/ scanf("%d",&n); /*调用库函数 scanf*/ for(m=0;m<=n;m++) { s=s+factorial(m); /*调用自定义 factorial 函数并作为一个运算对象*/ printf("%d!=%ld\n",m,factorial(m)); /*调用 factorial 函数并作为一个函数参数*/ } printf("s=%ld\n",s); /*调用库函数 printf*/ } long factorial(int n) /*定义函数 factorial 计算一个数 n 的阶乘*/ { int i; /*以下两行定义局部变量 i、jc*/ long jc=1; for(i=1; i<=n; i++) jc=jc*i; return jc; /*将 jc 作为 factorial 的函数值返回到调用用函数中*/ } 运行结果: 5 ↙ 0!=1 1!=1 2!=2 3!=6 4!=24 5!=120 s=154 程序中定义了两个函数,一个是 main 函数,一个是 factorial 函数,在 main 函数中调 用了库函数 scanf、printf 和用户自定义函数 factorial,通过调用库函数 scanf、printf 实现数
第4章
函数与变量
Function and Variable
本 章 概 要 Summary of the chapter C 程序是由函数构成的,掌握函数是掌握 C 语言程序设计的基础。通过本章的学习,应重点掌握函数 定义的格式、函数的调用方法、函数间的数据传递、函数的递归调用、变量的存储类型等内容,了解内部 函数和外部函数的概念,并能解决实际问题。
第4章
函数与变量
· 89 ·
} function2( ) /*定义无参函数 function2*/ { printf(" This is a C program!\n"); } main( ) { function1( ); /*调用无参函数 function1*/ function2( ); /*调用无参函数 function2*/ function1( ); /*调用无参函数 function1*/ } 运行结果: *************************** This is a C program! *************************** function1 函数和 function2 函数都是无参函数, 它们的作用就是完成输出字符串这个特 定的操作。 如果函数定义中选用了形参及其类型说明这一项,则定义的函数称有参函数,有参函 数一般用来完成某种计算并返回一个函数值,如例 4.1 中的 factorial 函数、例 4.2 中的 add 函数和例 4.3 中的 max 函数。在调用有参函数时,调用函数与被调用用函数之间有数据传 递。 4.C 语言规定,在一个函数内不能再定义另外一个函数,即函数不能嵌套定义。所有 函数的地位是平等的, 没有隶属关系, 除了 main 函数外, 函数之间可以相互调用, 即 main 函数只能作为调用函数,不能作为被调用函数。 5. 程序的执行总是从 main 函数开始, 并在 main 函数中结束整个程序的运行, 而不管 它的位置如何。main 函数名是由系统命名的。 6.函数名后面的圆括号是函数的标志,不能省略;函数体的花括号“{ }”则表示函数 体的开始与结束,也不能省略。但花括号“{ }”中可以没有任何内容,即函数体是空的,这 样的函数称空函数。 例如:dump( ) {} 这就是一个空函数。如果这个空函数被调用用,它什么也不做,但它在程序中却占用 一个位置。这在程序开发初期只确定了一些基本功能模块,但还没有编写具体的内容时常 常用到,作为一个虚设的部分,留待以后开发、完善。
· 88 ·
第4章
函数与变量
据的输入和输出,通过调用自定义函数 factorial 实现阶乘的计算。
4.1.1 函数的定义(Definition of Function)
函数必须先定义,然后才能使用。建立函数的过程称为“函数的定义” 。
4.1.1.1 函数的定义格式(Definition form of function)
4.1.1.2 有关函数的说明(Related instruction of function)
1.数据类型说明符是用来说明函数返回值的类型,简称函数类型。 如例 4.2 中定义的 add 函数类型是 float 类型,就是说函数返回值的类型是 float 类型。 这是一个可选项,省略不选时,C 系统默认为 int 类型,但建议初学者不要省略。 例 4.3 定义一个求两个数最大值的函数 max(int x, int y) { int z; if(x>y) z=x; else z=y; return z; } 定义函数 max 时省略了数据类型说明符,系统默认为函数 max 是 int 类型。 2.函数名与形参名都是用户命名的 C 标识符。在同一个程序中,函数名应当唯一;在 同一个函数中,形参名应当唯一。 3.形参名及其类型说明也是可选项。如果省略不选,则定义的函数称无参函数,无参 函数一般用来完成一个特定的操作过程。 如: 例 4.4 无参函数的定义和调用。 function1( ) /*定义无参函数 function1*/ { printf("**********************eturn value of function)
C 语言中,调用有参函数时,一般会从被调用函数中得到一个数据,这个数据是通过 return 语句带回的,称函数的返回值。 return 语句的一般格式为: return 表达式; 或
· 90 ·
第4章
函数与变量
return (表达式) ; return 语句的作用是:将程序的流程返回到调用该函数处,并将“表达式”的值作为 函数的返回值带回到调用函数中。 return 语句后面的“表达式”可以加圆括号,也可以不加圆括号。如例 4.3 中的 return 语句可以写成: return (z); 甚至可以不要变量 z 和 if-else 语句,直接把函数体写成一条语句: return x>y?x:y; 注意(Note) 函数的返回值的类型(即 return 语句中“表达式”的类型)必须与函数定义时所说 明的函数类型一致,如果不一致,则以函数的类型为准。对数值型数据,由系统自动进 行转换;对其它类型,要进行强制转换,这也是我们为什么要在函数定义时指定函数类 型的原因。 如例 4.2 中定义的 add 函数类型为 float 型,函数内 return 语句中表达式 s 的类型也是 float 型,是一致的。但如果它们两者的类型不一致,结果会如何呢? 例 4.5 修改例 4.2 中定义的 add 函数类型并调用 int add(float x, float y) /*将 add 函数的类型改为 int 型*/ { float s; s=x+y; return s; } main( ) { float a, b, c; printf("input two numbers a and b:\n"); scanf("a=%f b=%f", &a, &b); c= add(a, b); /*调用 add 函数*/ printf("sum=%f\n", c); } 运行结果: input two number a and b: a=1.5 b=2.0↙ sum=3.000000 可以看出, 我们只是将例 4.2 中定义的 add 函数的类型由 float 型改为 int 型, 其它没变, 但调用这个函数后, 程序运行的结果已不再是我们想象的值。 因为函数 add 的类型与 return 语句中的 S 的类型不一致,按上述规定,执行 return 语句返回时,以函数 add 的类型为准, 将 S 的实型值 3.5 转换为整型值 3 返回到调用函数 main 中,赋给 float 型变量 c,用%f 格 式输出,结果为 3.000000。 一个函数可以有一个或多个 return 语句,执行到哪一个 return 语句,哪一个 return 语