1. 主页
  2. 文档
  3. C语言教程
  4. C语言变量
  5. C 中的作用域规则

C 中的作用域规则

标识符的作用域是程序中可以直接访问标识符的部分。在 C 中,所有标识符都是词法(或静态)范围的。C 作用域规则可以涵盖在以下两个类别中。

基本上有4个作用域规则:

范围 意义
文件作用域 标识符的作用域从文件的开头开始,到文件的结尾结束。它仅指那些在所有函数之外声明的标识符。文件作用域的标识符在整个文件中都是可见的 具有文件作用域的标识符是全局的
块作用域 标识符的作用域从块/'{‘的开头开始,到块/’}’的末尾结束。具有块作用域的标识符是其块的本地标识符
函数原型作用域 在函数原型中声明的标识符在原型中是可见的
函数作用域 函数作用域从函数的开头开始,到函数的关闭结束。函数作用域仅适用于标签。声明的标签用作 goto 语句的目标,并且 goto 和标签语句必须在同一个函数中

让我们通过示例讨论每个作用域规则。 

文件作用域:这些变量通常在程序顶部的所有函数和块之外声明,并且可以从程序的任何部分访问。这些也称为全局范围变量,因为它们可以被全局访问。 

示例 1:

// C program to illustrate the global scope

#include <stdio.h>

// Global variable
int global = 5;

// global variable accessed from
// within a function
void display()
{
printf("%d\n", global);
}

// main function
int main()
{
printf("Before change within main: ");
display();

// changing value of global
// variable from main function
printf("After change within main: ");
global = 10;
display();
}

输出: 

Before change within main: 5
After change within main: 10

示例 2:


// filename: file1.c

int a;

int main(void)
{
a = 2;
}
// filename: file2.c
// When this file is linked with file1.c, functions
// of this file can access a

extern int a;

int myfun()
{
a = 2;
}

注意:要限制仅访问当前文件,可以将全局变量标记为静态。

块作用域:块是一组包含在左右大括号内的语句,即分别为“{”和“}”。块可以嵌套在 C 中(一个块中可能包含其他块)。在块内声明的变量可在块内和该块的所有内部块中访问,但在块外不可访问。基本上,这些对于定义变量的块来说是本地的,并且无法在外部访问。

#include <stdio.h>

// Driver Code
int main()
{
{
int x = 10, y = 20;
{
// The outer block contains
// declaration of x and
// y, so following statement
// is valid and prints
// 10 and 20
printf("x = %d, y = %d\n", x, y);
{
// y is declared again,
// so outer block y is
// not accessible in this block
int y = 40;

// Changes the outer block
// variable x to 11
x++;

// Changes this block's
// variable y to 41
y++;

printf("x = %d, y = %d\n", x, y);
}

// This statement accesses
// only outer block's
// variables
printf("x = %d, y = %d\n", x, y);
}
}
return 0;
}

输出: 

x = 10, y = 20
x = 11, y = 41
x = 11, y = 20

函数原型作用域:这些变量作用域包括在函数参数列表中。这些变量的作用域从函数原型中的声明之后开始,一直到声明列表的末尾。这些作用域不包括函数定义,而只是函数原型。 

例子:

// C program to illustrate
// function prototype scope

#include <stdio.h>

// function prototype scope
//(not part of a function definition)
int Sub(int num1, int num2);

// file scope
int num1;

// Function to subtract
int Sub(int num1, int num2)
{
return (num1-num2);
}

// Driver method
int main(void)
{
printf("%d\n", Sub(10,5));
return 0;
}

输出: 

5

函数作用域:函数作用域从函数的打开开始,到函数的关闭结束。功能范围仅适用于标签。声明的标签用作转到语句的目标,并且 goto 和标签语句必须在同一个函数中。 

例子:


void func1()
{
{
// label in scope even
// though declared later
goto label_exec;

label_exec:;
}

// label ignores block scope
goto label_exec;
}

void funct2()
{

// throwserror:
// as label is in func1() not funct2()
goto label_exec;
}

现在可能会出现关于变量访问范围的各种问题: 

如果内部块本身有一个同名变量怎么办?
如果内部块声明了一个与外部块声明的变量同名的变量,则外部块变量的可见性在内部块声明的点结束。

传递给函数的函数和参数呢?
函数本身就是一个块。函数的参数和其他局部变量遵循相同的块范围规则。

可以在另一个后续块中访问该块的变量吗?
不可以,在块中声明的变量只能在块内部和该块的所有内部块中访问。 

例如,以下程序会产生编译器错误。 

int main()
{
{
int x = 10;
}
{
// Error: x is not accessible here
printf("%d", x); 
}
return 0;
}

错误:

prog.c: In function 'main':
prog.c:8:15: error: 'x' undeclared (first use in this function)
  printf("%d", x); // Error: x is not accessible here
               ^
prog.c:8:15: note: each undeclared identifier is 
reported only once for each function it appears in

例子: 

// C program to illustrate scope of variables

#include<stdio.h>

int main()
{
// Initialization of local variables
int x = 1, y = 2, z = 3;

printf("x = %d, y = %d, z = %d\n",
x, y, z);
{

// changing the variables x & y
int x = 10;
float y = 20;

printf("x = %d, y = %f, z = %d\n",
x, y, z);
{

// changing z
int z = 100;
printf("x = %d, y = %f, z = %d\n",
x, y, z);
}
}
return 0;
}

输出: 

x = 1,y = 2,z = 3
x = 10,y = 20.000000,z = 3 
x = 10,y = 20.000000,z = 100

 

这篇文章对您有用吗?