C--四、函数

本文介绍了函数在编程中的重要性,包括解决复杂程序结构、封装功能、C语言的先定义后使用原则,以及函数的分类(按返回值、定义者和参数)、调用过程、递归示例、数组和二维数组作为参数的处理。
摘要由CSDN通过智能技术生成

问题引入:为什么要使用函数

如果程序的功能比较多,规模比较大,把所有的程序代码都写在main函数中,就会使主函数变得庞杂、头绪不清,使阅读和维护程序变得困难。此外,有时程序中要多次实现某一功能,就需要多次重复编写实现此功能的程序代码。这使程序冗长,不精练。而函数可以解决这些问题

函数的定义与使用

函数调用的目的:通过调用函数获得某些结果

函数强调的是功能性的封装,供调用者使用来改变调用者当中的一些数据

先定义后使用

C语言要求,在程序中用到的所有函数,必须“先定义,后使用”。

函数要素

  1. 函数名
    做到见名知意。别人阅读更加方便。
  2. 参数列表
    如:void demo(int x);x就是形参。
    参数列表根据具体函数所实现的功能进行分析。
  3. 返回值
    根据具体函数所实现的功能进行分析
    值包括:void(表示不返回值)或具体数据类型
  4. 函数体:
    实现函数功能的代码

函数分类

(1)根据返回值类型:

  1. 有返回值类型(需要在函数中加入return关键字)
  2. 没有返回值类型

​ (2)根据谁定义分类

  1. 库函数
  2. 自定义函数
  3. 系统调用

(3)从参数角度分类

  1. 有参函数
  2. 无参函数(可以在参数列表位置写void也可以什么都不写)

形参与实参

  1. 形参: 形参全称叫做“形式参数”,我们在定义函数的时候,其中参数列表位置的参数就是形参。
  2. 实参: 实参全称叫做“实际参数”。实参可以是常量、变量、表达式、类等,实参必须要有确定的值

函数的调用过程

  1. 内存分配:在为调用函数之前,不会为此函数分配内存空间,在调用之后才会分配内存给函数。
  2. 值传递:调用处,把函数所需的值通过实参传递给形参。如果没有就不传递。
  3. 值返回:函数通过return语句返回值。如果声明时返回值处void就不用返回。
  4. 内存释放:在值返回之后会将此函数的内存空间清除。形参的值再次不占用内存空间。
函数调用的条件
  1. 函数已被定义
  2. 调用库函数(使用#include 导入)
  3. 函数的声明:如果使用用户自己定义的函数,而该函数的位置在调用它的函数(即主调函数)的后面(在同一个文件中),应该在主调函数中对被调用的函数作声明(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;
}

数组作为函数的参数

首先明确,数组作为函数的参数是值传递
与普通参数的值传递的异同:

相同点:都是值传递。
不同点:
  1. 由于数组名内保存的数组的首地址,所以其传递是地址。
  2. 函数调用的数组会对本身的数组造成影响,这点和普通参数的值传递是不同的
数组作为函数参数详解:

形参中不存在数组的概念,即使声明一个数组的大小,也无效。
看以下代码

#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;
}
  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值