C语言中,作用域(scope)指的是一个变量或函数在程序中有效(可见)的区域。换句话说,作用域决定了你在程序的哪些部分可以访问和使用某个变量或函数。变量仅在创建区域内可用。 这称为作用域(scope)。本主主要介绍一下C语言中的作用域(scope)。

1、局部变量

一般指在函数中由{ }包括的代码块。它更多起分割作用,在这个代码块内部定义的变量就具有块作用域。例如函数内部的代码块或者像for循环、if语句等内部的代码块。虽然函数的形式参数声明在函数的左花括号之前,但也具有块作用域,属于函数体这个块。定义在函数内部的变量称为局部变量(Local Variable),它的作用域仅限于函数内部, 离开该函数后就是无效的,再使用就会报错。

例如,

#include <stdio.h>
int fn(int a){
    int b,c;  //a,b,c仅在函数fn()内有效
    return a+b+c;
}
int main(){
    int m,n;  //m,n仅在函数main()内有效
    return 0;
}

2、全局变量

C语言中,全局作用域是指在整个程序(所有源文件)中都可见的标识符。全局作用域的变量和函数可以在任何源文件中被访问。全局变量具有这种作用域,其作用范围是整个源文件,从定义处开始一直到文件末尾都是可见的。并且全局变量的生命周期持续到程序结束。在所有函数外部定义的变量称为全局变量(Global Variable),它的作用域默认是整个程序,也就是所有的源文件,包括 .c 和 .h 文件。使用 static 可以限制全局变量的作用域,使其只在定义它的文件中可见,这样它就只具有文件作用域。

例如,

#include <stdio.h>
int a=3;        //全局变量 
static int b=4; // 当前源文件中可见
void fn(){
   printf("%d\n %d\n",a,b);
}
int main(){
    fn(); 
    printf("%d\n %d\n",a,b);
    return 0;
}

3、函数作用域

在函数内部定义的一些变量,只能在函数内部使用,一旦离开了这个函数就必须重定义。函数内部形成了一个独立的作用域区域,函数中的变量与外界是隔离的,外部无法直接访问函数内部定义的变量,函数内部也不能直接访问外部的变量(除非通过函数参数传递或者全局变量等方式)。

#include <stdio.h> 
void function() { 
    int local_variable = 10; 
    // local_variable只能在function函数内部使用 
    printf("%d", local_variable); 
} 
int main() { 
    function(); 
    // 这里不能直接访问local_variable 
    return 0; 
} 

4、文件作用域

文件作用域是指在一个源文件中定义的标识符(如变量或函数)在该文件的整个范围内有效。文件作用域的标识符只能在定义它的源文件中被访问,其他源文件无法直接引用。

#include <stdio.h>
// file1.c
int fileScopedVar = 10; // 文件作用域

void fn() {
    printf("%d\n", fileScopedVar); // 可以访问
}

int main(){
    fn(); 
    printf("%d\n",fileScopedVar);
    return 0;
}

5、局部变量与全局变量的区别

1)局部变量是声明在块或者函数内部的变量。局部变量的作用域局限于该块或者函数。局部变量如果没有初始化,将包含垃圾数据。

2)全局变量是在所有块和函数之前声明的变量。全局变量对所有在它之后声明的函数有效。全局变量有默认值初始化,如0

注意:如果要调用另外一个文件中的全局变量,如果再声明一个同名的全局变量,那么编译器会因为重名报错,此时就要使用extern变量。extern声明告诉编译器这个变量的定义在其他文件中,所以并不会为它分配内存。

// file1.c
#include <stdio.h>

int globalVar = 10; // 定义全局变量

void printGlobal() {
    int localVar = 5; // 局部变量
    printf("Inside function:\n");
    printf("Local variable: %d\n", localVar);   // 输出局部变量
    printf("Global variable: %d\n", globalVar);  // 输出全局变量
}

// file2.c
#include <stdio.h>

// 声明全局变量
// 使用 extern 关键字声明访问
// 其它文件中全局变量
extern int globalVar; 

void modifyGlobal() {
    globalVar += 5; // 修改全局变量
}

int main() {
  // 输出全局变量
  printf("Global variable: %d\n", globalVar); 
  // printf("Local variable: %d\n", localVar); 
  // 错误:localVar 不能在这里访问
  printGlobal();
  modifyGlobal();
  printGlobal();
  return 0;
}

6、全局作用域和文件作用域区别

文件作用域是相对于单个源文件而言的,而全局作用域则是整个程序的范围。文件作用域的标识符只能在定义它的源文件中被访问,其他源文件无法直接引用。全局作用域的标识符可以被多个源文件共享,前提是它们没有使用 static 关键字进行限制。

#include <stdio.h>

// 全局变量:全局作用域
int globalVar = 10; // 可以在任何文件中访问

// 文件作用域的变量:只在此文件中可见
static int fileScopedVar = 20; // 文件作用域

void function1() {
    printf("In function1:\n");
    printf("Global Variable: %d\n", globalVar); // 可以访问全局变量
    printf("File Scoped Variable: %d\n", fileScopedVar); // 可以访问文件作用域变量
}

void function2() {
    printf("In function2:\n");
    printf("Global Variable: %d\n", globalVar); // 可以访问全局变量
    // printf("File Scoped Variable: %d\n", fileScopedVar); // 不可访问,编译错误
}

int main() {
    function1();
    function2();
    return 0;
}

7、静态局部变量和静态全局变量区别

1)静态全局变量则限制了其作用域, 即只在定义该变量的源文件内有效,在同一源程序的其它源文件中不能使用它。

2)静态局部变量作用域仅限于定义它的函数,能够在多次函数调用之间保持状态。

#include <stdio.h>

// 静态全局变量
static int globalVar = 0; // 静态全局变量

void modifyGlobalVar() {
    globalVar++;
    printf("Global Variable: %d\n", globalVar);
}

void staticLocalVarExample() {
    static int count = 0; // 静态局部变量
    count++;
    printf("Count: %d\n", count);
}

int main() {
    // 调用静态局部变量示例
    printf("Static Local Variable Example:\n");
    for (int i = 0; i < 5; i++) {
        staticLocalVarExample(); // 每次调用,count 保持其上次的值
    }

    // 调用静态全局变量示例
    printf("\nStatic Global Variable Example:\n");
    for (int i = 0; i < 2; i++) {
        modifyGlobalVar(); // 输出全局变量的值
    }

    return 0;
}

推荐文档