1、函数调用模型
先来分析分析函数的调用模型:
void changenum(int *mynum)
{
*mynum = 300;
}
int main()
{
int num = 10;
changenum(&num);
printf("%d \n", num);
}
上述代码,是通过调用一个函数修改了num的值。用内存四区模型画出来如下图:
从上图可以看出红色部分是调用函数时的模型。
m
y
n
u
m
mynum
mynum入栈在里面可以打印这个
m
y
n
u
m
mynum
mynum,函数结束时自动释放。
2、再来看一下递归的简单的示例代码
void Inverse(char *str1, char *str2)
{
if (str1 == NULL || str2 == NULL)//递归调用异常结束条件
{
return;
}
if (*str1 == '\0')//递归调用结束条件
{
return;
}
Inverse(str1 + 1, str2);
printf("out ");// 运行,可以清晰的看出嵌套了几层
strncat(str2, str1,1);//将str1中1个字符拷贝并追加到str2后面
}
int main()
{
char *buf = "abcde";
char buf2[32] = { 0 };//这里全部初始化为0,这样我们只需要往buf2
//中拷贝字符即可,不用担心在其尾部手动添加一个'\0'
Inverse(buf,buf2);
printf("\ninverse buf: %s \n", buf2);
return 0;
}
3、递归函数的入栈模型和嵌套调用返回流程
画出上面递归程序的入栈模型如上图(只画到了两层嵌套)。
我们可以看到第一次调用递归函数,入栈的是
a
a
a的地址,将来在这一层复制字符到
s
t
r
2
str2
str2后面的话,那就是
a
a
a。由于递归条件是入栈字符为‘\0’,所以上述模型会入栈6次。可以看打印
o
u
t
out
out的次数(
o
u
t
out
out应该是5次,因为最后一次入栈达到退出条件了,没有机会打印
o
u
t
out
out)
整个入栈出栈模型如下图所示: