文章目录
  1. 1. 作用域
  2. 2. 链接属性:
  3. 3. 存储类型:
  4. 4. 关键字static:

我自己也常常会搞不清static的用法,再次总结一下,主要摘抄了《c和指针》这本书相关章节。

作用域

编译器可以确定4种不同作用域:

  • 文件作用域:
    在所有代码块之外声明的标示符都具有文件作用域,作用域在源文件结尾处结束。

  • 函数作用域:
    函数作用域也具有代码块作用域的属性。
    注:函数形参的作用域开始于形参的声明处,位于函数外。如果在函数体内部声明了名字与形参相同的局部变量,将隐藏形参。

  • 代码块作用域:
    花括号中间的语句称为一个代码块。

  • 原型作用域:
    只适用于函数原型中声明的参数名,貌似并没有什么用,暂时不用理。函数声明中的参数名字不是必须,原型作用域只是为了保证参数名字不会和程序其他部分的名字冲突。

链接属性:

标示符的链接属性决定如何处理在不同文件中出现的标示符。
分类:external(外部)internal(内部)none(无)

  • 外部(external):
    不论声明多少次,位于几个源文件都表示同一个实体。

  • 内部(internal):
    在同一文件内的所有声明都指同一实体,不同文件中多个声明分属不同的实体。

  • 无(none):
    被当作单独的个体,标示符的多个声明会当作独立不同的实体,互不影响。
    注:缺省情况下,在所有函数外部的标示符具有external链接属性。

存储类型:

指存储变量值的内存类型,变量的存储类型决定变量何时创建、何时销毁以及它的值将保持多久。
存储变量的的地方:普通内存运行时堆栈硬件寄存器
变量的存储类型取决于它的声明位置:

  • 具有文件作用域的变量存储于静态内存中,被称为静态变量。在程序运行前创建。
  • 具有代码块作用域的变量存储于堆栈中,称为自动变量局部变量。程序执行时创建。
  • 关键字register可以用于自动变量的声明,提示应该存储于硬件寄存器,但是编译器不一定会理睬register关键字。基本上不会用register。

  1. 对于在代码块内部声明的变量,加上static关键字,可以使它的存储类型自动变为静态。
  2. 修改变量的存储类型不能改变该变量的作用域!!!
  3. 函数的形式参数不能声明为静态。

静态变量和自动变量(也称局部变量)的重要区别:

  1. 静态变量如果没有初始值将会初始化为0
  2. 自动变量因为在程序链接时无法判断自动变量的存储位置,所以,自动变量没有缺省的初始值,是不确定的。
  3. 静态变量只是在程序运行前初始化一次,但是自动变量每次都会初始化。

关键字static:

static在不同的环境下,有不同的意思。

  • 在函数定义时,或用于代码块之外的变量声明时(即具有文件作用域属性),static关键字用于修改标示符的链接属性,将external改为internal。
    注:标示符的存储类型和作用域不会改变。这种方式声明的变量或函数只能在声明它们的源文件中访问。

  • 在代码块内部的变量声明时,用于修改变量的存储类型,从自动变量修改为静态变量。
    注:变量的链接属性和作用域不受影响。
    在函数内部的变量加上static关键字后,在程序整个执行过程中都存在,只会被初始化一次,函数再次调用时不会再被初始化。

具有external链接属性的实体总是具有静态存储类型。
static只对缺省链接属性为external的声明才有改变链接属性的效果。
全局变量在程序开始执行前创建,并在程序整个执行过程中始终存在。

文章目录
  1. 1. 作用域
  2. 2. 链接属性:
  3. 3. 存储类型:
  4. 4. 关键字static: