А что такое
int a в main.h? Ты, наверное, имел в виду
int i?
Да и вообще, пример твой какой-то мутный... И дело не только во внешних переменных.
Ты вызываешь в main.c функцию
void funct()? И откуда же по-твоему компилятор возьмет ее определение? Ведь тело этой функции находится в другой единице трансляции (соответствующей файлу funct.c), и к main.c она не имеет никакого отношения.
А идея с внешними переменными, по сути своей, проста. Если у тебя есть переменная
int x, глобальная для некой единицы трансляции, и ты хочешь сделать эту переменную внешней, то есть видимой (и могущей быть использованной) в других единицах трансляции, то определена она должна быть, разумеется, только один раз, в своей единице трансляции. А во всех других, где данная переменная нужна, объявляем ее как внешнюю, с помощью ключевого слова
extern.
Пример.
main.c
Код: Выделить всё
#include <stdio.h>
int x = 10;
int main() {
if ( /* некоторое условие истинно */ ) {
x = 20;
}
return 0;
}
angle.c
Код: Выделить всё
extern int x;
while ( x > 5 ) {
/* Выполняем некоторое действие */
}
azimuth.c
Код: Выделить всё
extern int x;
void calc() {
if ( x == 3 ) {
/* сделать нечто очень важное */
}
}
Идея, думаю, ясна. Во всех трех единицах трансляции (компилируемых, как ты знаешь, независимо друг от друга) используется одна и та же переменная
int x. Она создается в
main.c один раз, а из других мест, в частности, из
angle.c и
azimuth.c на нее ссылаются как на внешнюю, то есть созданную где-то в другой единице трансляции.
Я не указал, как эти единицы трансляции связываются друг с другом с помощью заголовочных файлов. Здесь это не главное...
Важное замечание: ключевое слово
extern должно быть частью объявления, а не определения. Если ты напишешь в
angle.c так:
extern int x = 45;, то слово
extern будет проигнорированно! Потому что ты создаешь переменную, какой же смысл объявлять ее внешней? Внешняя на то и внешняя, что
создается в другой единице трансляции.