Linux C 编程教程第 10 部分 - 变量作用域
如果您正在学习我们的 C 编程教程系列,您应该了解变量的概念。虽然我们已经讨论了变量的基础知识,但还有另一个与变量相关的重要方面将在此处讨论:变量范围。
让我们从我们在之前的教程之一中使用的交换值代码开始:
#include <stdio.h>
void swap (int val1, int val2)
{
int temp = 0;
temp = val1;
val1 = val2;
val2 = temp;
printf("\nSwapped values are: %d and %d", val1,val2);
}
int main()
{
int a=0, b=0;
printf("Enter two integer values\n");
scanf("%d %d",&a,&b);
printf("Entered values are: %d and %d", a,b);
swap(a,b);
return 0;
}
在这里,在这段代码中,变量 val1 和 val2 具有局部作用域,这意味着它们在函数 swap 被调用时活跃起来,并且在对 swap 的调用结束后立即消失。您只是无法在调用函数交换之前或之后访问 val1 和 val2。类似地,变量 a 和 b 的作用域也是局部的——局部于函数 main。
请注意,这些局部作用域变量也称为自动变量。
现在,虽然具有局部作用域的变量仅限于声明它们的块,但还有另一种类型的变量,其作用域是全局的。顾名思义,全局作用域变量可以跨函数使用。例如,变量 var 是一个全局整数变量,可以在 main 和 swap 函数中使用。
#include <stdio.h>
int var;
void swap (int val1, int val2)
{
int temp = 0;
temp = val1;
val1 = val2;
val2 = temp;
printf("\nSwapped values are: %d and %d", val1,val2);
}
int main()
{
int a=0, b=0;
printf("Enter two integer values\n");
scanf("%d %d",&a,&b);
printf("Entered values are: %d and %d", a,b);
swap(a,b);
return 0;
}
默认情况下,值 0 分配给全局变量。但局部变量不是这种情况——您需要在定义它们时为它们赋值,否则它们将持有垃圾值。例如,在下面的程序中:
#include <stdio.h>
int var;
int main()
{
int a;
printf("Local variable 'a' currently holds: %d", a);
printf("\n Global variable var currently holds: %d", var);
return 0;
}
您很可能会得到 a 的非零值。另一方面,var 在开始时始终为零。
继续,可以有同名的全局变量和局部变量吗?嗯,答案是肯定的。好的,那么下面这段代码会输出什么:
#include <stdio.h>
int var = 5;
int main()
{
int var = 10;
printf("Local variable 'a' currently holds: %d", var);
printf("\n Global variable var currently holds: %d", var);
return 0;
}
那么,两种情况下的输出都是 10。原因是,局部变量 var 将覆盖全局 var。那么现在下一个合乎逻辑的问题是,在这种情况下如何访问 main 中的全局变量?可悲的是,答案是否定的。事实上,在使用 C 语言时,您应该避免陷入此类情况。
接下来是外部变量的概念。用外行术语来说,通过在任何变量声明中使用关键字 extern,您就是在告诉编译器该变量已经在其他地方声明/定义,并且只是在这里使用它。例如,在下面的代码中,编译器在尝试编译 main 函数中的 printf 语句时并不知道 var 的存在。
#include <stdio.h>
int main()
{
printf("\n Global variable var currently holds: %d", var);
return 0;
}
int var = 5;
这就是为什么在编译过程中会出现如下错误:
main.c: In function ‘main’:
main.c:14:58: error: ‘var’ undeclared (first use in this function)
printf("\n Global variable var currently holds: %d", var);
^
main.c:14:58: note: each undeclared identifier is reported only once for each function it appears in
但是,如果您在这里将 var 声明为 extern,您会发现一切正常。那是因为编译器最终会得到原始的 var 声明。
#include <stdio.h>
int main()
{
extern int var;
printf("\n Global variable var currently holds: %d", var);
return 0;
}
int var = 5;
你得到正确的输出:
Global variable var currently holds: 5
这就是 extern 的工作原理。当您的程序/项目被拆分为多个源代码文件并且您希望在文件 1 中使用文件 2 中定义的变量时,通常会使用外部变量。
最后,当我们讨论变量范围时,如果我们在这里也讨论静态变量会更好。静态变量的特殊之处在于它们即使在超出范围后仍保留其值。这意味着它们只被初始化一次,这是第一次。
static int counter
下面是一段代码,它使用静态变量来计算函数被调用的次数。
#include <stdio.h>
int swap (int val1, int val2)
{
static int counter = 1;
int temp = 0;
temp = val1;
val1 = val2;
val2 = temp;
printf("\n Function called %d times\n", counter);
counter++;
}
int main()
{
int a=9, b=4;
swap(a,b);
swap(a,b);
swap(a,b);
return 0;
}
继承人的输出:
Function called 1 times
Function called 2 times
Function called 3 times
所以你可以看到,变量 counter 即使在超出范围后仍保留其值。与全局变量一样,静态变量也有默认值 0。
在本教程中,我们讨论了几个重要的概念,它们都与 C 编程语言中的变量范围有关。不要忘记创建自己的程序以更好地理解外部变量、静态变量、全局变量和局部变量之间的区别。和往常一样,如有任何疑问或疑问,请在下方发表评论。