sem09 - препроцессор_ gcc (1114923), страница 4
Текст из файла (страница 4)
Предположим,что в трёх файлах определена переменная var следующим образом:int var = 1;int add1(void){return var++;}int var;int add2(void){return var += 2;}int var;int add3(void){return var += 3;}Если все три единицы компиляции объединяются в одну программу, то переменная varкаждого из трёх файлов будет располагаться по одному и тому же адресу, и каждая их трёхфункций будет работать, по сути, с общей переменной. Чтобы предотвратить такое слияниепеременных можно использовать явную инициализацию переменной var нулём, тогда компоновщик выдаст сообщение об ошибке.1.6 Программы из нескольких единиц трансляцииТолько самые простые программы размещаются полностью в одном исходном файле. Более сложные программы состоят из нескольких исходных файлов, которые объединяютсякомпоновщиком. При написании таких программ полезно следовать следующим рекомендациям.• При группировке функций и переменных по исходным файлам логически сильно связанные функции объединяются в один исходный файл.
Например, функции работы сфайлом таблицы могут быть помещены в один исходный файл, функции, которые выводят на экран содержимое таблицы, — в другой файл, в функции, которые анализируютввод пользователя, — в третий файл.• Чем больше переменных объявлено в единице компиляции с классом памяти staticвместо класса памяти по умолчанию common, тем лучше.
Лучше всего, если доступ кданным всегда происходит с помощью вызовов функций. Чем меньше «чужих» переменных использует некоторая единица компиляции, тем она проще для понимания.• Для каждого .c файла должен существовать интерфейсный файл с тем же именем,но суффиксом .h, в котором определяются переменные, функции, типы данных и пр.,которые могут использоваться извне данной единице компиляции.• Исходный .c файл должен обязательно подключать свой собственный .h-файл.В этом случае транслятор обнаружит рассогласования между объявлениями в.h-файлах и определениями в .c-файле.12• Интерфейсный .h файл должен быть обязательно защищён от повторного включенияследующей конструкцией:#ifndef __NAME_H__#define __NAME_H__<здесь находится текст файла>#endifЗдесь NAME — это имя файла (без суффикса). Поскольку некоторые .h-файлы могутвключать другие .h-файлы, когда программа становится большой, человек уже не может отследить, какие файлы уже включались, а какие — ещё нет.
Поэтому в .c файлевключаются все заголовочные файлы, необходимые данной единице компиляции. Защита от повторного включения предотвращает появление ошибок о переопределённыхтипах, переменных и функциях.• В заголовочном файле помещаются макроопределения и типы данных, являющиесяинтерфейсом данной единицы компиляции, то есть необходимые для использованияфункций и переменных этой единицы компиляции. С классом памяти extern помещаются необходимые переменные и прототипы функций, объявленные в соответствующей единице компиляции.• В заголовочный файл никогда не помещаются тела функций и определения переменных с классом памяти, отличным от класса extern.
В заголовочный файл никогда непомещаются прототипы функций с классом памяти static. Если некоторый тип иликонстанта используются только в теле какой-либо функций и не нужен для правильной работы с функциями и переменными данной единицы компиляции, этот тип иликонстанта также не помещаются в заголовочный файл.13.