как я могу избежать этой ошибки связывания?

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

headers.h:

#ifndef __HEADERS #define __HEADERS int x = 10; #endif 

1.c:

 #include "headers.h" main () { } 

2.c:

 #include "headers.h" fun () {} 

Компилятор жалуется, потому что будет множество определений x только он объединяет все объектные файлы для создания исполняемого файла. У вас есть два разных исходных файла, включая один и тот же заголовочный файл, и этот заголовочный файл определяет переменную x имеющую значение 10, поэтому вы получаете два определения x (один в 1.c и другой в 2.c).

Чтобы избежать множественных ошибок компоновщика определений, поместите это в файл заголовка (например, globals.h ):

 #ifndef GLOBALS_H #define GLOBALS_H /* * The "extern" keyword means that this variable is accessible everywhere * as long as this declaration is present before it is used. It also means * that the variable x may be defined in another translation unit. */ extern int x; #endif 

Затем поместите это в один исходный файл:

 #include "globals.h" int x = 10; 

Это classический случай, когда вы хотите, чтобы переменная объявлена ​​или объявлена ​​и определена.

Если вы определяете его в обоих исходных файлах, вы получите ошибку компоновщика с двойным определением. Один из способов справиться с этим – установить только __HEADERS для одного из исходных файлов, чтобы он был тем, где определена переменная.

Все остальные исходные файлы получают только декларацию.

 >>headers.h #ifndef __HEADERS int x = 10; #else extern int x; #endif >>1.c #define __HEADERS #include "headers.h" int main (void) { return 0; } >>2.c #include "headers" void fun (void) { } 

Конечно, лучше всего оставить __HEADERS из файлов заголовков вообще, если вы случайно определите __HEADERS в двух исходных файлах. Пытаться:

 >>headers.h extern int x; >>1.c #include "headers.h" int x = 10; int main (void) { return 0; } >>2.c #include "headers" void fun (void) { } 

#include работает точно так же, как если бы вы скопировали и вставляли текст из файла заголовка.

Подумайте об этом таким образом, и вы увидите, что вы поэтому положили строку int x=10 в оба исходных файла.

Фиксированная версия приведена ниже:

 >>headers.h #ifndef __HEADERS #define__HEADERS extern int x; // extern tells the compiler it will be linked from another file #endif ----------------- >>1.c #include "headers.h" int x = 10; // must have it in ONE file for linking purposes main () { } --------------------- >>2.c #include "headers" fun () {} 
  1. Определите __HEADERS в ifndef.
  2. Поместите в заголовки объявления, а не определения:
 // header extern int x; // implementation int x = 10; 

3. 2.c имеет неправильное включение.

Так:

 // headers.h #ifndef __HEADERS #define __HEADERS extern int x; #endif 

// 1.c

 #include "headers.h" int x = 10; main () { } 

// 2.c

 #include "headers.h" fun () {} 

Вы можете определить x в любом месте. Просто сделайте это на одном месте.