C语言变量和数据存储

C语言从两个方面控制变量的性质:scope和lifetime

scope指存储变量的代码范围

lifetime指可以存取变量的时间范围

作用域:

extern 整个程序

static 在函数外部说明为static的变量的作用域为从定一点到该文件尾部;在函数内部说明为static的变量的作用域为从定一点到该局部程序块尾部

 

auto 从定义点到该局部程序块尾部

 

生存期:

extern和static变量的生存期,从main()函数被调用之前开始,到程序退出时为止。

auto变量的生存期从函数调用开始,到函数返回时为止。

第三种是动态分配的数据的生存期,它从程序调用malloc()或calloc()为数据分配存储空间开始,到程序调用free()或程序退出时为止。

 

 

 

变量的存储区域

在函数外部定义的变量(全局变量或静态外部变量)和在函数内部定义的static变量,其生存期就是程序运行的全过程,这些变量被存储在数据段中。(数据段是在内存中为这些变量留出的一段大小固定的空间,它分为两部分,一部分用来存放初始化变量,另一部分用来存放未初始化变量。)

 

在函数内部定义的auto变量(没有用关键字static定义的变量)的生存期从程序开始运行其所在的程序块代码时开始,到程序离开该程序块时为止。作为函数参数的变量只在调用该函数期间存在。这些变量被存储在栈中。(栈是内存中的一段空间,开始很小,以后逐渐自动增大,直到达到某个预定的界限。在象dos这样的没有虚拟内存的系统中,这个界限由系统决定,并且通常很大,因此程序员不必担心用尽栈空间。)

 

第三种内存空间 实际上并不存储变量,但是可以用来存储变量所指向的数据。如果把调用malloc()函数的结果赋给一个指针变量,那么这个指针变量将包含一块动态分配的内存地址,这块内存位于一段名为“堆”的内存空间中。堆开始也很小,但当程序员调用malloc()或calloc()等内存分配函数时它就会增大。堆可以和数据段或栈公用一段内存,也可以有它自己的内存段,这完全取决于编译选项和操作系统。

 

const指针

const指针解释为指向const数据的指针,即它所指向的数据不能被修改。只要在指针说明的开头加入const修饰符,就可以说明一个const指针。尽管const指针所指向的数据不能被修改,但const指针本身是可以修改的。

 

volatile修饰符

volatile修饰符告诉编译器不要对该变量所参与的操作进行某些优化。

两种特殊使用情况:1、涉及到内存映射硬件(memory-mapped hardware,如图形适配器,这类设备对计算机来说就好像是内存的一部分一样);2、涉及到共享内存时(shared memory,即被连个以上同时运行的程序所使用的内存)。

 

浮点数

从数学意义上讲,两个不同数字之间有无穷个实数。计算机只能区分至少有一位bit不同的两个数字。如果要表示那些无穷无尽的各不相同的数字,就要使用无穷数目的位。计算机只能用较少的位(通常是32位或64位)来表示一个很大的范围内的数字,因此它只能近似的表示大多数数字。

一个数字型变量可以容纳的最大值

要判断某种特定类型可以容纳的最大值或最小值,一种简便的方法是使用ANSI标准头文件limit.h中的预定义值。

运算符升级

当两个不同类型的运算分量进行运算时,它们会被转换为能容纳它们的最小的类型,并且运算结果也是这种类型

 

不应该对用const或volatile说明了的对象进行类型强制转换,否则程序就不能正确运行。

 

变量与函数

使用全局变量或static局部变量的函数大多数情况都不可重入(reentrant)。这意味着,如果这个函数的一个实例正在运行时,那么程序中其他执行线程就不能再调用它。更坏的情况是,函数的结果必须在该函数再次被调用之前,保存到其他地方;否则,它将被新的结果重写。

 

结构体的传递方式默认是值传递方式,即传递结构体给函数时,需要将整个结构体赋值一遍再传递给函数,这比结构体指针的传递慢多了。

你可能感兴趣的:(C语言变量和数据存储)