3. 局部变量和全局变量

3.1、局部变量

局部变量 是指函数内部声明(没有用 static修饰)的变量和函数的形参变量。

说明:

示例:

#include <stdio.h>

int myadd(int x, int y) {
    int r; // x, y, r 都是局部变量。
    r = x + y;
    return r;
}

int main(int argc, char *argv[]) {
    int result;  // argc, argv 和 result 也是局部变量。
    result = myadd(1, 5);  // 调用时在栈上创建 x、y、r变量
    // myadd 函数调用结束,myadd 内部的x、y、r 变量销毁

    printf("result:%d\n", result);

    return 0;
}

3.2、全局变量

全局变量 是指函数外部,.c 文件内部声明的变量。全局变量的特点是所有的函数可以不通过传参可以直接引用其变量。方便全局数据的存储。

说明:

一个程序优先访问离自己最近的复合语句或函数内的局部变量,如果局部变量不存在才访问全局变量,如果全局变量也不存在则程序编译时报错。

示例:

#include <stdio.h>

// week 数组为全局变量的数组
const char * week[] = {"Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat"};
int call_count = 0;  // call_count 为 int 型全局变量

int myadd(int x, int y) {
    call_count += 1;
    return x + y;
}

int main(int argc, char *argv[]) {
    myadd(1, 2);
    myadd(3, 4);

    printf("myadd 函数共调用 %d 次\n", call_count);
    printf("today is %s\n", week[1]);
    return 0;
}

程序运行结果如下:

myadd 函数共调用 2 次
today is Mon

计算机程序在运行时,大致分为如下几部分:

  1. 栈(Stack)
  2. 堆(Heap)
  3. 数据段(Data)
    • 初始化的数据
    • 未初始化的数据(BSS)段,其数据初始值全部置零。
  4. 代码段(Code)

典型程序运行时的存储空间安排如下图所示:

             +---------------+
high address |     argv[]    | 命令行参数和环境变量
             +---------------+
             |     stack     | 
             | - - - - - - - |
             |       |       |
             |       V       |
             |               |
             |               |
             |       ^       |
             |       |       |
             | - - - - - - - |
             |      heap     | 
             +---------------+
             |      bss      | 未初始化的全局变量
             +---------------+
             |initalized data| 初始化的全局数据
             +---------------+
low address  |     code      | 代码段
             +---------------+

其中,代码段用来存储函数编译后的二进制指令;bbsinitalized data 存放全局变量;heap 存放动态分配内存的数据;stack 用于存放函数内的局部变量。

练习:

写一个函数 factorial 求一个整数 n 的阶乘。

要求函数的定义格式如下:

int factorial(int n) {
    ...
}

在数学中 n 的阶乘用 n! 表示,即:

n!  等于 1 * 2 * 3 * ... * n-1 * n 的积。

如: