函数的递归

        简而言之,函数的递归就是自己用自己(如果你了解科赫雪花的迭代或许能更好理解)。

以求1加到100为例。

#include <stdio.h>

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

int main()
{
    printf("%d\n", sum(100));
}

        该函数sum()便反复调用自身

函数调用的深入理解

数据结构——栈

        为保证函数调用的正常运行,计算机会开辟新空间,记录调用前函数的位置,与缓存区空间的队列先进先出的特点不同,其特点为先进后出,即入栈和出栈。

以如下函数为例

        当开始运行f1时,需要调用f1,而为了防止调用函数f1后无法回到main函数中,需要把main的地址保存下来,即入栈,所以此时在栈的最底层则是main的位置,此过程也被称为保护现场,而同理,f1和f2也接连入栈,于是在出栈时,顺序便是f2,f1,main,此过程也被称为恢复现场。Linux系统栈区内存大小为8G,Windows为1G

        综上,在c语言运行之前,必须开辟出来栈的空间,即栈区。其实栈区内不光保存了返回函数的地址,局部变量,包括函数的形参这些空间也是包含在其中。函数调用本质是指令跳转,会调用栈区空间,如果栈区空间沾满导致程序崩溃

        不仅栈区,一个应用程序在应用过程中,还存在另外四个区,如下

        功能: 

                堆区:必须向操作系统申请,用完就还

                字符串常量区:存放字符串常量的,即双引号内“”

                代码区:存放代码。字符常量也在其中

                静态区:函数内的静态局部变量及函数外的全局变量

                例:char s[10] = "Hello"        其中s在栈区,“Hello”在字符串常量区

函数的传参

 传递方式——值传递      

        在c语言中,函数传参都是以值传递的方式,只是将实参的值传递给形参,而并没有把实参本身传递给形参,以以下代码为例。

         输出i的值为20而并非30。因为在对形参n开辟空间时,用实参i来对n进行初始化,然后对n进行操作,根本不改变i的值,即无法在被调函数里修改主调,而能改变的是指针传参

传参方向——自右向左

        当函数有两个及以上参数时,传参时先传右侧,再传左侧,以以下代码为例。

        先输出10,再输出20,最后输出30。 

        在此期间,禁止使用同一变量的自增自减(如下),否则结果不确定

数组作为函数参数

        数组作为函数参数时,需要传两个参数,一个是数组名,一个是数组元素的个数,以计算数组内数总和为例。

         形参数组a[]可以不指定大小,因为c语言编译只将实参首元素地址传递给形参。

        应该强调的是,用数组名作为函数实参时,并不是把数组元素的值传递给形参,而是把实参数组的首元素地址传递给形参数组,这样两个数组就攻占同一段内存单元,所以当改变其中一个的值时,另一个也会随之改变,也就是说,形参数组中各元素的值如果发生变化,会使得实参数组的值同时发生变化。

        例:求数列中最大值函数

#include <stdio.h>

int max(int a[], int len)
{
    int max = a[0];
    for(int i = 1; i < len; ++i)
    {
        if(max < a[i])
        {
            max = a[i];
        }
    }
    return max;
}

int main()
{
    int a[] = {13,5,152,853,12,56,123};
    printf("%d\n", max(a, 7));
}

各种string类型函数的拆分

strcpy
strlen

strcmp 
strcat 

二维数组

        我们已经知道,二维数组可以看作多个一维数组组成,所以可以试着采用一维数组的方式。

        二维数组作为形参时,第二维也就是列数是固定的,也就是说,在二维数组函数中,需要给出二维数组的行数,但是由于列数是固定的,所以在函数中包括循环终止等操作可以以固定的数位基准,虽然可以通过sizeof得出列数,但是完全没有必要。

        例:求出二维数组边界总和

#include <stdio.h>

int sums(int a[][4], int rows)
{
    int sums = 0;
    for(int i = 0; i < rows; ++i)
    {
        for(int j = 0; j < 4; ++j)
        {
            if(i == 0 || i == rows - 1 || j == 0 || j == 3)
            {
                sums  += a[i][j];
            }
        }
    }
    return sums;
}


int main()
{
    int a[][4] = {1,2,3,4,5,6,7,8,9,10,11,12,13,14};
    int rows = sizeof(a) / sizeof(a[0]);
    printf("%d\n", sums(a, rows));
}

Logo

有“AI”的1024 = 2048,欢迎大家加入2048 AI社区

更多推荐