自学嵌入式第十天C语言篇9

目录

函数实现的原理

栈 

函数调用的关系:

        特殊的嵌套调用:递归关系——自己调用自己。

数组作为函数的参数

函数实现的原理

         代码都要被翻译成机器指令,这些指令在内存中跑起来,每个函数在内存上都有自己的空间,这些指令在内存中都只存了一份,不论被调用多少次,只是将值传入相应空间完成数据处理或者相应指令。

        函数名代表函数的入口地址。

        函数调用的本质:利用栈的结构——先进后出(FILO),保证了函数可以层层嵌套调用。

        计算机在调用函数时,会将当前函数的环境保存起来(保存现场),然后将控制权转交给被调用的函数。被调用的函数执行完毕后,会将控制权交还给保存的环境(还原现场),继续执行后续的指令。 

 

栈 

        栈:是一种数据结构——表示数据组织形式,特点为先进后出(FILO)。

        C语言角度的栈:它的本质还是一块内存空间,只是按照栈这种数据结构来处理和使用

        补充:C语言程序把内存划分成5个区域:栈、堆、字符串常量区、静态区(全局区)、代码区。 

                栈:主要用来存放自动变量或者函数调用的数据。linux系统中栈的大小默认为8Mb,可以修改。

                堆:空间大,堆上的空间使用时需要手动申请,手动释放。

                字符串常量区:该区域只读,不可修改。

                静态区:存放全局变量和静态变量

                代码区:只读,不可修改

 

函数调用的关系:

        1.调用者:使用另一个函数的函数。

        2.被调用者:被另一个函数使用的函数。

//main是调用者
//main函数是整个程序的入口,只能是调用者
int main()
{
    int s[10];
    
    //sizeof在此处是被调用者
    printf("%d\n",sizeof(s));

    return 0;
}

//函数不支持嵌套定义,但是支持嵌套调用。

        特殊的嵌套调用:递归关系——自己调用自己。

                1.直接递归:函数直接调用函数本身;

                2.间接递归:函数本身不调用自己,但是调用别的函数时,别的函数掉用来自己。

                递归和循环类似,是一种特殊的循环

                因为栈的大小是有限的,递归在使用时,如果递退下去的时候没有找到停止的条件或者调用自己太多次,栈中存不下多次调用函数的环境参数,栈就会崩溃,使得程序发生段错误。 

                思想:想要求问题n,需要先求出n-1的结果,直到推到结束条件,然后回归。

                实现思路先考虑递推关系,如何从问题n到问题n-1;然后考虑递推结束的条件;

                实列: 求解n的阶乘

                        先将问题往前看,要算n的阶乘,只需要知道n-1的阶乘然后乘以n,在往前看,现在是要求n-1的阶乘,只需要知道n-2的阶乘再乘以n-1,……最后求到0的阶乘,就是1,就可以往后走了

#include <stdio.h>

int factorial(int n)
{
    int ret;

    //0的阶乘为1,求解到此时,就可以回归了,往上依次求出1、2、3、……、n的阶乘
    if (n == 0)
    {
        ret = 1;
    }
    else
    {
        //要求n的阶乘,可以递推成用n-1的阶乘乘以当前的n
        ret = factorial(n-1) * n;
    }   

    return ret;
}

int main()
{
    int n,f;

    printf("input a num:");
    scanf("%d",&n);

    f = factorial(n);

    printf("%d! = %d\n",n,f);

    return 0;
}

数组作为函数的参数

#include <stdio.h>

//打印整个数组的值
void printArray(int a[],int len)
{
    int i;
    
    for (i = 0;i < len;i++)
    {
        printf("%d\n",a[i]);
    }

    return;
}

//给数组循环赋值
void assignment(int a[],int len)
{
    int i;
    for (i = 0;i < len;i++)
    {
        scanf("%d",a[i]);
    }
}

int main()
{
    int n;

    printf("input a num:");
    scanf("%d",&n);

    int a[n];

    assignment(a,n);
    printArray(a,n);

    return 0;
}

                1.一维数组本身做函数参数:形参写成数组形式,形参还需要数组长度,实参写数组名和数组长度,实参传入的是数组的首地址,无法在函数中算出该数组的长度。

                2.一维数组元素作为函数的参数:数组元素作为函数的参数时,相当于同一类型的变量作为参数。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值