【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]);
	}

}


   

  • 12
    点赞
  • 14
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值