为什么在头文件中声明和在文件中定义会产生多重定义错误
Why does Declaring in header file and defining in file gives multiple definition error?
我是c++编程新手。我对JAVA有更好的了解。所以使用hackerrank我正在尝试学习c++。为了跟踪每个程序的独立实体,我开始为每个程序或挑战使用头文件和程序文件。所以我试着做一个hackerrank练习,输入和输出(https://www.hackerrank.com/challenges/cpp-input-and-output)。所以我试着用这种方式实现我的程序;
InputAndOuput.h
#ifndef INPUTANDOUTPUT_H_
#define INPUTANDOUTPUT_H_
int arr[3];
int m;
int InputAndOutput();
#endif
InputAndOutput.cpp
#include "InputAndOutput.h"
#include<iostream>
#include<cmath>
#include<cstdio>
int InputAndOutput(){
int arr[3];
for(int i1 = 0; i1 < 3 ; i1++)
std::cin >> arr[i1];
for(int i = 0; i < 3 ; i++)
m = m + arr[i];
return m;
}
main.cpp
#include<iostream>
//#include<day1DataTypes>
#include<cmath>
#include<cstdio>
//#include "day1DataTypes.h"
#include "InputAndOutput.h"
int main()
{
int k = InputAndOutput(); \the error persists even the whole block is commented
std::cout << k << std::endl ;
}
这个给出了以下错误;
Description Resource Path Location Type
first defined here Hackerrank line 6 C/C++ Problem
first defined here Hackerrank line 8 C/C++ Problem
make: *** [Hackerrank] Error 1 Hackerrank C/C++ Problem
multiple definition of `arr' Main.cpp /Hackerrank line 9 C/C++ Problem
multiple definition of `m' Main.cpp /Hackerrank line 12 C/C++ Problem
请给我解释一下这个符号有什么问题。顺便说一句,我正在使用eclipse,它在编译时抛出错误。
为了解释最简单的问题,我们先来看一下"int arr[3];"
对于变量声明,它是在InputAndOutput.h头文件中声明和实现的。
main.cpp和InputAndOutput.cpp都包含头文件,因此实现了变量两次。
要声明变量,它可以在其他文件中使用,您可以使用:
InputAndOutput.h
extern int arr[3];
extern int m;
InputAndOutput.cpp
int arr[3];
int m;
这告诉编译器有两个变量,arr和m,它们在。h文件中声明,但在外部文件中实现,使用extern关键字。
请注意,你在问题中发布的代码仅仅是c++文件中的C。
在c++中,不鼓励使用全局变量来存储数据。
因此,如果您要删除全局变量并使用c++ stl容器,您将拥有以下内容:
InputAndOutput.h
#include <array>
int32_t InputAndOutput(std::array<int32_t, 3>& arr, int32_t& m);
InputAndOutput.cpp
int32_t InputAndOutput(std::array<int32_t, 3>& arr, int32_t& m)
{
for(auto i1 = 0; i1 < 3 ; i1++)
std::cin >> arr[i1];
for(auto i = 0; i < 3 ; i++)
m = m + arr[i];
return m;
}
main.cpp
int main()
{
auto arr = std::array<int32_t, 3>{0,0,0};
auto m = 0;
const auto k = InputAndOutput(arr, m);
std::cout << k << std::endl ;
}
现在,这应该照顾到你的大部分问题,然而,我没有看到在你的原始代码你是如何从std::cin获得输入,因为你没有提示用户输入…这会导致一个bug。
既然你在学习c++,你应该学习现代c++,而不是c++ 98。
我建议你仔细阅读https://github.com/isocpp/CppCoreGuidelines
并且,也可以查看Herb Sutter的网站,关于Almost-Always-Auto: https://herbsutter.com/2013/08/12/gotw-94-solution-aaa-style-almost-always-auto/
- 告诉CMake链接到自定义文件夹中的Boost
- 通过cMake使用具有自定义文件扩展名的共享库
- 威纳派读取自定义文件或文件夹的所有访问权限
- 使用命令列表解析自定义文件
- 单独的类声明和方法定义文件问题
- Qt解析自定义文件格式
- 将单独的头文件和类定义文件链接到主函数文件 - G++ 返回重载"undefined reference to"构造函数
- FAT32和NTF中的自定义文件属性
- 如何在没有"fatal error: Wt/WApplication: No such file or directory"的情况下将wt安装到自定义文件夹中
- C++ while 循环在自定义文件结构中
- QT C 读取自定义文件结构
- gcc 是否有编译指示来定义文件类型/编译器
- C/C++ 中的跨平台自定义文件头
- 使用头文件和类定义文件时未解决的外部符号错误
- 将此c++代码分解为单独的类规范文件和函数定义文件
- 自定义文件类中fstream对象的生存期
- 如何使用BinaryReader类使用C#读取自定义文件(C++)
- 提供带有libjpeg的自定义文件IO
- C++模块定义文件头内联符号
- 错误:未定义文件中的第一个引用符号