C语言函数的定义和使用(附带实例)
函数是指一段可以直接被程序或代码引用的程序或代码,也叫作子程序。
一个较大的程序一般应分为若干个程序块,每一个程序块用来实现一个特定的功能。所有的高级语言中都有子程序这个概念,用子程序实现程序块的功能。
在 C语言中,子程序是由一个主函数和若干个子函数构成的。主函数调用子函数,子函数也可以互相调用。同一个函数可以被一个或多个函数调用任意次。
在程序设计中,一般会将一些常用的程序块编写成函数,放在函数库中供公共使用。用户可以利用这些函数,以减少重复编写程序块的工作量。
C 语言中函数定义的一般形式如下:
被调用的函数执行已定义的任务,当函数的返回语句被执行时,或到达函数的结束括号时,会把程序控制权交还给主程序。
调用函数时,主程序传递所需参数,如果函数有返回值,则可以将返回值传给调用它的主程序。
形式参数就像函数内的其他局部变量,在进入函数时被创建,退出函数时被销毁。
默认情况下,C 程序使用传值调用来传递参数(只将主程序中的变量值传递过去,不改变主程序的变量)。
形参未被调用时,不占存储单元。形参只在调用过程中占用存储单元。
实际参数(简称实参)有确定的值,在调用函数的过程中,实参将值赋给形参。简而言之,在函数定义中,函数首部的参数叫形参,调用函数时使用的参数叫实参,二者之间的区别和联系如下:
当调用函数时,有两种向函数传递参数的方式,如下表所示。
【实例 1】交换函数中两个整数的值(将两个整数通过第三个临时变量进行交换)。
关于如何在子函数中引用调用函数交换主程序中两个变量的值,我在《C语言指针变量作为函数参数》一文中做了详细的讲解。
在实例中,函数声明和定义都在主程序上方;函数声明也可以在主程序中,然后在主程序结束之后再进行定义;或者在主程序上方声明,然后在主程序结束之后再进行定义。其中后两种方式的代码如下:
【实例 2】输入 3 个整数,并将最大值输出。
这个程序先输入 3 个整数 i_x、i_y 和 i_z,把 i_x 和 i_y 作为参数传递给函数 GetMax(),获取其中的最大值赋给 i_temp,作为函数返回值,然后返回给主程序的 i_max 变量;再一次调用函数 GetMax(),将 i_z 和 i_max 作为参数传递给函数 GetMax(),将其中的最大值赋给 i_ temp,作为函数返回值,然后返回给主程序的 i_max 变量,最后将 i_max 输出。
一个较大的程序一般应分为若干个程序块,每一个程序块用来实现一个特定的功能。所有的高级语言中都有子程序这个概念,用子程序实现程序块的功能。
在 C语言中,子程序是由一个主函数和若干个子函数构成的。主函数调用子函数,子函数也可以互相调用。同一个函数可以被一个或多个函数调用任意次。
在程序设计中,一般会将一些常用的程序块编写成函数,放在函数库中供公共使用。用户可以利用这些函数,以减少重复编写程序块的工作量。
C语言函数的定义
简单来说,函数是执行一个任务的一组语句。每个 C语言程序都至少有一个函数,即主函数 main()。函数定义告诉编译器函数的返回类型、名称和参数,函数定义提供函数的实际主体。C 语言中函数定义的一般形式如下:
返回值类型 函数名(参数列表) { 函数主体; }下面介绍一个函数的组成部分:
- 返回值:返回值是函数返回的值的数据类型,一个函数可以返回一个值;有些函数执行所需的操作而没有返回值,在这种情况下,返回值类型是 void,即空类型。
- 函数名:函数的实际名称必须符合标识符的规定,函数名和参数列表一起构成了函数签名。
- 参数列表:参数就像是占位符,当函数被调用时,向参数传递一个值,这个值被称为实际参数;参数列表包括参数的类型、顺序、数量;参数是可选的,函数可能不包含参数。
- 函数主体:函数主体是一组定义函数执行任务的语句。
C语言函数的使用
在程序中,当程序调用函数时,程序控制权会转移给被调用的函数。被调用的函数执行已定义的任务,当函数的返回语句被执行时,或到达函数的结束括号时,会把程序控制权交还给主程序。
调用函数时,主程序传递所需参数,如果函数有返回值,则可以将返回值传给调用它的主程序。
1) 函数参数
如果函数要使用参数,则必须声明接受参数值的变量,这些变量称为函数的形式参数。形式参数就像函数内的其他局部变量,在进入函数时被创建,退出函数时被销毁。
默认情况下,C 程序使用传值调用来传递参数(只将主程序中的变量值传递过去,不改变主程序的变量)。
2) 形式参数和实际参数
形式参数(简称形参)就是定义函数时的参数表,只是定义了调用函数时参数的个数、类型和用来引用的名字,并没有具体的内容。形参未被调用时,不占存储单元。形参只在调用过程中占用存储单元。
实际参数(简称实参)有确定的值,在调用函数的过程中,实参将值赋给形参。简而言之,在函数定义中,函数首部的参数叫形参,调用函数时使用的参数叫实参,二者之间的区别和联系如下:
- 形参只有在函数被调用时才会分配内存,调用结束后立刻释放内存,所以形参只有在函数内部使用才有效,不能在函数外部使用。
- 实参可以是常量、变量、表达式、函数等,无论实参是何种类型的数据,在进行函数调用时,它们都必须有确定的值,以便把这些值传送给形参,所以应该提前用赋值、输入等办法使实参获得确定的值。
- 实参和形参在数量上、类型上、顺序上必须严格一致,否则会出现“类型不匹配”的错误。当然,如果能够进行自动类型转换,或者进行强制类型转换,那么实参类型也可以不同于形参类型。
- 形参和实参虽然可以同名,但它们之间是相互独立的,互不影响,因为实参在函数外部有效,而形参在函数内部有效。例如,在下面的实例 1 中,主程序与函数中都有 i_a 和 i_b 两个变量,但它们相互独立,互不影响。
当调用函数时,有两种向函数传递参数的方式,如下表所示。
调用类型 | 描述 |
---|---|
传值调用 | 将实参的值赋给函数的形参,修改函数内的形参不会影响实参(主程序中的变量) |
引用调用 | 通过指针传递方式,形参为指向主程序中实参的地址,当对形参进行操作时,就相当于对实参本身进行操作(等同于对主程序中的变量进行操作)。 |
【实例 1】交换函数中两个整数的值(将两个整数通过第三个临时变量进行交换)。
#include <stdio.h> void swap(int i_a, int i_b) /*函数定义*/ { int temp; temp = i_a; /*保存地址 i_a 的值*/ i_a = i_b; /*把 i_b 赋值给 i_a*/ i_b = temp; /*把 temp 赋值给 i_b*/ return; //该函数无返回值 } int main () { int i_a = 100; int i_b = 200; printf("交换前i_a, i_b 的值: %d, %d\n", i_a, i_b); swap(i_a, i_b); /*调用函数交换值*/ printf("交换后i_a, i_b 的值: %d, %d\n", i_a, i_b); return 0; //也可以写成return (0),即()可省 }编译运行,结果如下:
交换前i_a, i_b 的值: 100,200
交换后i_a, i_b 的值: 100,200
关于如何在子函数中引用调用函数交换主程序中两个变量的值,我在《C语言指针变量作为函数参数》一文中做了详细的讲解。
在实例中,函数声明和定义都在主程序上方;函数声明也可以在主程序中,然后在主程序结束之后再进行定义;或者在主程序上方声明,然后在主程序结束之后再进行定义。其中后两种方式的代码如下:
#include <stdio.h> int main () { int i_a = 100; int i_b = 200; void swap(int i_a, int i_b); //只声明不定义 printf("交换前i_a, i_b 的值: %d, %d\n", i_a, i_b); swap(i_a, i_b); /* 调用函数交换值*/ printf("交换后i_a, i_b 的值: %d,%d\n", i_a, i_b); return 0; } void swap(int i_a, int i_b) /*函数定义*/ { int temp; temp = i_a; /*保存地址 i_a 的值*/ i_a = i_b; /*把 i_b 赋值给 i_a*/ i_b = temp; /*把 temp 赋值给 i_b*/ return; //该函数无返回值 }或者如下:
#include <stdio.h> void swap(int i_a , int i_b); //只声明不定义 int main () { int i_a = 100; int i_b = 200; printf("交换前i_a, i_b 的值: %d, %d\n", i_a, i_b); swap(i_a, i_b); /*调用函数交换值*/ printf("交换后i_a, i_b 的值: %d, %d\n", i_a, i_b); return 0; } void swap(int i_a, int i_b) /*函数定义*/ { int temp; temp = i_a; /*保存地址 i_a 的值*/ i_a = i_b; /*把 i_b 赋值给 i_a*/ i_b = temp; /*把 temp 赋值给 i_b*/ return; //该函数无返回值 }
【实例 2】输入 3 个整数,并将最大值输出。
这个程序先输入 3 个整数 i_x、i_y 和 i_z,把 i_x 和 i_y 作为参数传递给函数 GetMax(),获取其中的最大值赋给 i_temp,作为函数返回值,然后返回给主程序的 i_max 变量;再一次调用函数 GetMax(),将 i_z 和 i_max 作为参数传递给函数 GetMax(),将其中的最大值赋给 i_ temp,作为函数返回值,然后返回给主程序的 i_max 变量,最后将 i_max 输出。
#include <stdio.h> int GetMax(int i_x, int i_y) //获取二者中的最大值 { int i_temp; (a>b)?(i_ temp = i_x):(i_ temp = i_y); //三目运算,将最大值赋给i_temp return i_ temp; } int main(){ int i_x, i_y, i_z, i_max; printf("请输入三个数字(空格分隔):"); scanf("%d%d%d", &i_x, &i_y, &i_z); i_max=GetMax(i_x, i_y); //调用函数 i_max=GetMax(i_z, i_max); //再次调用函数 printf("最大数为: %d \n", i_max); return 0; }编译运行,结果如下:
请输入三个数字(空格分隔): 1 22 11
最大数为: 22