写在前面

在本篇前需要提到的一个内容——变量的作用域问题。每一个变量都有一个自己的作用域。c语言中根据变量的作用域可以将变量分为全局变量和局部变量。从另一个角度变量的存在时间(及生存期)来观察,会发现有的变量在程序运行的开始就会被分配存储空间,直到整个程序运行结束后才会释放存储空间,但有的变量在调用改该变量所在函数时候才会分配存储空间,函数调用结束后,分配的存储空间就会被释放。会有这种不同是原因是变量的存储方式。变量的存储方式有静态存储方式和动态存储方式。

  • 局部变量和全局变量

    • 局部变量

      • 在函数的开头定义:在本函数中可以使用;

      • 在函数内地复合语句中的定义:在该复合语句中可以使用,这种复合语句也称为“分程序”或“程序块”;

      • 在函数的外部定义:函数的外部定义呢要分开情况定,因为有的外部定义也可以是全局变量;

局部变量的生存期从函数调用开始直到函数调用结束;

- 全局变量

    程序的编译单位是源程序文件,一个源程序文件可包含一个或多个函数,而在函数之外定义的外部变量为全局变量。全局变量可以被本文件中的其他函数使用,生存期直到源文件结束为止;

    为更好的区分全局变量和局部变量,c语言在编写的时候有一个大家都在遵循的习惯:全局变量名的第一个字母用大写表示;

    思考:还有一个宏定义,它和这几种变量有什么区别。
  • 动态存储方式和静态存储方式

    动态存储方式:在程序运行的过程中动态的分配存储空间

静态存储方式:在程序运行的过程中由系统分配固定的存储空间;

- 内存中供用户使用的存储空间分为3个部分:

    - 程序区:主要分配为程序运行使用;

    - 静态存储区:放全局变量,程序结束后会释放;

    - 动态存储区:函数形式参数,调用函数时给形参分配空间,函数定义的没有用关键字static声明的变量;函数调用时的现场保护和返回地址等。

    在c语言中,每个变量和函数有两个属性:数据类型和数据存储类别。存储类别指的就是数据在内存中存储的方式,细分可分为自动的(auto)、静态的(static)、寄存器的(register)、外部的(extern)4种。在一般时,系统会隐含的指定为某一种存储类别,前提是用户没有指定。
  • 局部变量的存储类别

    • 自动变量(auto)

      函数如果没有专门使用static声明,就都是动态地分配内存空间、函数中的形参和函数中定义的局部变量都是属于此类。实际上,关键字auto一般是省略的,auto类别是系统隐含指定的“自动存储类别”,属于动态存储方式;

以下为示例代码:

    
1
2
3
4
5
6
int f(int a)              //定义f函数,a为形参
{
auto int b,c = 3; //定义b,c为自动变量
....
....
}
说明:

a为形参,b和c为自动变量,对c赋初值后,该函数执行完f函数后、会自动释放a、b、c、的存储单元。
另外【int b,c = 3;】等价于【auto int b,c = 3;];

- 静态局部变量(static)

    使用关键字static声明变量,在函数掉哦给你结束后不会消失,会继续保留原值。

以下为示例1代码:

    
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
#include<stdio.h>
int main()
{
int f(int); //函数声明
int a = 2,i; //自动局部变量
for(i = 0; i < 3; i++)
{
printf("%d\n",f(a));
}
return 0;
}

int f(int a)
{
auto int b = 0;
static int c = 3;
b = b + 1;
c = c + 1;
return(a+b+c);
}
以下为输出结果:
1
2
3
7
8
9
说明: 静态局部变量属于静态存储类别吗,在静态存储区内分配存储单元。在程序整个运行期间都不会被释放,自动变量在函数结束后会释放存储单元。