程序变量

来源:互联网 发布:网络机顶盒港澳台直播 编辑:程序博客网 时间:2024/05/22 05:26

程序变量

阐明变量的代码作用域,自动存储时期的根源

通过链接概念,说明变量文件作用域的根源

C语言中变量的分类

1、  自动存储变量(Auto)
在一个代码块内(或者是在一个函数头部作为参量)声明的变量,无论是否存在存储类修饰符auto,都属于自动存储变量。此类变量具有自动存储时期、代码块作用域和空链接。未经初始化,此类变量的值是不确定的。

2、  寄存器变量(Register)
在一个代码块内(或者是在一个函数头部作为参量)使用存储类修饰符register声明的变量属于寄存器存储类变量。此类变量具有自动存储时期、代码块作用域和空链接,并且无法获取其地址。把一个变量声明为寄存器变量可以指示编译器提供可用的最快访问。如果未经初始化,此类变量的值是不定的。

3、  静态、空链接变量(Static)
在一个代码块内使用存储类修饰符static声明的变量属于静态空链接的存储类变量。此类变量具有静态存储时期、代码块儿作用域和空链接。仅在编译时初始化一次,如未明确初始化,此类变量由系统初始化为0。

4、  静态、外部链接变量(声明时不使用Static,引用时使用Extern)
在所有函数外部定义、未使用存储类修饰符static的变量属于静态、外部链接存储类变量。此类变量具有静态存储时期、文件作用域和外部链接。仅在编译时初始化一次,如未明确初始化,此类变量由系统初始化为0。

5、  静态、内部链接变量(Static)
在所有函数外部定义、使用存储类修饰符static的变量属于静态、内部链接存储类变量。此类变量具有静态存储时期、文件作用域和内部链接。仅在编译时初始化一次,如未明确初始化,此类变量由系统初始化为0。


 

处理器中存储区分类

1、  栈区
———————<—栈顶
……
———————
var 1
———————
var 2
———————
var 3
———————
parameter 1
———————
parameter 2
———————
parameter 3
———————
RET
———————
……
———————<—栈底
上面描述了在C语言中变量的分类,其中在程序中使用最多的是自动存储变量,自动存储变量也是和栈区关系最为密切的变量。(应用最多的既是无修饰符默认情况下定义的变量,这样是最为合理的安排办法。)自动存储变量的来源有两个:函数的局部变量——variable(代码块内),函数定义头部的形式参数parameter(函数头部作为参量)。Variable和parameter是在函数调用时从堆栈中申请的存储空间如上图所示,当然main函数也不例外。当函数调用完成后,variable和parameter需要从栈中弹出,返回地址也要弹出,进而从调用处继续向下执行。这样堆栈中内分配给variable和parameter的空间随着栈指针的变化得到释放。存储空间释放后,访问存储空间的variable和parameter也就相继失去了声明,丢失了作用域和生命期。这样对于,程序的其余部分来说,上述的variable和parameter也就不可用了。明白了上面的过程,如下代码不能实现a和b交换的原因即可得解。类似的涉及内存分配的问题是同样的道理。
#include <stdio.h>
void switch(int a,int b)
int main(void)
{
int a=1,b=2;
switch(a,b);
printf(“a=%d,b=%d”,a,b)
}
void switch(int a,int b)
{
int temp;
temp=a;
a=b;
b=temp;
}

2、  堆区
这个概念存在于有操作系统的系统中,对于“裸奔”的嵌入式设备,malloc和free函数所在的stdlib.h不可用,所以也就不存在堆区的概念。

3、  静态存储区
经过在RL78/G14中的验证,声明为static的变量被安排在ram中的高址部分的某个区域。在静态存储区中的变量,在程序运行的整个过程中都存在。这样具有静态存储期的变量的生命周期是源程序的整个运行过程。具有静态存储器的变量分为函数体内部声明的static变量,函数体外部声明的变量(包括使用static修饰符修饰的和不使用static修饰符修饰的)。这三种变量的不同点在于拥有不同的链接性,换句话说是在整个源程序中对于其他部分的可见性。在函数体内部声明的静态变量只能被此函数内部引用,虽然此类变量在源程序运行过程中始终存在。在函数体外部声明的变量,是否使用static修饰符修饰的变量的区别在于,使用static的变量只能在本源程序文件中声明以下位置引用,而不使用static修饰符修饰的变量可以在其他源程序文件中使用extern关键字引用。

4、  文字常量区

5、  程序代码区

6、  镜像区


 

示例代码

//main.cpp
int a = 0; //
静态存储区,未初始化
char *p1; //
静态存储区,初始化
main()
{
int b; //
栈区
char s[4] = "abc"; //s
[4]属于栈区
char *p2; //p2属于栈区

char *p3 = "123456"; //p3属于栈区,“123456\0”属于文字常量区。
static int c =0
//静态存储区,初始化
p1 = (char *)malloc(10);//
堆区,10字节
p2 = (char *)malloc(20);//
堆区,20字节
strcpy(p1, "123456"); //
123456\0”放在文字常量区,编译器可能会将它与p3所指向的"123456"优化成一个地方。
}

0 0