问题引入:为什么要使用函数
如果程序的功能比较多,规模比较大,把所有的程序代码都写在main函数中,就会使主函数变得庞杂、头绪不清,使阅读和维护程序变得困难。此外,有时程序中要多次实现某一功能,就需要多次重复编写实现此功能的程序代码。这使程序冗长,不精练。而函数可以解决这些问题
函数的定义与使用
函数调用的目的:通过调用函数获得某些结果
函数强调的是功能性的封装,供调用者使用来改变调用者当中的一些数据
先定义后使用
C语言要求,在程序中用到的所有函数,必须“先定义,后使用”。
函数要素
- 函数名
做到见名知意。别人阅读更加方便。 - 参数列表
如:void demo(int x);x就是形参。
参数列表根据具体函数所实现的功能进行分析。 - 返回值
根据具体函数所实现的功能进行分析
值包括:void(表示不返回值)或具体数据类型 - 函数体:
实现函数功能的代码
函数分类
(1)根据返回值类型:
- 有返回值类型(需要在函数中加入return关键字)
- 没有返回值类型
(2)根据谁定义分类
- 库函数
- 自定义函数
- 系统调用
(3)从参数角度分类
- 有参函数
- 无参函数(可以在参数列表位置写void也可以什么都不写)
形参与实参
- 形参: 形参全称叫做“形式参数”,我们在定义函数的时候,其中参数列表位置的参数就是形参。
- 实参: 实参全称叫做“实际参数”。实参可以是常量、变量、表达式、类等,实参必须要有确定的值
函数的调用过程
- 内存分配:在为调用函数之前,不会为此函数分配内存空间,在调用之后才会分配内存给函数。
- 值传递:调用处,把函数所需的值通过实参传递给形参。如果没有就不传递。
- 值返回:函数通过return语句返回值。如果声明时返回值处void就不用返回。
- 内存释放:在值返回之后会将此函数的内存空间清除。形参的值再次不占用内存空间。
函数调用的条件
- 函数已被定义
- 调用库函数(使用#include 导入)
- 函数的声明:如果使用用户自己定义的函数,而该函数的位置在调用它的函数(即主调函数)的后面(在同一个文件中),应该在主调函数中对被调用的函数作声明(declaration)。声明的作用是把函数名,函数参数的个数和参数类型等信息通知编译系统,以便在遇到函数调用时,编译系统能正确识别函数并检查调用是否合法。在前面的例子中已出现过对被调用函数的声明,下面再作进一步的说明。
函数的递归
递归案例:
求n!
#include <stdio.h>
/*
求 n!阶乘
*/
int getFactorial(int n){
if(n >= 17){
puts("越界");
return -1;
}
if(n < 0){
printf("数据错误!\n");
return -1;
}
if(n == 0){
return 1;
}
if(n == 1){
return 1;
}
return n * getFactorial(n-1);
}
int main(){
int n;
int result;
puts("输入求多少的阶乘:");
scanf("%d",&n);
result = getFactorial(n);
printf("result = %d",result);
return 0;
}
数组作为函数的参数
首先明确,数组作为函数的参数是值传递。
与普通参数的值传递的异同:
相同点:都是值传递。
不同点:
- 由于数组名内保存的数组的首地址,所以其传递是地址。
- 函数调用的数组会对本身的数组造成影响,这点和普通参数的值传递是不同的
数组作为函数参数详解:
形参中不存在数组的概念,即使声明一个数组的大小,也无效。
看以下代码
#include <stdio.h>
void printData(int arr[],int size){
//os中用8个字节来表示一个地址
printf("arr = %d\n",sizeof(arr));//arr = 8
}
int main(){
int arr[10] = {1,3,231,21,311,313};
int size = sizeof(arr)/sizeof(int);
printf("arr = %d\n",sizeof(arr));//arr = 40
//数组名和第一个元素的地址都代表数组的首地址
printData(arr,10);
printData(&arr[0],10);
}
ps:在main函数使用sizeof得到arr的实际字节数为40,但是在printData函数中其值为8。而我使用的os中用8个字节来表示一个地址,也印证了上文高亮的话。
二维数组作为函数的参数
正确的写法:int arr[][3],int arr[2][3]
错误的:int arr[][],int arr[2][] --> type of formal parameter 1 is incomplete
–>error:declaration of ‘arr’ as multidimensional array must have bounds for all dimensions except the first
#include <stdio.h>
void printDoubleArray(int arr[][3],int row,int column){
int i,j;
for(i =0;i<row;i++){
for(j = 0;j < column;j++){
printf("%d ",arr[i][j]);
}
}
}
int main(){
int arr[2][3] = {{1,2,3},{11,22,33}};
printDoubleArray(arr,2,3);
return 0;
}