第九章函数


title: 第九章 函数
author: HardyDragon
tags: C Notes


第九章 函数

  • 函数原型即函数声明,函数调用,函数定义即明确指定函数要做什么。

  • 有些老编译器识别不了void返回值的函数,需要改为int。

  • 如果函数放到其他文件需要导入

  • 局部变量和全局变量

  • 形参和实参

  • return返回值

  • 没有返回值的函数返回类型为void没有参数的函数声明应该使用void关键字。

    void print_name(void);
    
  • 递归:需要有终止递归的条件才不会无限循环。递归方案比较简洁,但是效率没有循环高。

// recur.c -- 递归演示
#include <stdio.h>
void up_and_down(int);
int main(int argc, char const *argv[])
{
    up_and_down(1);
    return 0;
}

void up_and_down(int n)
{
    printf("Level %d: 地址 %p\n", n, &n);
    if (n < 4)
    {
        /* code */
        up_and_down(n + 1);
    }
    printf("LEVEL %d : 地址为 %p\n", n, &n);
}

result:

Level 1: 地址 000000000061FE00
Level 2: 地址 000000000061FDD0
Level 3: 地址 000000000061FDA0
Level 4: 地址 000000000061FD70
LEVEL 4 : 地址为 000000000061FD70
LEVEL 3 : 地址为 000000000061FDA0
LEVEL 2 : 地址为 000000000061FDD0
LEVEL 1 : 地址为 000000000061FE00

每级函数调用都有自己的变量,递归使用的空间比较多的原因。递归返回各级函数的结果顺序安装栈的先进后出的顺序。

  • 尾递归是最简单的递归形式,即将递归函数放在main函数的末尾,即return之前,相当于循环。

    // binary.c -- 以二进制形式打印整数
    #include <stdio.h>
    void to_binary(unsigned long n);
    int main(int argc, char const *argv[])
    {
        unsigned long number;
        printf("enter a num (q to quit):\n");
        while (scanf("%lu", &number) == 1)
        {
            /* code */
            printf("二进制数:");
            to_binary(number);
            putchar('\n');
            printf("enter a num (q to quit):\n");
        }
        printf("Done!\n");
    
        return 0;
    }
    void to_binary(unsigned long n)
    {
        int r;
        r = n % 2;
        if (n >= 2)
        {
            to_binary(n / 2);
        }
        putchar(r == 0 ? '0' : '1');
        return;
    }
    
    

    retuslt:

    enter a num (q to quit):
    3
    二进制数:11
    enter a num (q to quit):
    q
    Done!
    
  • 自己编写头文件,然后使用#include导入即可。一般是放一些#define 和函数声明。或变量

  • &取地址符,&加在变量前就是相当于给变量加了一个* ,* (取值符)放在变量名前相当于给变量名去掉一个 * ; 打印地址的转换说明符是 %p

  • 交换两个变量的值

    temp = x;
    x=y;
    y=temp;
    
    // swap1.c -- 第一个版本的交换函数,只在局部交换值
    #include <stdio.h>
    void interchange(int u, int v);
    int main(int argc, char const *argv[])
    {
        int x = 5, y = 10;
        printf("初始xy的值是x=%d y=%d.\n", x, y);
        interchange(x, y);
        printf("交换后的值x=%d,y=%d", x, y);
    
        return 0;
    }
    void interchange(int u, int v)
    {
        int temp;
        printf("初始xy的值是x=%d y=%d.\n", u, v);
    
        temp = u;
        u = v;
        v = temp;
        printf("初始uv的值是x=%d y=%d.\n", u, v);
    }
    

    result:

    初始xy的值是x=5 y=10.
    初始xy的值是x=5 y=10.
    初始uv的值是x=10 y=5.
    交换后的值x=5,y=10
    

    只是在函数内交换了u 和 v的值,但是结果传回main 时并不是。可以尝试return返回,但是return只能返回一个值,要是返回两个需要用到指针?这是函数之间的通信问题。

  • 指针值是地址。将指针作为函数参数使用,可以实现通过函数修改变量的实际值。

    #include <stdio.h>
    int main()
    {
    
        int* x; // x pointer
        int num;
        printf("给x指针赋值(让指针指向xx) ,x指针的地址:%p:\n",x);
        scanf("%d",&num);
        x = &num;
        printf("x指向的值:%d\n",*x);
    
        return 0;
    }
    
    

    result:

    给x指针赋值(让指针指向xx) ,x指针的地址:0000000000000010:
    16
    x指向的值:16
    
  • 利用指针解决函数的通信问题。

    //swap3.c -- 使用指针解决交换函数的问题
    #include <stdio.h>
    void interchange(int *x, int *y);
    int main(int argc, char const *argv[])
    {
        int x = 5, y = 10;
        printf("初始的x=%d,y=%d.\n", x, y);
        interchange(&x, &y);
        printf("交换后x=%d,y=%d", x, y);
    
        return 0;
    }
    
    void interchange(int *x, int *y)
    {
        int temp;
    
        temp = *x;
        *x = *y;
        *y = temp;
    }
    
    

    result:

    初始的x=5,y=10.
    交换后x=10,y=5
    
  • 小结:

    注意函数定义和函数声明。

    利用指针作为函数的参数解决函数之间的通信问题。利用函数修改指针所指向的值。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值