📜  C中的范围规则

📅  最后修改于: 2021-05-26 00:55:54             🧑  作者: Mango

标识符的范围是程序的一部分,可以直接访问标识符。在C语言中,所有标识符都在词法(或静态)范围内。 C范围规则可以分为以下两类。

基本上有4个范围规则:

Scope Meaning
File Scope Scope of a Identifier starts at the beginning of the file and ends at the end of the file. It refers to only those Identifiers that are declared outside of all functions. The Identifiers of File scope are visible all over the file Identifiers having file scope are global
Block Scope Scope of a Identifier begins at opening of the block / ‘{‘ and ends at the end of the block / ‘}’. Identifiers with block scope are local to their block
Function Prototype Scope Identifiers declared in function prototype are visible within the prototype
Function scope Function scope begins at the opening of the function and ends with the closing of it. Function scope is applicable to labels only. A label declared is used as a target to goto statement and both goto and label statement must be in same function

让我们用示例讨论每个范围规则。

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

范例1:

C
// C program to illustrate the global scope
 
#include 
  
// 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();
}


C
// filename: file1.c
 
int a;
 
int main(void)
{
   a = 2;
}


C
// 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 
 
// 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;
}


C
// C program to illustrate
// function prototype scope
 
#include 
  
// 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;
}


C
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;
}


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


C
// C program to illustrate scope of variables
 
#include
 
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;
}


输出:

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

范例2:

C

// filename: file1.c
 
int a;
 
int main(void)
{
   a = 2;
}

C

// 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中(一个块中可能包含其他块)。在块内声明的变量可在该块以及该块的所有内部块中访问,但不能在该块外部访问。基本上,这些变量对于定义了变量的块来说是局部的,无法在外部访问。

C

#include 
 
// 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

// C program to illustrate
// function prototype scope
 
#include 
  
// 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和label语句必须在同一函数。

例子:

C

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;
}

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

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

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

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

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

C

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

// C program to illustrate scope of variables
 
#include
 
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
想要从精选的最佳视频中学习和练习问题,请查看《基础知识到高级C的C基础课程》。