5.C语言函数

3 阅读4分钟

函数

完成某种特定功能的指令序列集合的集合

函数作用

  • 实现代码的复用(高内聚、低耦合)
  • 实现模块化设计
  • 函数可以灵活组合调用

函数的设计

  • 需求分析:函数是干什么的,完成什么功能,需要什么资源
  • 函数的功能实现:算法
  • 需不需要返回一个结果

函数的定义

// 函数头
返回值类型 函数名(形参列表)

// 函数体
{
    函数的具体实现步骤(具体功能实现的代码);
}

// 一个标准的函数
返回值类型 函数名(形参列表)
{
    函数的具体实现步骤(具体功能实现的代码);
}
  • 返回值类型:一般是单值类型,即基本类型、指针类型、构造类型。也可以返回空 void,如果不指定返回值类型的话,默认就是int类型
  • 函数名:c语言标识符,要符合标识符命名规范
  • 形参列表:需要外部调用者提供的资源,格式:(数据类型1 数据名1, 数据类型2 数据名2, ..., 数据类型n 数据名n)
  • 函数的具体实现步骤:函数的功能实现

main默认函数为:

int main(int argc, const char *argv[]){
    // 写代码
}

函数的调用

语法:{返回值类型 变量名=}函数名(实参列表);

#include <stdio.h>

// 声明函数
int sum(int nums[], int size);

int main(){
    int ns[] = {1,2,3,4};
    int size = sizeof(ns) / sizeof(ns[0]);

    printf("%d\n", sum(ns, size));
    return 0;
}

int sum(int nums[], int size){
    int result_num = 0;

    for (int i=0; i<size; i++){
        result_num += nums[i];
    }
    return result_num;
}
  • 返回值类型:与函数的返回值一致
  • 函数名:被使用的那个函数的名字
  • 实参列表:与形参列表对应,位置、类型、数量要一模一样
  • 主调函数:
    • 调用别的函数的函数:上述代码中:main是sum的主调函数
  • 被调函数:
    • 上述代码中,sum为被调函数

函数的调用过程

  • 把实参的值赋值给形参
  • 执行被调函数中的语句代码
  • 被调函数返回时,函数的表达式的值就是return后面的表达式的值

函数的数据传递

  • 主调函数 --> 被调函数:传参
  • 被调函数 --> 主调函数:返回值
  • 主调函数 <-> 被调函数:指针,全局变量

函数的声明:

  • 提前告知编译器有这么一个函数
  • 因为编译器在变异代码的时候,是从上往下的。当被调函数在主调函数的后面的时候,就要声明。否则会找不到。
  • 声明的时候可以省略形参名
    // 声明函数
    函数头;
    

注意:一个程序里面main函数有且只有一个,其他函数不限制

递归函数

是指在函数调用过程中,直接或者间接调用自身。
递归函数不会降低复杂度,只会增加复杂度

  • 优点:

    • 把复杂问题简单化
    • 提高big
  • 代码(计算1+2+3+...+n)

#include <stdio.h>


int calc(int);

int main(){
    printf("%d\n", calc(100));
    printf("%d\n", calc(1000));
    return 0;
}

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

变量的作用域和生存期:

变量的作用域
  1. 全局变量
  • 全局变量作用域:从定义到当前文件结束都可以使用
  • 对于整个工程来说,在其他文件里使用,要加extern进行外部声明
  • 如果全局变量使用static修饰的话,那么就只能在本文件使用
  1. 局部变量
  • 从局部变量定义处开始到函数结束或者复合语句结束
  • 不同作用域的两个变量,必定是两个不同且独立的内存空间。即使同名,也是独立的。遇到同名情况,会往上就近寻找。
变量的生存期

变量的生存周期,当变量过了他的生存期,其内存空间就会被释放掉

  • 全局变量的生存期:
    • 随进程持续性。即只要程序一运行,全局变量的内存就会被分配好,并且一直会存在,直到程序退出
  • 局部变量的生存期:
    • 普通局部变量:从定义处到他的函数结束或者复合语句结束
    • 静态的局部变量:即使用了static进行修饰的局部变量。生存期从程序已运行就会分配内存,直到程序结束,并且初始化只会执行一次。

注意:我们可以通过花括号来确定一个变量的作用域,向下找右花括号。从定义处到向右花括号就是作用域范围。