提问人:pvasbob 提问时间:9/20/2023 最后编辑:pvasbob 更新时间:9/21/2023 访问量:47
在 Header 中定义的全局变量。其他函数调用可以看到其变化
Global variables defined in Header. Other function call can see its changes
问:
我有一个 .h 文件和两个 .cpp 文件:
global_var.h fun.cpp main.cpp
详情如下:
global_var.h:
extern int a;
void fun();
趣味.cpp
#include <iostream>
#include "global_var.h"
void fun()
{
int a = 10;
std::cout << "Print out in fun() " << a << std::endl;
}
main.cpp
#include <iostream>
#include "global_var.h"
int main()
{
int a;
fun();
std::cout << "Print out in main: " << a << std::endl;
return 0;
}
还有一个 makefile:
ALL = main.o fun.o
Target = main
CC = g++
$(Target): $(ALL)
$(CC) -o $(Target) $(ALL)
clean:
rm *.o
代码的输出是:
Print out in fun() 10
Print out in main: 0
在 main 函数中,对 fun() 的调用将 a 修改为 10,然后在 main 中再次打印出 a。我认为fun()的变化也可以在main中看到,所以我期望的输出是:
Print out in fun() 10
Print out in main: 10
知道如何实现这一目标吗?
我的最终目标是拥有如下结构:
global_var.h
// 定义(或声明。如果我使用了错误的术语,请纠正我)所有变量都共享给下面定义的所有函数。
func1.h func1.cpp /
/ 包含global_var.h,定义func1,可以在global_var.h中使用或修改变量
func2.h func2.cpp /
/ 包含global_var.h,定义 func2 可以使用或修改 global_var.h 中的变量
.......
main.cpp
//包含上面的所有 .h 文件。这里的函数调用可以看到其他函数调用引入的变量的修改。
谢谢!
答:
您尚未定义全局变量。您已经声明了一个变量,然后在两个不同的地方定义了具有相同名称的局部变量。注意,您的程序具有未定义的行为,因为您使用了 的值 而没有初始化它。main
a
你是故意这样做的吗?
趣味.cpp
#include <iostream>
#include "global_var.h"
int a; // definition at namespace scope.
void fun()
{
a = 10; // assignment, not definition with initialiser
std::cout << "Print out in fun() " << a << std::endl;
}
main.cpp
#include <iostream>
#include "global_var.h"
int main()
{
// a is declared in the header, don't declare it again
fun();
std::cout << "Print out in main: " << a << std::endl;
return 0;
}
但是,我对全局可变状态的建议是:不要。随着程序规模的增大,你会发现越来越难推理任何单个部分的作用,因为你无法跟踪它读取和写入的状态。
评论
class
private
你的标题确实如此
extern int a;
不是(与您的描述相反)的定义。它是 的声明。尽管所有变量定义都是(类型)声明,但并非所有变量声明都是定义。a
a
您的任何源文件中都没有对此进行定义。a
相比之下,两者都定义了一个变量,该变量是各自功能块的局部变量,名为 。所以 in 与 in 不同。此外,这两个 s 都与标头中声明的 s 不同。有些人会说函数中的 s 隐藏了标头中声明的 s(这意味着,在这两个函数中,每个函数中定义之后的用法指的是本地的,而不是标头中声明的那个)。main()
fun()
a
a
main()
a
fun()
a
a
a
a
a
a
程序从不使用标头中声明的变量。因此,您的程序可以成功构建(尽管声明了标头中的变量,但它未在任何地方使用,因此不需要定义)。a
如果我们要更改您的一个(且只有一个)源文件以添加另一个函数
void fun2()
{
a = 10;
std::cout << "Print out in fun2() " << a << std::endl;
}
这与你的工作方式不同,因为前面的内容已被删除。这是一个很小的变化(大约三个删除的字符),但效果是显着的;fun2()
fun()
int
a = 10
- in 的用法为 DOES 为标头中声明的变量赋值。
a
fun2()
a
- 由于使用了标头中声明的变量,因此必须对其进行定义。
- 如果没有定义,那么在大多数工具链中,您的程序将编译(在将 .cpp 文件转换为对象的意义上),但不会链接(即不会从目标文件生成可执行文件,如果没有可执行文件,您的程序就无法运行)。
如果你想被调用,那么你可以在某处添加它的调用(例如,如果你在上面的 main.cpp 中定义,请从 调用它)。fun2()
fun2()
main()
main()
为了使我们修改后的程序成功构建,我们现在需要定义那个讨厌的.这必须在一个(并且只有一个)源文件中完成,在 ing 标头之后(以及任何函数之外),像这样的一行a
#include
int a; // alternatively int a = 42; to initialise to non-zero
请注意,如果将其添加到多个源文件中,则会破坏单一定义规则(实际上,这通常意味着由于多次定义符号,程序将不会链接)。
但是,除非您进行适当的修改,否则它们都不会引用标头中声明的内容。fun()
main()
a
评论
int a = 10;
函数内部隐藏全局变量。你是说吗?无论如何,你的设计看起来是个坏主意。a = 10;
a