C语言中不同类型变量的解读

C语言中变量分为四类,分别是

  • auto 自动变量
  • static 静态存贮分配变量(又分为内部静态和外部静态)
  • extern 全局变量(用于外部变量说明)
  • register 寄存器变量(分配在硬件寄存器中)

四大类,所有变量必须先说明(定义),后使用

自动变量(局部变量)

局部变量:在一个函数开头或段开头处说明的变量,它有几个特征:

  • 作用域为定义它的函数
  • 编译器不会对自动变量给予隐含的初值,故其值不确定,因此每次使用前必须明确的置初值。
  • 形参是自动变量,作用域仅限于相应函数内
  • 自动变量随函数的引用而存在和消失,由一次调用到下一次调用之间不保持值。
#include <stdio.h>  
void print_number (int x, int y)   
{  
      int m,sum;  
      for(m = x;m<y;m++) 
      {  
            sum +=m;  
      }  
      printf("%d\n",sum);  
 }  
void main(void)   
{  
     print_number(3,5);  
     print_number(3,5);  
} 
  • 这个程序打印的值均不正确,因为sum未赋初值,
    造成了打印的数为随机数。 我们把sum赋初值为0再执行以下,结果就正确了。
  • 这个程序说明局部变量必须要先赋初值再使用,另外说明局部变量的生命周期为函数调用时开始,函数调用完成时消亡。

外部变量:

  • 在函数外部定义的变量即为外部变量,它的作用域是整个程序(全程变量,也就是全局变量)。

  • 全局变量的作用范围是整个程序(如果程序是多个文件,必须在其他的文件中说明,其实说明方法就是添加extern关键字)

  • c程序可以分别放在几个文件上,每个文件可以作为一个编译单位分别进行编译。外部变量只需在某个文件上定义一次,其它文件若要引用此变量时,应用extern加以说明(外部变量定义时不必加extern关键字)。

  • 在同一文件中,若前面的函数要引用后面定义的外部(在函数之外)变量时,在函数里加extern加以说明。

引进外部变量的原因:解决函数单独编译的协调;与变量初始化有关;外部变量的值是永久的;解决数据共享;
注意:函数本身也被认为是外部变量

静态变量:

  • 分为内部静态变量和外部静态变量
  • 静态变量的作用范围要看静态变量的位置,如果在函数里,则作用范围 就是这个函数
  • 内部静态变量:

    • 在局部变量前加上static就为内部静态变量
    • 静态局部变量仍是局部变量,其作用域仍在定义它的函数范围内,但它采用静态存贮分配(由编译程序在编译时分配,而一般的自动变量和函数形参均采用动态存贮分配,即在运行时分配空间),当函数执行完,返回调用点时,该变量并不撤销,再次调用时,其值将继续存在。
    • 内部静态变量也称作局部静态变量
  • 外部静态变量:

    • 在函数外部定义的变量前加static即为外部静态变量
    • 作用域为定义它的文件,即成为该文件的私有变量,其他文件上的函数一律不得直接访问,除非通过它所在文件上的函数进行操作,这可实现数据隐藏。
      外部静态变量也称为静态全局变量。静态全局变量,只在本文件可以用,虽然整个程序包含多个文件,但静态全局变量只能用在定义它的那个文件里,却不能用在程序中的其他文件里。它是定义存储因型为静态型的外部变量,其作用域是从定义点到程序结束,所不同的是存储类型决定了存储地点,静态型变量是存放在内存的数据区中的,它们在程序开始运行前就分配了固定的字节,在程序运行过程中被分配的字节大小是不改变的,只有程序运行结束后,才释放所占用的内存。

寄存器变量:

  • 只有自动(局部)变量和函数参数才能进一步指定为寄存器存贮类
    • 使用register变量可以提高存取速度,但寄存器变量的数目依赖于具体机器,声明多了也只有前几个有效。
    • 只限于int,char,short ,unsigned和指针类型用寄存类。
    • .不能对register变量取地址(即&操作)

变量的初始化:

  • 外部变量和静态变量由编译程序给予隐含的初始值0;
  • 局部变量的初始化每进入函数便初始化一次。
  • 外部或静态变量仅在编译时初始化一次。
  • 自动变量或寄存器变量只能显示初始化,否则将有不确定的值。
  • 外部数据的说明,如果带有初始化项,则当成一个定义。
  • 在c语言中函数不能嵌套定义,但是变量可以嵌套定义。

各种变量在内存的位置

  • 局部变量存储在堆栈中,也就是在栈区内。无论局部变量显示初始化,或者未初始化,都只有当定义它们的程序块被调用时(即执行时),才分配空间,声明或定义时并不分配,局部变量不是可执行模块的一部分!!除非显示地对局部变量进行初始化,否则,它们的初始值是不确定的。

  • 全局变量没有声明在任何一个函数内,作用范围在程序运行始终存在。能被同一源文件的任何函数使用,也能被其他文件中的函数使用,但要使用extern关键字(这里再重复一遍,前边已经说明了一次)。全局变量存储在数据段中。全局变量显示初始化时(如b),或者未初始化时(如a),在程序映像中有不同的分区:已初始化的全局变量是可执行模块的一部分。未初始化的全局变量则不是可执行模块的一部分,只有当定义它们的程序被调用时(即执行时),才分配空间,声明或定义时并不分配。未初始化的全局变量在运行时被初始化为0。

  • 静态变量,用static关键字定义的变量,与局部变量相比, static局部变量以下不同:

    • 存储空间分配不同,auto类型分配在栈上,属于动态存储类别,占动态存储区空间,函数调用结束后自动释放, 而static分配在静态存储区,在程序整个运行期间都不释放,两者之间的作用域相同,但生存期不同;
    • static局部变量在所处模块在初次运行时进行初始化工作,且只操作一次;

注意:对于外部(全局)变量,不论是否有static限制,它的存储区域都是在静态存储区,生存期都是全局的。此时的static只是起作用域限制作用,限定作用域在本模块(文件)内部。静态全局变量与全局变量的差别是:静态全局变量只能被同一源文件中的函数调用,其他文件中的函数不能调用静态全局变量。

发布了62 篇原创文章 · 获赞 68 · 访问量 5万+

猜你喜欢

转载自blog.csdn.net/magic_world_wow/article/details/81139891