C/汇编学习(四)


学习内容:

1、函数如何调用自己头文件的声明:

给头文件添加新建项,在该项目中添加自己所需要的头文件,然后在源文件中调用自己的头文件的声明:#include"entry.h"

2、使用指针在函数中可以实现多个值的返回

3、递归函数

函数自己调用自己

4、如何解决课后练习01中程序中栈溢出问题

递归函数的优点是定义简单,逻辑清晰。理论上,所有的递归函数都可以写成循环的方式,但循环的逻辑不如递归清晰。使用递归函数需要注意防止栈溢出。在计算机中,函数调用是通过栈(stack)这种数据结构实现的,每当进入一个函数调用,栈就会加一层栈帧,每当函数返回,栈就会减一层栈帧。由于栈的大小不是无限的,所以,递归调用的次数过多,会导致栈溢出。可以试试factorial(1000)。

解决递归调用栈溢出的方法是通过尾递归优化,事实上尾递归和循环的效果是一样的,所以,把循环看成是一种特殊的尾递归函数也是可以的。尾递归是指,在函数返回的时候,调用自身本身,并且,return语句不能包含表达式。这样,编译器或者解释器就可以把尾递归做优化,使递归本身无论调用多少次,都只占用一个栈帧,不会出现栈溢出的情况。

函数属性页→配置属性→链接器→系统→栈堆保留大小

将栈堆保留大小改为52428800即可

5、#include<stdarg.h>

stdarg.h是C语言中C标准函数库的头文件,stdarg是由standard(标准) arguments(参数)简化而来,主要目的为让函数能够接收可变参数。C++的cstdarg头文件中也提供这样的功能;虽然与C的头文件是兼容的,但是也有冲突存在。

VA_LIST 是在C语言中解决变参问题的一组宏,所在头文件:#include <stdarg.h>,用于获取不确定个数的参数

va_start,函数名称,读取可变参数的过程其实就是在堆栈中,使用指针,遍历堆栈段中的参数列表,从低地址到高地址一个一个地把参数内容读出来的过程·


学习产出:

课后练习:
01. 编写一个函数,使用递归打印0 - 10000之间所有的偶数(不得使用循环)

第一种实现(有bug,解决方法在学习内容中):

#include"entry.h"

int Print_Oushu(int a)
{
    if (a == 0)
    {
        return 0;
    }
    if ((a%2) == 0)
    {
        printf("%d\n", a);
    }
    Print_Oushu(a - 2);
}

int main()
{
    Print_Oushu(10000);
    system("pause");
    return 0;
}

第二种实现:

#include"entry.h"

int Print_Oushu(int a)
{
    if (a == 0)
    {
        return 0;
    }
    if ((a%2) == 0)
    {
        printf("%d\n", a);
        printf("%d\n", a - 2);
    }
    Print_Oushu(a - 4);
}

int main()
{
    Print_Oushu(10000);
    system("pause");
    return 0;
}


02. 编写一个函数,使用变参函数,根据参数多少,决定打印内容

#include<stdio.h>
#include<stdlib.h>
#include<stdarg.h>

void PrintAdd(int a, ...)
{
    int result = 0;
    va_list v1;
    va_start(v1, a);
    for (int i = 0; i < a; i++)
    {
        result += va_arg(v1, int);
    }
    printf("%d\n", result);
    va_end(v1);
}

int main()
{
    PrintAdd(4, 10, 10, 20, 10);
    system("pause");
    return 0;
}

03. 编写一个函数,使用指针遍历打印一个二维数组

#include<stdio.h>
#include<stdlib.h>
#include<stdarg.h>

int main()
{
    int a[2][5] = { { 1,2,3,4,5 },{ 5,4,3,2,1 } };
    int(*p)[5];
    int i, j;
    p = a;
    for (i = 0; i < 2; i++)
    {
        for (j = 0; j < 5; j++)
        {
            printf("%d\n", *(p[i] + j));
        }
    }
    system("pause");
    return 0;
}


04. 编写一个函数,使用一个二维数组作为参数,打印其中最大的值,并且打印该值处于哪个一维数组中
05. 编写一个函数,参数是一维数组,把这个数组中的元素倒叙存储到原数组中
06. 编写一个函数,对一个9 * 9的二维数组进行初始化,并且打印其中的值(使用循环顺序赋值)
07. 编写一个函数,对上一题中的二维数组进行运算,得出加法和乘法的结果
08. 编写一个函数,让用户输入10个数字,存储到一个数组中,然后按大小对这个数组进行排序
09. 把数组排序功能通过指针实现
10.使用指针判断两个字符串是否相同

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值