Код
// a.h
typedef struct A {int f; } AA;
extern AA a;
//b.cpp
#include "a.h" // тут будет включен полный текст файла а.h, в результате компилятор узнает, что есть тип АА и есть переменная а этого типа
// если бы мы не писали "extern AA a" в a.h, то это объявление пришлось бы писать везде, где нужна переменная "а".
// Если она нужна всего в одном файле, то стоит ее там и определить, причем как "static AA a;" static означает, что переменная локальная для файла
void f() { a.f = 2; }
// c.cpp
#include "a.h" // компилятор работает с каждым файлом отдельно. Тут он уже забыл про АА и а, надо включить снова
AA a; // выше мы только объявили "а". Где-то должно быть и определение, иначе будет ошибка линковки. Определение может быть в любом файле проекта
// но только в одном - если мы в a.h уберем extern, то объявление окажется в двух файлах (b.cpp и c.cpp), в результате будет ошибка линковки
void g() { a.f += 1; }
А вообще наройте книжку по Си и почитайте, это ж основы. Сложно учить язык методом проб и ошибок