Advertisement

【C语言】函数相关基础知识

阅读量:

函数的调用,有调用者和被调用者,其中main函数只能是调用者,函数之间可以相互调用,也可在函数中调用另一个函数,层层下去,这个叫函数的嵌套,但是注意,函数不支持函数的嵌套定义,只可嵌套调用。

1、函数的嵌套:

函数嵌套有内部原理知识,假设有个main函数,里面调用一个函数,此函数中再调用一个函数,在这个被调用的函数中再调用一个函数,形成嵌套,这就是函数的嵌套。

我们知道,程序都是在内存上运行,函数实现的功能代码都去一段对应的内存上运行,每一个函数都占一个内存空间,函数名相当于是函数的入口地址,输入函数名进入该函数,接收到返回值结束函数,pc program counter 程序计数器,是一种寄存器,寄存器直接跟cpu打交道,从主函数跳到别的函数时,cpu会保存现场,再返回时会恢复现场,那么如何保存现场呢?用了一种很巧妙的结构,栈,栈的本质是内存上一段空间,栈的特点是先进后出,从结构上来说,划分为栈底和栈顶,栈顶指向有效数据,保存现场用了栈这种结构普,入栈,出栈,保护现场就是把main函数相关数据压进栈中,调用函数相当于把函数中的数据再压进栈中,所以程序按顺序执行,出栈,入栈,栈的先进后出的特点保证了先进的最后执行,所以实现了由主函数开始的对函数的层层调用。 栈帧;

1、1栈

一种数据结构,表示数的组织形式。
特点,先进后出 (First In Last Out)
C语言角度的栈本质是一块内存空间,只是按照栈这种数据结构来处理和使用的
栈上的变量是局部变量,?自动申请,自动变量。
c语言程序把内存划分了五个区域:
栈:主要用来存放自动变量或函数调用的数据,默认是8兆,可以修改
堆:空间大 ,堆上的空间手动申请,手动释放;
字符串常量区:“hello”,这块区域只读,不可修改
静态区(全局区):全局变量和静态变量,不初始化默认初始化成0;
代码区:只读的
程序 = 代码+数据
修改:一定命令 or 内核

函数层层嵌套调用中,有一种特殊的嵌套调用:递归(递推 ---递推结束的条件 ---回归)
递归:(类似循环)运行到最后会栈崩溃,有时候会说递归是一种特殊的循环;
直接递归,间接递归(最后要调到自己),记得判断要不要加函数声明

递归思路:求问题n,依赖于问题n-1的解决;
举例:求前100的和:
1、用到函数,实现前100项的和;
2、求前99项的和 +100
3、……

复制代码
 #include <stdio.h>

    
  
    
 int sum(int n)
    
 {
    
 	if (n == 1)
    
 	{
    
 		return 1;
    
 	}else 
    
 	{
    
 		return sum(n-1) + n;
    
 	}
    
 }
    
    
    
    

递归代码实现思路:(找每一次的结果)
1、递推关系
2、递推结束的条件
这一次调用的结果 = 这一次的值

练习:求n项的阶乘;
阶乘:前第n-1项的结果乘第n项;所以前第n-1项需要作为返回的结果,然后*n;

复制代码
 int factorial(int n)

    
 {
    
 	if (n == 1)
    
 	{
    
 		return 1;
    
 	}else 
    
 	{
    
 		return factorial(n-1) * n;
    
 	}
    
 }
    
    
    
    

练习:求斐波那契数列第n项的值

复制代码
 int fibo(int n)

    
 {
    
 	if (n == 1 || n == 2)
    
 	{
    
 		return 1;
    
 	}else 
    
 	{
    
 		return fibo(n-1) + fibo(n-2);
    
 	}
    
 }
    
    
    
    

数组作为函数参数:
1、数组元素作为函数参数;
2、数组本身作为函数参数;

2、一维整型数组做函数参数

形参: ---写成数组形式 (int a[ ]) 还需要数组长度 len
实参 :---数组名(不加[ ]),数组长度
代码举例:

复制代码
 //写成函数形式

    
 void array(int a[],int len) //
    
  
    
 //主函数中调用形式
    
 array(a,len)
    
    
    
    

练习:准备一个数组,实现一个函数,找最大值;

复制代码
 int max(int a[],int len)

    
 {
    
 	int m = a[0];
    
 	int i = 0;
    
 	for(i = 0;i<len ; i++)
    
 	{
    
 		if(m < a[i])
    
 		{
    
 			m = a[i];		
    
 		}
    
 	}
    
 	return m;
    
 }
    
  
    
 int main()
    
 {
    
 	int a[] = {1,2,3,4,5,6,7,8};
    
  
    
 	int len = sizeof(a) / sizeof(a[0]); 
    
 	
    
 	printf("%d\n",max(a,len));
    
  
    
 }
    
    
    
    

3、一维字符型数组做函数参数

一维字符型数组,主要作用是处理字符串。
因为处理的是字符串数据,字符串操作的依据是‘\0’
注意:不需要传长度
一维字符型数组做函数参数
形参 数组形式
实参 数组名

4、二维数组做函数参数

总结:
形参 --- 二维数组形式 + 行数 //本质 一维数组 + 长度
实参 --- 数组名 + 行数 //

举例:实现一个函数,求二维数组元素的和 :

复制代码
 int sumOfArray(int a[][4],int row)

    
 {
    
 	int i = 0;
    
 	int j = 0;
    
 	int sum = 0;
    
  
    
 	for (i = 0; i < row; ++i)
    
 	{
    
 		for (j = 0; j < 4; ++j)
    
 		{
    
 			sum = sum + a[i][j];
    
 		}
    
 	}
    
  
    
 	return sum;
    
 }
    
    
    
    

找出二维数组中主对角上最大值:

复制代码
 int maxOfArray(int a[][4],int row)

    
 {
    
 	int i = 0;
    
 	int j = 0;
    
 	int max = a[0][0];
    
  
    
 	for (i = 0; i < row; ++i)
    
 	{
    
 		for (j = 0; j < 4; ++j)
    
 		{
    
 			if (i==j && a[i][j] > max )
    
 			{
    
 				max = a[i][j];
    
 			}
    
 		}
    
 	}
    
  
    
 	return max;
    
  
    
 }
    
    
    
    

5、二维字符数组做函数参数:

与二维整型数组 使用方式相同
形参 --- 二维数组形式 + 行数 //本质 一维数组 + 长度
实参 --- 数组名 + 行数 //
举例:
实现一个输入多个字符串函数 inputStr()

复制代码
 void inputStr(char (*s)[10],int row)

    
 {
    
 	int i = 0;
    
  
    
 	for (i = 0; i < row; ++i)
    
 	{
    
 		gets(s[i]);
    
 	}
    
  
    
 }
    
    
    
    

全部评论 (0)

还没有任何评论哟~