人之所以痛苦,那是因为你在成长。--------magic_guo
变量可以分为全局变量和局部变量,那变量的存储方式可以分为静态存储方式和动态存储方式;
静态存储方式:指在程序运行期间由系统分配固定的存储空间的方式
动态存储方式:指在程序运行期间根据需要进行动态的分配存储空间的方式
定义一个变量和函数都有两个属性:数据类型(浮点型、整形等)和存储类别(数据在内存中的存储方式)
在动态存储区存放以下数据:
1.形参(在函数调用期间给形参分配存储空间)
2.函数中定义的没有用关键字static声明的变量,即自动变量(auto)
3.函数调用时的现场保护和返回地址等
在C中存储类别分为4中:自动的(auto)、静态的(statis)、寄存器的(register)、外部的(extern)
下面我们来讨论局部变量和群聚变量的存储类别有什么不同:
局部变量的存储类别:
1.自动的(auto)
即函数中没有用关键字static声明的变量,函数的形参,函数中的局部变量都属于此类,动态的分配存储空间,数据存储在动态存储区中。
自动变量属于动态存储类别,函数调用完后即释放内存单元,自动变量赋值不是在编译时进行赋值的,而是在进行函数调用时进行赋值,每调用一次函数重新给一次初值。
代码如下:
int f1(int a) //形参,a为动态存储类别
{
auto int b = 3; //自动变量,b为动态存储类别
int c = 4; //不带static关键字,与b同类别,也是动态存储类别
static e = 5; //使用static关键字声明,所以e为静态存储类别
}
2.静态存储类别(static局部变量)
如上图的e变量
静态局部变量属于静态存储类别,在静态存储区域内分配存储单元。在整个程序运行期间都不释放,静态局部变量是在编译时赋初值的,在程序运行时它已有初值,以后每次调用不需在重新赋值而只是保留上次函数调用结束时的值。
虽然静态局部变量的值在函数调用结束后仍然存在,但其他函数是不能引用它的,因为它是局部变量,只能被本函数引用。
代码如下:
自动变量和静态变量赋值的区别:
# include<stdio.h>
int main(void)
{
int f1(int a); //f1函数的前置声明
int f2(int a); //f2函数的前置声明
int i, a = 1;
for (i=0; i<3; i++)
{
printf("%d\n", f1(a)); //调用f1函数
}
return 0;
}
int f1(int a)
{
auto int b = 0; //定义自动变量
b = b + 1;
return (a+b);
}
int f2(int a)
{
static c = 0; //定义静态变量
c = c + 1;
return (a+c);
}
调用f1函数的结果:
调用f2函数的结果:
显然两种变量的存储方式不一样,导致的结果也不一样。
3.寄存器变量
使用关键字register作声明
一般情况下变量的值是存在内存中的,当程序需要用到那个变量时,由控制器发送指令将内存中变量的值送到运算器中。经过运算,如果需要存起来,再从运算器将数据传送到内存中存放。
如果有些使用频繁的变量,则存取变量的值会浪费很多时间,为提高执行效率,则将局部变量的值放在CPU中的寄存器中,不必再到内存中去取。这种变量叫做寄存器变量
声明如下:
register int a;
三种变量的存储位置是不同的:
自动变量存储在动态存储区、静态变量存储在静态存储区、寄存器变量存储在CPU的寄存器中
全局变量的存储类别:
全局变量又称为外部变量,存储在静态区域内,存在于程序的着呢个运行过程
从作用域的角度来看,分为三种情况:
1.在一位文件内扩展外部变量的作用域
如下,函数后面定义的外部变量,想要使用,则需要使用关键字“extern“对该变量进行外部声明,表示将该变量的作用域扩展到此位置。
# include<stdio.h>
int main(void)
{
int max();
extern A, B, C; // 如果不在这里使用extern声明A,B,C,则无法使用A,B,C三个变量
printf("请输入三个整数以求出起最大值:");
scanf("%d %d %d", &A, &B, &C);
printf("最大值是:%d\n", max());
return 0;
}
int A, B, C;
int max()
{
int m;
m = A>B? A:B;
if (C>m)
m=C;
return m;
}
2.将外部变量的作用域扩展到其他文件
方法同上,也是使用extern关键字进行作用域声明,区别是在另一个文件内进行声明。
3.将外部变量的作用域限制在本文件内
在本外部变量前面加上static关键字即可,如下:
static int A;
则此全局变量(外部变量)只能在定义它的文件内使用。
扩展:
将函数的作用域限制在所定义它的文件中,也是使用static关键字作声明:
static int max()
{
int m;
m = A>B? A:B;
if (C>m)
m=C;
return m;
}
则此函数只能在本文件内使用,其他文件则不能引用,称为内部函数。
外部函数:在函数首部的左端加关键字extern,则此函数是外部函数:
extern int max()
{
int m;
m = A>B? A:B;
if (C>m)
m=C;
return m;
}