C和指针 3.5 作用域

缘起

《C和指针》3.5节

分析

变量的作用域指的是

1
当变量在程序的某个部分被声明之后,它只能在程序的某一个区域才能被访问到, 这个区域就是该变量的作用域.

例如函数的局部变量作用域限于函数体. 所以作用域之外可以给不同变量起同样的名字.

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

  1. 文件作用域
  2. 函数作用域
  3. 代码块({}之间的内容称为代码块)作用域
  4. 原型作用域

代码块作用域

代码块就是 {} 包括的内容. 在代码块中声明的变量的作用域就在这个代码块中. 所以不同代码块中可以声明同名的变量(虽然并不建议这么做). 一个代码块中的变量是无法别的代码块访问的(不是嵌套代码块哈),因为它们的作用域没有重叠. 编译器甚至可能将它们存储于同一个内存地址. 例如

1
2
3
4
5
6
{
int f,g,h; // 1
}
{
int f; // 2
}

2中声明的f完全可能和1中声明的f、g、h中的任何一个共享同一个内存地址.(1处的f、g、h并不会共享内存地址). 因为1处的代码块结束后,弹栈,然后2中的f又进栈,所以完全可能共享啊.

对于嵌套代码块,内层的完全可以声明和外层代码块重名的变量. 而且内层代码块只能访问到内层同名变量而不会访问到外层同名变量

1
2
3
4
5
6
7
{
int f = 1; // 1
{
int f = 2,g,h; // 2
printf("%d\n", f); // 是2处的f,而不是1处的f
}
}

上述程序输出2而不是1.

文件作用域

源文件声明的全局变量和函数就具有文件作用域. 表示在整份源文件中是可以访问的. 注意,文件作用域要和#include导入别的文件的声明区分开来. 因为一份文件A使用#include导入别的文件的声明P就好像声明P直接写在A的#include处一样.

原型作用域

就是函数原型声明中的参数,该参数可以省略,而且不必和函数实现(或者说函数定义)中的形参的名字一致.

####