📜  C |变量声明和范围|问题2(1)

📅  最后修改于: 2023-12-03 15:29:43.523000             🧑  作者: Mango

C语言变量声明和范围的问题

问题描述

在C语言中,变量的声明和范围是很关键的概念。声明和定义变量的位置和作用域会影响程序的正确性和性能。以下是两个常见问题:

  1. 在函数中定义变量时,调用完函数后该变量的值怎么处理?
  2. 在多个源文件中定义同名变量时,链接器会如何处理?
变量的作用域

在C语言中,变量的作用域分为全局作用域和局部作用域两种。局部作用域的变量只在声明该变量的代码块内有效,而全局作用域的变量在整个程序中都可以使用。

局部变量

局部变量只在声明该变量的代码块内有效,包括以下场合:

  • 函数内部定义的变量
  • for循环、while循环等语句块中定义的变量
  • if语句块中定义的变量

例如:

void func() {
    int i = 0;
    printf("%d", i);
}

在上述代码中,变量i的作用域只在函数func内部,func调用结束后,i的值就不存在了。

全局变量

全局变量在整个程序中都可以使用,它的作用域从变量声明处开始,到程序结束或变量被其他函数或模块覆盖为止。

例如:

#include <stdio.h>

int i = 0;

void func() {
    i++;
}

int main() {
    func();
    printf("%d", i);
    return 0;
}

在上述代码中,变量i的作用域为整个程序,因此在func函数中加1后,在main函数中输出的值为1。

变量的存储类别

变量的存储类别有auto、register、static和extern四种。

auto变量

auto变量声明后,系统会分配存储空间,在程序执行完该变量所在的函数或代码块时,该变量就会被释放。

例如:

void func() {
    auto int i = 0;
    printf("%d", i);
}

在上述代码中,变量i被声明为auto变量,该变量的作用域只在函数func内部,调用结束后i的值就不存在了。

register变量

register变量与auto变量类似,只是将变量存储在CPU的寄存器中,以加快对变量的访问。不同的编译器可能会对register变量有不同的实现。

例如:

void func() {
    register int i = 0;
    printf("%d", i);
}

与auto变量类似,在上述代码中,变量i的作用域只有在函数func内部,调用结束后i的值就不存在了。

static变量

static变量可以声明为静态变量,即在函数调用结束后,该变量的值不会被释放。静态变量与全局变量类似,都是存储在静态存储区中的变量。

例如:

void func() {
    static int i = 0;
    i++;
    printf("%d", i);
}

在上述代码中,变量i被声明为static变量,该变量的作用域只在函数func内部,但在函数调用结束后,i的值不会被释放,下一次调用func函数时,i的值依旧会保留。

extern变量

extern变量用于引用其他源文件或模块中定义的全局变量或函数。当程序调用引用到extern变量时,编译器会在程序中搜索该变量或函数。

例如:

在文件a.c中定义了变量i:int i = 0;

在文件b.c中使用该变量:

extern int i;

void func() {
    i++;
    printf("%d", i);
}

在上述代码中,变量i被声明为extern变量,如果没有在代码中定义i的话,编译器就会在其他源文件或模块中搜索该变量的定义。如果找不到,编译就会出错。如果找到了,该变量的作用域就变为了整个程序。

链接器的处理

当多个源文件中定义了同一个变量时,链接器会根据符号表将它们链接成一个,成为唯一一个定义。当多个源文件中缺少同一个变量的定义时,链接器会报错,提示找不到该变量的定义。如果变量定义多次,可能会导致符号冲突的问题。

在源文件a.c中定义整型变量i:

int i = 0;

在源文件b.c中也定义整型变量i:

int i = 1;

在主函数中使用变量i:

#include <stdio.h>

int i;

int main() {
    printf("%d", i);
    return 0;
}

在上述代码中,由于定义了两个变量i,链接器会报错,提示找到了多个变量i的定义。如果将源文件b.c中的变量定义修改为:

extern int i;

则编译和链接都能正常通过,输出结果为0。

总结

变量的声明和作用域是C语言中很重要的概念,掌握它们对程序的正确性和性能都有很大的影响。在编写程序时,要注意变量的存储类别、作用域和链接的问题,避免符号冲突的问题。