Как скомпилировать проект C с более чем одной функцией?

Я новичок в C, и теперь прочитал некоторый учебник и собираюсь применить его примеры.

проблема в том, что всякий раз, когда я создаю новый проект и пытаюсь поместить более одного файла, содержащего основную функцию, компоновщик (как я thougt0 объясняет, говоря:

/home/mohammed/tmp/abcd/main.c:4: multiple definition of `main'

(кстати, я использовал много IDEs, MonoDevelop, Qt creator, VS2010, Codebloks,...) В настоящее время я использую Qt Creator, это кажется очень хорошей IDE.

таким образом, нет обходного пути для решения таких проблема??

EDIT:

Я спрашиваю, потому что я нахожусь в стадии обучения, и не делаю реального программирования прямо сейчас. Мне просто нужен простой способ создания программ на C без необходимости создавать отдельный проект на примере книги. В то же время я не хочу использовать командную строку Gedit/VI+.

итак, нет ли такого способа, как очистка проекта, а затем скомпилировать - только-один файл, который мне нужно запустить ??? Кстати, в JAVA мы можем запустить программа, которая объединяет более одного основного (IDE дает мне выбор среди них)

14 ответов


что вы пытаетесь сделать с несколькими main функции?

если вы пытаетесь скомпилировать несколько разных программ одновременно, вам нужно скомпилировать каждую отдельно (т. е. только одну main в программе).

если вы пытаетесь скомпилировать одну программу и хотите, чтобы несколько main функции все бежать, вы не можете. Вам нужно указать только один main и переименуйте других в что-то другое (и вызовите их из одного main в том порядке, в котором вы хотите их запустить).

если вы пытаетесь использовать только один из main функции в качестве одной точки входа в вашу программу и игнорировать другие, то вы не должны включать файлы с другими mains, Когда вы связываете. Я предлагаю разместить каждый main в отдельном файле, если вы хотите сохранить их и включить только один из этих основных файлов при связывании/компиляции.

если вы получаете эту ошибку по ошибке, то вы, вероятно, делаете что-то неправильно с проектом в вашей IDE. Возможно, вы случайно пытаетесь скомпилировать несколько разных программ в одну? Возможно, Вам потребуется указать каждый файл, содержащий main как отдельный продукт сборки. C не похож на Java, где вы можете поместить main метод внутри каждого класса и указать, какой из них вызывать;main в C-это глобальное имя.


в вашем приложении не может быть более одной точки входа. При запуске окончательного исполняемого файла функция точки входа (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связаны вместе.

Если вы вместо этого хотите, чтобы они были отдельными программами, вам придется связать их отдельно.


каждая программа должна иметь ровно одну основную функцию. Однако main может вызывать любую функцию, которую вы хотите (включая себя, хотя это может быть запутанным). Таким образом, вы должны разбить программу на логические части.


как многие говорили,вы можете иметь только одну основную программу. Вы не хотите идти через хлопот создания нового проекта для каждого примера, как вы идете через книгу. Это понятно, но в основном вам придется это сделать. Я вижу две альтернативы:

  1. новый проект в IDE (как VS2010). Это сделает всю тяжелую работу за вас. Вы всегда можете удалить их позже.
  2. Если вы не хотите держать код вокруг, просто опустошите файл (или даже функция main ()) и повторно использовать его. С примерами книг вы, вероятно, никогда не будете пересматривать код в любом случае, поэтому просто удалите его.

вы можете иметь более одного main в одном проекте, если каждому main будет соответствовать другой исполняемый файл в дереве каталогов сборки.

следующий пример использует CMake, я не знаю, можно ли это сделать с другим программным обеспечением диспетчера сборок.

сохраните следующие два .cpp файлы в папке с именем источник, и назовите их 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. Затем, в той же папке, добавить .txt называется CmakeLists.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
[ 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/ Могут быть другие методы, чтобы иметь похожие, если не те же результаты, но я не знаю никаких. Надеюсь, другой пользователь внесет свой вклад в эту тему!


на самом деле, я нахожу, что Dev-C++ поддерживает работу с несколькими основными файлами, которые не являются частью какого-либо проекта, поэтому я могу создать столько файлов, сколько мне нужно.

спасибо всем, кто корпоратив здесь :) ГУК удача для всех.

кроме того, для Linux / win я нашел код:: блоки делают этот трюк. спасибо.


Я предполагаю, что один из ваших IDEs автоматически создает файл с . Проверьте вокруг, чтобы увидеть, если один уже создан.


вы не можете иметь несколько определений main. "Основная" функция-это то, что, по сути, определяет, что делает ваша программа. Если бы у вас было более одной копии main, какую из них вы ожидали бы выполнить?

решение вашей проблемы заключается в использовании библиотек; если вы хотите повторно использовать функциональность, то вы должны создать библиотеку, которая в основном идентична программе, за исключением того, что, хотя она имеет функции и данные (например, программа), у нее нет специальной функции, называемой "main", и, следовательно, не имеет" точки входа", где выполнение должно начинаться, когда оно будет дважды щелкнуто или иным образом загружено ОС. Библиотеки бывают двух вариантов: общие/динамические и статические. Любой из них подойдет. Каждая создаваемая программа будет иметь свою основную функцию, но вы можете без проблем использовать библиотеку в разных программах.

теперь о практическом элементе создания библиотеки... смотрите мой Шаблон Проекта Библиотеки C++.


Как говорили другие, Ваш проект может иметь только одну основную функцию.

Почему вы пытаетесь иметь более одной основной функции? Это потому, что вы помещаете несколько небольших примеров программ в один проект, и каждый из них имеет основной? Если это так, вам может потребоваться создать отдельный проект для каждого примера, чтобы ваша IDE не просила компилятор компилировать/связать источник из нескольких примеров в одну программу. Ваша IDE также может поддерживать такую концепцию, как target, что позволяет сохранить код для нескольких связанных программ в одном проекте и выбрать, какую программу (цель) фактически построить. Затем IDE будет компилировать / связывать только файлы в этой цели.


попробуйте использовать ключевое слово static, например:

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.

просто идея.


Если вы используете MS linker, используйте параметр / FORCE:MULTIPLE linker. Первый встреченный главный символ победит. Не уверен, что вариант для других компоновщиков.


Ну, я думаю, что 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 в файле pro. используйте его в переменной SOURCES.

Как вы можете видеть, я тестирую несколько реализаций деревьев. Прямо сейчас тестирование простой вариации деревьев, где я тестирую новую реализацию для поиска определенного узла, прежде чем тестировать их на сбалансированном дереве.

метод, однако, не идеален, так как вы не можете иметь одинаковые имена для функций так далее. И через некоторое время мне может быть сложно придумать новые имена для find_node() или traverse_tree()


в QtCreator вы можете щелкнуть правой кнопкой мыши файл и выбрать опцию "компилировать", которая компилирует только выбранный файл и необходимые зависимости. Поэтому, если вы компилируете один из ваших основных файлов, и этот файл не включает в себя какой-либо другой основной файл, это должно работать.


лучшее решение, которое я мог найти, было на Eclipse создает проекты каждый раз для запуска одного файла? Он имеет некоторые альтернативы, чем создание нового проекта для каждой программы.