Error redefinition of int main

VPF:: - Форум программистов Vingrad

Проблема множественного включения заголовочных файлов(headers)

Пример:

Пускай программа состоит из трёх файлов — main.cpp, a.h, b.h.
a.h:

Код

struct point
{
    int x;
    int y;
};

void func_a();

b.h:

Код

#include "a.h"

void func_b(point* pnt);

main.cpp:

Код

#include "a.h"
#include "b.h"

int main()
{
    point* p;
    func_a();
    func_b(p);

    return 0;
}

В заголовочном файле a.h описывается структура point и объявляется функция func_a.
В заголовочном файле b.h включается заголовочный файл a.h и объявляется функция func_b.
В основном файле программы main.cpp подключаются заголовочные файлы a.h и b.h, в функции main() поочерёдно вызываются функции func_a, func_b, затем программа завершается.

Проблема:
Программа не компилируется. Компилятор выдаст ошибку, например так:

Код
a.h:1: error: redefinition of ‘struct point’

Почему так происходит?
Директива компилятора #include говорит компилятору о том, что содержимое указанного файла нужно вставить в данное место.
Описание структуры point, итого, вставится в main.cpp два раза: 1-й раз — явно — при включении файла a.h, второй раз — неявно — при включении файла b.h, так как файл b.h тоже включает в себя содержимое файла a.h.
Код главного модуля сначала преобразуется в такое:

Код

struct point
{
    int x;
    int y;
};

void func_a();

#include "a.h"

void func_b(point* pnt);

int main()
{
    point* p;
    func_a();
    func_b(p);

    return 0;
}

После чего снова обрабатывается #include и получается:

Код

struct point
{
    int x;
    int y;
};

void func_a();

struct point
{
    int x;
    int y;
};

void func_a();

void func_b(point* pnt);

int main()
{
    point* p;
    func_a();
    func_b(p);

    return 0;
}

В этом, итоговом, коде присутствуют два определения struct point. Это и служит причиной выдачи ошибки компилятором.

Решение:
Использовать условные директивы компилятора #ifndef…#define…#endif.
Их также называют «стражами включения».

Код всех заголовочных файлов нужно обрамлять:

Код

#ifndef идентификатор_файла
#define идентификатор_файла

// здесь всё, что было раньше в заголовочном файле

#endif

Идентификатором файла может быть любое правильной имя переменной в С/С++.
Однако, принято давать этим иденфикаторам имена, состоящие из больших букв латинского алфавита и подчёркиваний, логические связанные с именем файла.
К примеру, для файла abcd.h можно взять идентификаторы ABCD_H, FILE_ABCD_H, ABCD_H_INCLUDED
Важно: идентификаторы заголовочных файлов в пределах одной программы(одного проекта) должны быть разными, иначе Вы получите обратный результат(не множественное включения, а отсутствие включения).

Исправленный заголовочный файл a.h:

Код

#ifndef A_H_INCLUDED // если этот файл ещё не включён
#define A_H_INCLUDED // включить этот файл

struct point
{
    int x;
    int y;
};

void func_a();
#endif

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

В этом случае, код модуля с учётом произведённых #include имеет вид:

Код

#ifndef A_H_INCLUDED // идентификатор ещё не определён
#define A_H_INCLUDED // определяем

struct point
{
    int x;
    int y;
};

void func_a();
#endif

#ifndef A_H_INCLUDED // а здесь идентификатор уже определён
#define A_H_INCLUDED // поэтому эта и все остальные строки до #endif удаляются

struct point
{
    int x;
    int y;
};

void func_a();
#endif

void func_b(point* pnt);

int main()
{
    point* p;
    func_a();
    func_b(p);

    return 0;
}

Итого получается следующее:

Код

struct point
{
    int x;
    int y;
};

void func_a();

void func_b(point* pnt);

int main()
{
    point* p;
    func_a();
    func_b(p);

    return 0;
}

Это и есть желаемый нами код.

Данное решение работает на всех известных компиляторах С/С++.

Замечания:
1. В данном примере файл b.h тоже желательно должен быть обрамлён.
2. Не начинайте имя идентификатора с подчёркивания, это крайне не рекомендуется стандартом С++.

Другие решения.
Некоторые компиляторы С/С++ предоставляют ещё одно решение проблемы.
Для этого необходимо включить в начало каждого заголовочного файла директиву

Данная директива имеет тот же эффект, что и вышеприведенное решение, но для её применения потребуется компилятор, поддерживающий это расширение. В число таких компиляторов входят: компилятор из MS Visual Studio (MSVC), компилятор g++ из GCC.

Назад к FAQ

Это сообщение отредактировал(а) bsa — 26.7.2011, 11:02

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

 #include <iostream>

using namespace std;

int findMaxSumArray (int arr[3][3])
{
int sum1, sum2 = 0;
int i, j = 1;
int row = 3;
int col = 3;
for (i = 0; i < row; ++i)
{
sum1 = sum1 + arr[1][i];
}
for (j = 2; j < col; ++j)
{
for (i = 0; i < row; ++i)
{
sum2 = sum2 + arr[j][i];
}
if (sum2 > sum1)
{
sum1 = sum2;
}
}
return sum1;
}

int main ()
{

int arr[3][3] = { {1, 2, 3}, {2, 3, 4}, {5, 6, 7} };

cout << findMaxSumArray(arr);
}

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

Syntax Error(s)
prog.cpp: In function 'int main()':
prog.cpp:46:5: error: redefinition of 'int main()'
int main() {
^
prog.cpp:38:5: note: 'int main()' previously defined here
int main ()
^

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

0

Решение

Это не связано с вашим вопросом, но есть еще одна проблема в вашем коде — вы используете неинициализированную локальную переменную.

Несмотря на то, что это может выглядеть, эта строка кода не инициализируется sum1, он только объявит это:

int sum1, sum2 = 0;

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

int sum1;
int sum2 = 0;

Локальные переменные не получают нулевой инициализированный по умолчанию (как глобальные переменные), это означает, что они будут иметь некоторое значение, но мы не можем предсказать его.

Как вы можете догадаться, используя var1 не даст ожидаемых результатов.

sum1 = sum1 + arr[1][i];  //!!

Вместо этого это вызовет странные ошибки.

1

Другие решения

Других решений пока нет …

Алехандрыч

0 / 0 / 0

Регистрация: 07.11.2016

Сообщений: 4

1

07.11.2016, 22:16. Показов 9535. Ответов 2

Метки c++ (Все метки)


C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
#include <iostream>
#include <locale>
 
using namespace std;
 
int main(int argc, const char * argv[]) {
    setlocale(LC_ALL, "RUSSIAN");
 
    int i;
    char arr[50];
 
    cout << "Напишите пожелание автору. Вам даётся 20 символов" << endl;
        cin >> arr;
        int i = strlen(arr);
 
        if (int (i) < 10) 
            cout << "Мало символов, надо хотя бы 11" << "А у вас " << i << endl;
        
        else if (int (i) > 50)
            cout << "Много симолов нужно меньше 50" << "А у вас " << i << endl;
        else
            cout << "Спасибо =)" << endl;
    
    system("pause");
    return 0;
}

Что тут не так?
Ошибка: ‘int i’: redefinition

__________________
Помощь в написании контрольных, курсовых и дипломных работ, диссертаций здесь



0



Cheshyrsky_Kot

0 / 0 / 1

Регистрация: 28.05.2015

Сообщений: 30

07.11.2016, 23:49

2

Алехандрыч, Ты в начале задал тип данных для «i»

Добавлено через 4 минуты
Вот:

C++ (Qt)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
#include <iostream>
#include <locale>
#include <cstring>
using namespace std;
 
int main(int argc, const char * argv[]) {
setlocale(LC_ALL, "RUSSIAN");
 
int i;
char arr[50];
 
cout << "Напишите пожелание автору. Вам даётся 20 символов" << endl;
cin >> arr;
i = strlen(arr);
 
if (i < 10) 
cout << "Мало символов, надо хотя бы 11" << "А у вас " << i << endl;
 
else if (i > 50)
cout << "Много симолов нужно меньше 50" << "А у вас " << i << endl;
else
cout << "Спасибо =)" << endl;
 
system("pause");
return 0;
}



0



0 / 0 / 0

Регистрация: 07.11.2016

Сообщений: 4

08.11.2016, 15:28

 [ТС]

3

Спасибо большое помог!



0



IT_Exp

Эксперт

87844 / 49110 / 22898

Регистрация: 17.06.2006

Сообщений: 92,604

08.11.2016, 15:28

Помогаю со студенческими работами здесь

Какая из этих функций int Q(int w) int W(int y,int u,int i) сработает быстрее?
Если есть 2 функции(простые или перегруженные) к примеру Q(int w) int W(int y,int u,int i)или int…

ОШИБКА [Error] cannot convert ‘int*’ to ‘float*’ for argument ‘1’ to ‘void Syma(float*,int*,int)
Какая то проблема с указателями,незнаю,не хочет щитать суму парних чисел в второй…

Ошибка: error: invalid types ‘int[int]’ for array subscript
Выпрыгивает ошибка:
&quot;main.cpp: In function ‘int main()’:
main.cpp:33:12: error: invalid types…

Ошибка — перегруженность pow(int,int) неосуществима. Как исправить?
#include &lt;iostream&gt;
#include &lt;cmath&gt;
using namespace std;
struct point
{
int x,y,z;
};…

Искать еще темы с ответами

Или воспользуйтесь поиском по форуму:

3

Понравилась статья? Поделить с друзьями:
  • Error remote desktop connection broker is not ready for rpc communication
  • Error redeclaration of
  • Error remote connect что это
  • Error remote connect сбербанк
  • Error remote connect при оплате картой