为什么我不能在函数内定义我之前声明的extern变量?

3

我对编程一般和特别是C++还很新。我使用以下文件制作了一个程序:

my.h

extern int foo;
void print_foo();

my.cpp

#include <iostream>
#include "my.h"


void print_foo(){
    std::cout << "foo = " << foo <<std::endl;

}

use.cpp

#include "my.h"

int main(){
    int foo = 7;
    print_foo();
}

当我尝试编译它时,我会收到错误消息“未定义对foo的引用”,但是当我在main()函数外定义foo时,它可以正常工作。为什么会这样?

use.cpp

#include "my.h"

int foo;

int main(){
    foo = 7;
    print_foo();
}

6
int foo = 7; 是一个局部变量,它只在 main 函数中有效。它与同名的 extern 变量不是同一个东西,因为后者从未被定义。如果想了解词法作用域、声明和定义等相关知识,可以参考一本好书 - molbdnilo
1
当你在函数内部声明一个变量(在这种情况下,是main函数内的foo),这个变量就不能在函数范围之外访问。它在第二种情况下起作用是因为foo是在全局范围内声明的。 - M. Yousfi
1
@463035818_is_not_a_number 我同意,但是仅使用 extern int foo; 声明了变量 foo,但没有定义它。 - M. Yousfi
1
@463035818不是一个数字。它是一个全局变量的声明,必须在某个地方定义,而main()中的那个不算。 - user207421
2
新程序员为什么应该从 externstatic 对象入手?它们是大的“不行”的。它们的使用情况限定在特定情况下,而且好的实现不会在 API 中使用它们。 - Red.Wave
显示剩余2条评论
3个回答

3
当我尝试编译它时,我收到错误消息“未定义对`foo'的引用”。
因为当你在main内定义foo时,它是局部的,只能在main函数内使用。但是你在print_foo内使用的foo是一个全局的foo,你没有定义(全局)。

基本上,extern int foo;(在您的程序中)声明了一个名为foo全局变量,而在print_foo中使用的foo是您从未定义的全局声明foo

但是当我像下面这样在main()函数外定义foo时,它可以正常工作

在这种情况下,由于您已经全局定义了foo并且由于print_foo内部的foo指向全局声明的foo,因此在这种情况下程序按预期工作,因为全局定义的foo可用。


2

正如你已经发现的那样,你无法这样做,因为外部变量和函数局部变量是完全不同的东西

而且你应该能够自己推断出这一点,因为:

  • 当你在函数内声明一个变量时,该变量只在函数作用域内可见,对于函数外部的任何东西都是不可见的。

  • 当你在全局作用域中声明一个变量时,该变量当然可被任何东西看到和使用。

因此,如果以某种神奇的方式使该函数局部变量定义满足extern变量定义,那么你将会使一个函数局部变量在全局作用域中可见,这是没有意义的,编程语言的整个目的就是防止这类事情发生,由于全局变量存储在数据段中,而函数局部变量存储在堆栈上等原因,这是物理上不可能的。


2

简短回答你的问题是,范围很重要。例如,这个程序中的每个foo都是自己的变量,它们都指向不同的东西/值/内存位置/或者你想怎么称呼它都可以:

int foo;

void stuff(int foo) { ... }

void thing() {
  int foo;
}

namespace bla {
  int foo;
}

我甚至不确定从哪里开始长篇回答,所以我会引荐您参考《C++权威指南》书单


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接