05、作用域介绍
本文主要介绍下C语言中作用域的概念。
作用域是编程中的一个核心概念,它定义了变量、函数等标识符的可访问范围。
本文会深入探讨C语言中的作用域规则,包括全局作用域、文件作用域(静态全局作用域)、函数作用域,以及块作用域。
全局作用域
全局作用域是指在程序的所有部分都可以访问的标识符。在C语言中,全局变量和全局函数拥有全局作用域。当你在函数外部声明一个变量或函数时,它们就拥有了全局作用域。
// global_example.c
#include <stdio.h>
int globalVar = 100; // 全局变量
void globalFunction() {
printf("This is a global function.\n");
}
void anotherFunction() {
printf("Accessing global variable: %d\n", globalVar);
globalFunction();
}
int main() {
printf("Global variable in main: %d\n", globalVar);
globalFunction();
anotherFunction();
return 0;
}
在上例,globalVar
和globalFunction
都可以在任何函数内部被访问,包括main
函数和anotherFunction
函数。
多文件共享全局变量
当一个项目包含多个源文件时,可能需要在多个文件中访问同一个全局变量。这时,可以使用extern
关键字来声明变量,而不定义它,告诉编译器该变量在其他地方定义。
file1.c:
#include <stdio.h>
int sharedVar = 50; // 定义全局变量
file2.c:
#include <stdio.h>
extern int sharedVar; // 声明全局变量
void printSharedVar() {
printf("Shared variable value: %d\n", sharedVar);
}
main.c:
#include <stdio.h>
extern int sharedVar; // 再次声明,以便在main中使用
void printSharedVar(); // 声明file2.c中的函数
int main() {
printf("Initial shared variable value: %d\n", sharedVar);
sharedVar = 100; // 修改全局变量的值
printSharedVar(); // 调用file2.c中的函数,验证值的变化
return 0;
}
编译并链接这些文件后,程序将正常运行,显示全局变量sharedVar
的修改效果。
限制全局变量的可见性
使用static
关键字可以将全局变量的作用域限制在定义它的文件内,这样其他文件就无法访问这个变量。
file_static.c:
#include <stdio.h>
static int fileScopeVar = 200; // 文件作用域变量
void printFileScopeVar() {
printf("File scope variable: %d\n", fileScopeVar);
}
在这个文件中,fileScopeVar
只能在file_static.c
内部被访问,其他文件即使使用extern
声明也无法访问它。
其实整体比较好理解,如果在一个源文件中定义了一个全局变量,那这个变量的作用域就是整个源文件。
比如:
// test.cc
int global = 1;
void func() {
cout << global;
}
void func2() {
cout << global;
}
注意这里global
的作用域是在作用在整个源文件中,只在本文件内可访问。
而一个应用程序可以由多个源文件组成,在其他文件其实也可以访问这个global
变量,但是不能直接访问,比如:
// test2.cc
void func() {
cout << global;
}
void func2() {
cout << global;
}
这样是不能编译通过的,这里需要在test2.cc
中使用extern
声明一下:
// test2.cc
extern int global;
void func() {
cout << global;
}
void func2() {
cout << global;
}
这里的extern int global;
表示在声明一个global变量,但却不在此文件内定义,它的定义会存在于其他源文件中。
通过extern
声明后,在test2.cc
中就可以访问test.cc
中的global全局变量了。
那有没有办法定义一个全局变量,只在当前源文件内可访问,其它源文件不可见呢?
可以,加个static
关键字:
// test.cc
static int global = 1;
void func() {
cout << global;
}
void func2() {
cout << global;
}
static
在这里表示局部的含义,表示只在当前源文件可见。在开发的过程中大家如果有上面的需求(只希望在源文件内可见),无论是变量还是函数,建议都使用static
修饰。
函数作用域
函数作用域主要指的是函数内部定义的变量,这些变量只能在函数体内被访问,函数外部无法访问。
所有在函数内部定义的变量默认具有函数作用域(也称为局部变量)。
#include <stdio.h>
void exampleFunction() {
int localVar = 10; // 局部变量
printf("Local variable inside function: %d\n", localVar);
}
int main() {
exampleFunction();
// printf("Trying to access localVar: %d\n", localVar); // 错误:localVar未声明
return 0;
}
在main
函数中尝试访问localVar
会导致编译错误,因为localVar
的作用域仅限于exampleFunction
内部。
块作用域
块作用域是指由一对花括号{}
包围的代码块内定义的变量的作用域。任何在块内定义的变量只能在该块内访问,包括函数内的局部块。
#include <stdio.h>
void blockScopeExample() {
int a = 10;
if (1) {
int b = 20; // 块作用域变量
printf("Inside if block, b = %d\n", b);
}
// printf("Trying to access b: %d\n", b); // 错误:b未声明
printf("Outside if block, a = %d\n", a);
}
int main() {
blockScopeExample();
return 0;
}
在这个例子中,变量b
的作用域仅限于if
语句块内,一旦出了这个块,b
就无法被访问。
静态变量
在C语言中,static
关键字除了用于限制全局变量的作用域外,还可以用于函数内的局部变量,使其具有静态存储持续时间。这意味着即使函数执行完毕,变量的值也不会丢失,下次调用该函数时,变量将保持上次的值。
#include <stdio.h>
void staticExample() {
static int count = 0; // 静态局部变量
count++;
printf("Count = %d\n", count);
}
int main() {
staticExample();
staticExample();
staticExample();
return 0;
}
每次调用staticExample
函数时,count
的值都会递增,因为count
是静态局部变量,其生命周期贯穿程序的整个运行过程,但其作用域仍限制在staticExample
函数内。
注意:上面的各种概念可能和书本上的不太一样,我是本着易于理解的角度来介绍的,可能有些概念整理的不是很书面且标准。
