我是C的新手,现在阅读一些教科书并开始应用它的例子。
问题是,每当我创建一个新项目并尝试放置包含main函数的多个文件时,链接器(正如我thougt0解释说的那样:
/home/mohammed/tmp/abcd/main.c:4: multiple definition of `main'
(BTW,我使用过很多IDE,MonoDevelop,QT创建者,VS2010,Codebloks,...) 我目前使用QT Creator,它似乎是一个非常好的IDE。
那么,解决这样的问题没有解决办法吗?
编辑:
我在问,因为我处于学习阶段,现在没有真正的编程。 我只需要一种简单的方法来在C中创建程序,而不必为每个书籍示例创建一个单独的项目。 同时,我不想使用Gedit / VI +命令行。
那么,是不是有任何方法,比如清理项目,然后编译 - 只需一个文件,我需要运行??? 顺便说一句,在JAVA中,我们可以运行一个程序,它包含多个主程序(IDE给我选择)
答案 0 :(得分:10)
你想用多个main
函数做什么?
如果您尝试一次编译多个不同的程序,则需要单独编译每个程序(即每个程序只编译一个main
)。
如果您正在尝试编译一个程序并希望运行多个main
函数 all ,则不能。您只需要指定一个main
并将其他人重命名为其他内容(并按照您希望它们运行的顺序从单个main
中调用它们。)
如果您尝试仅使用其中一个main
函数作为程序的单个入口点而忽略其他函数,那么当您使用其他main
时,不应包含这些文件正在联系。如果您希望保留它们,我建议将每个main
放在一个单独的文件中,并在链接/编译时只包含其中一个主文件。
如果您错误地收到此错误,那么您可能在IDE中执行了错误的项目。也许你不小心尝试将多个不同的程序编译成一个?您可能需要将包含main
的每个文件指定为单独的构建产品。 C与Java不同,您可以在每个类中放置main
方法并指定要调用的方法; C中的main
是全局名称。
答案 1 :(得分:5)
您的应用程序中不可能有多个入口点。 启动最终可执行文件时,将调用入口点函数(main)。而且这个不能含糊不清。
因此,如果您想逐个调用它们,您可以将它们链接起来:
void main1() {} /* Note that these aren't called main. */
void main2() {}
...
int main(int argc, char* argv[]) {
main1();
main2();
return 0;
}
您甚至可以使用线程(例如boost.Thread)调用它们,以便它们并行运行。
但是,您不能将多个名为main
的函数链接在一起。
如果您希望它们分别是单独的程序,则必须单独链接它们。
答案 2 :(得分:2)
每个程序必须只有一个主要功能。但是,main可以调用你想要的任何函数(包括它自己,虽然这可能会令人困惑)。因此,您应该将程序分解为逻辑部分。
答案 3 :(得分:2)
正如许多人所说,每个节目只能有一个主要节目。在阅读本书时,您不希望为每个示例创建一个新项目的麻烦。这是可以理解的,但基本上你必须这样做。我看到两种选择:
答案 4 :(得分:2)
如果每个main都对应于构建目录树中的不同可执行文件,那么在同一个项目中可以有多个main。
以下示例使用CMake,我不知道是否可以使用其他构建过程管理器软件。
将以下两个.cpp文件存储在名为 source 的文件夹中,并将其命名为square_root.cpp和power_of_two.cpp:
square_root.cpp:
#include <stdio.h>
#include <stdlib.h>
#include <math.h>
int main (int argc, char *argv[])
{
if (argc < 2) {
fprintf(stdout,"Usage: %s number\n",argv[0]);
return 1;
}
double inputValue = atof(argv[1]);
double outputValue = sqrt(inputValue);
fprintf(stdout,"The square root of %g is %g\n",
inputValue, outputValue);
return 0;
}
power_of_two.cpp:
#include <stdio.h>
#include <stdlib.h>
#include <math.h>
int main (int argc, char *argv[])
{
if (argc < 2) {
fprintf(stdout,"Usage: %s number\n",argv[0]);
return 1;
}
double inputValue = atof(argv[1]);
double outputValue = inputValue*inputValue;
fprintf(stdout,"The power of two of %g is %g\n",
inputValue, outputValue);
return 0;
}
请注意,它们都包含方法main。 然后,在同一个文件夹中,添加一个名为CmakeLists.txt的.txt:它会告诉编译器可执行文件的数量,如何调用它们以及在哪里找到main .s。
的CMakeLists.txt:
cmake_minimum_required (VERSION 2.6)
project (Square_and_Power)
add_executable(Square2 square_root.cpp)
add_executable(Power2 power_of_two.cpp)
在源的同一根中创建一个名为build的新文件夹,然后使用cmake进行配置和生成。看一下在文件夹构建中创建的文件夹的结构。 在构建中打开终端并键入 make 。
→ make
[ 50%] Built target Power2
Scanning dependencies of target Square2
[ 75%] Building CXX object CMakeFiles/Square2.dir/square_root.cpp.o
[100%] Linking CXX executable Square2
[100%] Built target Square2
如果没有错误发生,您将有两个可执行文件:Square2和Power2。
→ ./Square2 5
The square root of 5 is 2.23607
→ ./Power2 5
The power of two of 5 is 25
所以你有两个主要编译两个不同应用程序的项目。然后,两个cpp文件可以在项目中的其他.cpp或.h文件中共享相同的标头和其他方法。 我建议你看看cmake教程https://cmake.org/cmake-tutorial/ 可能有其他方法有相似但不相同的结果,但我不知道。希望其他用户将为此主题做出贡献!
答案 5 :(得分:1)
实际上,我发现Dev-C ++支持处理不属于任何项目的多个主文件,因此我可以创建一个运行尽可能多的文件。
感谢所有合作伙伴:) 为所有人带来好运。
另外,对于Linux / win,我发现Code :: Blocks可以做到这一点。感谢。
答案 6 :(得分:0)
我猜你的一个IDE会自动创建一个main
函数的文件。检查周围是否已经创建了一个。
答案 7 :(得分:0)
您不能拥有main的多个定义。 “主要”功能实质上是定义程序的功能。如果您有多个main副本,您希望执行哪个副本?
您的问题的解决方案是使用库;如果你想重用功能,那么你应该创建一个库,它与程序基本相同,只是它有功能和数据(如程序),它没有一个叫做“main”的特殊功能,因此没有“入口点”,执行应该在操作系统双击或以其他方式加载时开始。库有两种变体:共享/动态和静态。任何人都应该这样做。您创建的每个程序都有自己的主要功能,但您可以在不同的程序中重复使用您的库。
现在关于创建图书馆的实际要素......请参阅我的C++ Library Project Template。
答案 8 :(得分:0)
正如其他人所说,你的项目可能只有一个主要功能。
为什么要尝试多个主要功能?是因为您将多个小示例程序放入一个项目中,并且每个项目都有一个主要的?如果是这种情况,您可能需要为每个示例创建一个单独的项目,以便IDE不会要求编译器将来自多个示例的源代码编译/链接到一个程序中。您的IDE也可能支持像目标这样的概念,它允许您在一个项目中保留多个相关程序的代码,而不是选择实际构建的程序(目标)。然后,IDE将仅编译/链接该目标中的文件。
答案 9 :(得分:0)
尝试使用静态关键字,例如:
file1.cpp:
#ifdef RUN_FILE1
#define STATIC static
#else
#define STATIC
#endif
int STATIC main(int argc, char **argv(){}
file2.cpp:
#ifdef RUN_FILE2
#define STATIC static
#else
#define STATIC
#endif
int STATIC main(int argc, char **argv(){}
用于汇编添加/DRUN_FILE2
或/DRUN_FILE1
。
只是一个想法。
答案 10 :(得分:0)
如果您正在使用MS链接器,请使用/ FORCE:MULTIPLE链接器选项。遇到的第一个主要符号将获胜。不确定其他连接器的选项是什么。
答案 11 :(得分:0)
我认为QtCreator是一个很棒的IDE。
对于学习和测试,能够拥有多个是很好的 主电源易于使用,但如前所述,您只能有一个主电源 因为这就是在QTcreator / .pro qmake文件中定义项目的方式。
您可以在pro或make / CMAKE文件中创建多个目标。
但是对于测试,我在项目的.pro文件中做了这个。
MAIN = simpletree_test.c
SOURCES += \
$$MAIN \
simpletree.c \
graph_tree.c \
redblacktreenode.c \
redblacktree.c \
redblack.c \
pointers.c
HEADERS += \
simpletree.h \
graph_tree.h \
redblacktreenode.h \
redblacktree.h \
redblack.h \
pointer_manipulator.h
message("The project contains the following files:")
message($$SOURCES)
所以我只是在专业文件中交换名为MAIN的变量中的主文件名。 在SOURCES变量中使用它。
正如您所看到的,我测试了几种树的实现。 现在正在测试树的简单变体,在测试特定节点的新实现之前,在平衡树上测试它们。
然而,该方法并不完美,因为您不能为函数等命名。 过了一段时间,我很难为find_node()或traverse_tree()
提出新名称答案 12 :(得分:0)
在QtCreator中,您可以右键单击文件并选择“编译”选项,该选项仅编译所选文件和所需的依赖项。因此,如果您编译一个这样的主文件,并且该文件不包含任何其他主文件,那么这应该可行。
答案 13 :(得分:0)
我能找到的最佳解决方案是Eclipse creating projects every time to run a single file?,除了为每个程序创建一个新项目之外,还有其他选择。
答案 14 :(得分:0)
NOT:我在这里解释了 cpp 但如果你想为 c 语言做只需要改变编译器 g++ 到 gcc。
这是一个老问题,但我想我理解你提出的问题。
是的,正如您所说,在一个项目中,我们需要使用多个文件,例如main.cpp、test1.cpp 等,但是,我们应该在项目中只有一个“main()”函数。
但是,当你想对任何 cpp 文件进行独立测试时,编译器会提示“这个文件中我宝贵的 main() 或 _start() 函数在哪里?”,终端输出喜欢:
/usr/bin/ld: /usr/lib/gcc/x86_64-linux-gnu/9/../../../x86_64-linux-gnu/Scrt1.o: in function `_start':
(.text+0x24): undefined reference to `main'
collect2: error: ld returned 1 exit status
解决方案是使用#ifdef / #endif机制。如下图:
示例项目结构:
main.cpp 函数:
#include <iostream>
int main(int argc, char *argv[])
{
std::cout << "MAIN" << std::endl;
return 0;
}
我们的测试脚本,cpp代码(vector_test.cpp):
#include <iostream>
using namespace std;
int vmain()
{
std::cout << "vmain -> ifdef" << std::endl;
return 0;
}
#ifdef TESTING
int main(int argc, char *argv[])
{
vmain();
return 0;
}
#endif
因此,当您运行项目时,永远不会出现任何编译时错误,因为您使用 #ifdef 在其他脚本中隐藏了其他主要函数。
当您需要测试任何脚本时,只需在编译时添加如下参数即可:
$ g++ -DTESTING vector_test.cpp
$ ./a.out
输出为:
<块引用>vmain -> ifdef
如您所见,这种方法类似于著名的python
def main():
#do somethings
if __name__ == "__main__":
main()
方法。