关于作用域的认知

所谓作用域,其实就是指变量作用的范围.

C语言变量的作用域按照类型可分为:
1. 代码块作用域(代码块是{}之间的一段代码)
2. 函数作用域
3. 文件作用域

普通局部变量

局部变量也叫auto自动变量(auto可写可不写),一般情况下代码块{}内部定义的变量都是自动变量,它有如下特点:
– 在一个函数的形参或在其内部定义(即{}内),则只在本函数范围内有效.
– 在复合语句中定义,只在复合语句中有效.
– 只有在运行到定义变量的位置,才会开始分配空间.
– 在函数调用结束或复合语句结束后局部变量的生命周期也结束.
– 变量如果没有赋初值,则其内容为随机值.

int i; // 等同于 auto int i;

static修饰的局部变量

  • static局部变量生命周期和普通局部变量不一样,其它用法和普通局部变量一样
  • 程序运行到static局部变量初始化的语句时,才进行初始化;下次执行到,则不再初始化.因此static局部变量只初始化一次,可以赋值多次.
  • static局部变量的作用域也是在定义的函数内有效
  • static局部变量的生命周期和程序运行周期一样.在函数没有调用前,static局部变量就已经存在;函数调用完毕,static局部变量还存在.不释放,只有在整个程序结束才释放.
  • static局部变量只能用常量初始化,不能用变量初始化.若未赋以初值,则由系统自动赋值:
    • 数值型变量自动赋初值0.
    • 字符型变量赋空字符'\0'.

普通全局变量(外部链接)

普通全局变量的特点:

  • 函数外部定义的变量就是全局变量.
  • 函数没有调用前,全局变量就已经存在,任何函数都能用全局变量.
  • 如果全局变量的定义不是在使用位置的前面,则使用前需要声明,且声明时不可赋值,声明格式:extern 类型 变量名;.
  • 在函数外定义,可被本文件及其它文件中的函数所共用,若其它文件中的函数调用此变量,须用extern声明.
  • 全局变量的生命周期和程序运行周期一样.
  • 不同文件的全局变量不可重名.

普通全局变量声明和定义
int var; 通常指的是声明,但也有可能是定义.
– 全局变量只能定义一次,可以声明多次(和函数一样)
– 只要初始化的全局变量,一定是定义.全局变量定义时,建议初始化.
– 如果是声明,建议加extern.
– 只有声明,没有定义,没有意义.
同一源文件中,允许全局变量和局部变量同名,在局部变量的作用域内,全局变量不起作用.

普通全局变量分文件问题
– 不同文件,只能定义一次普通全局变量,但可以声明多次.
– 头文件放函数的声明和全局变量的声明,不建议在头文件写定义.
– 防止头文件重复包含和同一个文件多次包含,因此只有最后一次有效.

static修饰的全局变量(内部链接)

  • static全局变量要想使用,必须在使用前定义.
  • 在函数外定义,作用范围被限制在所定义的文件中(当前文件);与普通全局变量不同,普通全局变量任何文件都能使用.
  • 不同文件静态全局变量可以重名,但作用域不冲突;且不同文件,static全局变量和普通全局变量可以同名(不建议这么做).
  • static全局变量的生命周期和程序运行周期一样,同时staitc全局变量的值只初始化一次.

普通函数和static修饰的函数

C语言中函数默认都是全局的,使用关键字static可以将函数声明为静态.

  • 函数定义为static就意味着这个函数只能在定义这个函数的文件中使用,在其他文件中不能调用,即使在其他文件中声明这个函数都没用.
  • 对于不同文件中的staitc函数名字可以相同.