aho.h

// ↓最初インクルードするときはAは定義されてないから真にならない
//  #endifまでインクルードしたコードの一部になる(#includeの部分がインクルードしたファイルの内容に置き換わると考えれば分かりやすい)
//  再度インクルードすると、すでにAは定義されてるから@は偽になる(こっから#endifまでないことにされる)
#ifndef __AHO_H__ @  
#define __AHO_H__ A

#define AHO_R 004
#define AHO_W 002
#define AHO_X 001
void aho1();
void aho2();

#endif

aho1.c

#include "aho.h"
void aho1() {
  printf("super aho:permission =%u\n", AHO_R | AHO_W | AHO_X);
  printf("komono aho:permission =%u\n", AHO_R);
}

aho2.c

#include "aho.h"
void aho2() {
  printf("komono aho:permission =%u\n", AHO_R);
}

で、aho.hの定義や宣言をaho1.c、aho2.cで使えることがアホでも分かるハズ