如何在多个文件中使用变量
How can I use variables in multiple files?
我想在标题中定义一个变量,并能够在多个文件中使用它。例如在某个地方定义了可变的a
,并且能够在p1.cpp和p2.cpp
这是一个示例,其中有3个简单的文件,即我要做的事情。
// vars.hpp
#ifndef VARS_HPP
#define VARS_HPP
int a = 1;
float b = 2.2;
void double_vars();
#endif
// vars.cpp
#include "vars.hpp"
void double_vars () {
a *= 2;
b *= 2;
}
// vars_main.cpp
#include <cstdio>
#include "vars.hpp"
int main () {
printf("a: %d; b: %fn", a, b);
double_vars();
printf("a: %d; b: %fn", a, b);
}
现在,用:
编译上述内容g++ -Wall -W -g vars.cpp vars_main.cpp -o vars && ./vars
给我以下错误:
/tmp/ccTPXrSe.o:(.data+0x0): multiple definition of `a'
/tmp/ccnc1vof.o:(.data+0x0): first defined here
/tmp/ccTPXrSe.o:(.data+0x4): multiple definition of `b'
/tmp/ccnc1vof.o:(.data+0x4): first defined here
有人可以向我解释为什么会发生这种情况?我的标题文件中有警卫,据我所知,只有一旦就可以包括在内,因此不应有多个声明
在标题文件中,写下:
extern int a;
extern float b;
这将声明变量。
在一个CPP文件中,写下:
int a = 1;
float b = 2.2;
这将定义变量。只要变量被精确定义一次,您将定义放置在哪个CPP文件上都无关紧要。
首先,不要这样做。全球可变状态通常是一件坏事。
问题是,一旦链接器完成了包含措施中的文件的结合,它已经看到了两次,一次在main.cpp中,一次在vars_main.cpp中:
int a = 1;
float b = 2.2;
如果仅将其放入标题文件中,则会以多个翻译单元显示,一次用于包含标头的每个cpp
文件。编译器不可能知道您在说哪个A和B。
解决此问题的方法是在标题中声明extern
:
extern int a;
extern float b;
这告诉编译器a和b是在某个地方定义的,不一定在代码的这一部分中。
然后,在您的一个CPP文件中,您将定义它们:
int a = 1;
float b = 2.2;
这样,a
和b
的存储空间有一个定义明确的位置,并且编译器可以正确连接点。
collin已经描述了问题和解决方案,但我想强调这是多么糟糕的样式。
您即使是从这个简单的练习中发现的,以这种方式使用全球群体通常是一件坏事。除了您已经发现的编译器问题外,使用Globals在功能之间共享状态会导致以下问题:
-
它使功能本身在其他程序中更难重复使用,因为该功能期望这些符号的存在;
-
更改一个函数可能会在共享该状态的其他功能中引起问题(即,更改未本地化到函数);
-
代码变得更难调试,因为任何人都可以随时修改
a
和b
。
理想情况下,函数应仅通过参数,返回值和异常(如果适用)进行通信;有时共享状态是正确的答案,但是相对较少,而且相对较远。
由于您显然使用了C 编译器,因此我将使用引用而不是指示器来执行C 的方式。我还将使用C iostream
例程,而不是cstdio
(写C或C ;尝试混合两个只会导致胃灼热)。
vars.hpp:
#ifndef VARS_H // Include guard to prevent multiple inclusion
#define VARS_H
void double_vars(int &, float &);
#endif
vars.cpp:
#include "vars.hpp"
void double_vars(int &x, float &y)
{
x *= 2;
y *= 2.0;
}
main.cpp:
#include <iostream>
#include "vars.hpp"
int main(void)
{
int a = 1;
float b = 2.2;
std::cout << "a: " << a << "; b: " << b << std::endl;
double_vars(a, b);
std::cout << "a: " << a << "; b: " << b << std::endl;
return 0;
}
由于x
和y
被称为参考类型(使用&
),因此在double_vars
中写入 expressions expressions x
and y
等于 a
和 b
inmain
。
c的方法是指代而不是参考文献:
vars.h:
#ifndef VARS_H // Include guard to prevent multiple inclusion
#define VARS_H
void double_vars(int *, float *);
#endif
vars.c:
#include "vars.h"
void double_vars(int *x, float *y)
{
*x *= 2;
*y *= 2.0;
}
main.c:
#include <stdio.h>
#include "vars.h"
int main(void)
{
int a = 1;
float b = 2.2;
printf("a: %d; b: %fn", a, b);
double_vars(&a, &b);
printf("a: %d; b: %fn", a, b);
return 0;
}
在这种情况下,我们使用指针而不是引用,因此我们需要将表达式的结果传递给double_vars
&a
和 &b
;在功能中,写入表达式*x
和*y
与a
和main
中的b
相同。
- 通过多个头文件使用常量变量
- 在 .h 文件中的类中声明静态变量和在.cpp文件中声明"global"变量有什么区别
- 如何从另一个文件继承私有成员变量和公共函数
- 在 Windows 上,是否可以让 dll 在不使用 PATH 环境变量的情况下在另一个文件夹中查找依赖项?
- 无法通过头文件保存变量的值
- 尝试调用 .h 文件中定义的变量时出现变量未定义错误
- 在 C++ 中将双精度变量写入二进制文件
- 如何使用文件中的文本,例如变量
- 定义C++新的环境变量并在 bat 文件中使用它
- 在头文件中定义变量不会出错
- 复制文件流C++静态变量
- 从另一个 cpp 文件更改结构内、映射键内的变量
- 在C++中使用变量而不是"#define"来指定数组大小是不是一种糟糕的做法?(C错误:在文件范围内
- C++将文本从.txt文件解析为变量
- 从 C 中的变量获取文件的路径,C++
- 可以在 cpp 文件中C++定义为特殊符号的变量β
- 如何使用可视化代码和平台IO将环境变量注入CPP文件?
- C++ 静态成员变量 - 文件之间的访问
- 正在创建一个集中式变量文件
- 静态成员变量文件作用域