C语言编程常见问题解答之变量和数据存储
第2章变量和数据存储
C语言的强大功能之一就是可以灵活定义数据的存储方式。c语言从两个方面控制变量的性质:作用域和生存期。作用域是指可以访问变量的代码范围,生存期是指可以访问变量的时间范围。
有三个范围:
1。extern (external)这是在函数外部定义的变量的默认存储。extern变量的范围是整个程序。
2。static(静态)在函数外被描述为静态的变量的范围是从定义点到文件的末尾;函数中描述为静态的变量的范围是从定义点到局部块的末尾。
3。Auto(自动)这是函数中描述的变量的默认存储方法。auto变量的范围是从定义点到局部块的末尾。
变量也有三种寿命,但是它们没有像作用域那样预定义的关键字名称。第一个是extern和static变量的生存期,从调用main()函数之前开始,到程序退出时结束。第二个是函数参数和自动变量的生存期,从调用函数时开始,到函数返回时结束。三是动态分配数据的生存期,从程序调用malloc()或calloc()为数据分配存储空时开始,到程序调用free()或程序退出时结束。
2.1变量存储在内存的什么地方?
变量可以存储在内存的不同位置,这取决于它们的生存期。函数外部定义的变量(全局变量或静态外部变量)和函数内部定义的静态变量的生存期是程序运行的全过程,这些变量存储在datasegment中。段是内存中为这些变量保留的固定大小的空空间。它分为两部分,一部分用于存储初始化的变量,另一部分用于存储未初始化的变量。
函数中定义的auto变量(不是用关键字static定义的变量)的生存期从程序开始执行它所在的块的代码时开始,到程序离开该块时结束。作为函数参数的变量只存在于函数调用期间。这些变量存储在一个堆栈中。它是堆栈内存中空的一段,开始很小,然后逐渐自动增大,直到达到一个预定义的极限。在像DOS这样没有虚拟内存的系统中,这个限制是由系统决定的,而且通常很大,程序员不用担心栈空用完。关于虚拟内存的讨论见2.3。
第三个(也是最后一个)内存空其实不存储变量,但是可以用来存储变量指向的数据。如果将调用malloc()函数的结果赋给一个指针变量,那么这个指针变量将包含一个动态分配的内存的地址,这个地址位于memory 空的一个叫做“heap”的段中。堆一开始也很小,但是当程序员调用malloc()或calloc()之类的内存分配函数时,堆就会变大。堆可以与数据段或堆栈共享一个内存段,也可以有自己的内存段,这完全取决于编译选项和操作系统。
和栈类似,堆也有增长限制,决定这个限制的规则和栈的规则一样。
参见:
1.1什么是本地块(10calblock)?
2.2变量一定要初始化吗?
2.3什么是pagethrashing?
7.20什么是栈?
7.21什么是堆7。
2.2变量一定要初始化吗?
不可以。在使用变量之前,您应该给它们一个值。一个好的编译器会帮助你找到那些没有被赋值的变量。然而,变量不一定需要初始化。在函数外部定义的变量或在函数内部用static关键字定义的变量(在数据部分定义的变量,见2.1)在被程序显式初始化之前,已经被系统初始化为0。没有static关键字的函数或块中定义的变量都是自动变量。如果不显式初始化这些变量,它们将有未定义的值。如果你没有初始化一个自动变量,你必须确保在使用它之前给它赋值。
通过调用malloc()函数从堆中分配的空也包含未定义的数据,所以在使用之前必须进行初始化,但是通过调用calloc()函数分配的空在分配的时候已经初始化为0。
请看:
1.1什么是本地块(10calblock)?
7.20什么是栈?
7.21什么是堆?
2.3什么是pagethrashing?
有些操作系统(如增强模式的UNIX和Windows)使用虚拟内存,这是一种使机器的作业地址空大于实际内存的技术。它是通过在磁盘空之间模拟RAM(随机存取存储器)来实现的。
0条评论