Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
Скачиваний:
119
Добавлен:
13.03.2016
Размер:
470.02 Кб
Скачать

2.3.3. Директива #include включения файлов

Директива #includeпозволяет включать в исходную программу любые текстовые файлы. Формы директивы:

#include <СпецификацияФайла>

#include "СпецификацияФайла"

#include ИмяМакро

Первая форма директивы предполагает, что подключается заголовочный файл с расширением .h (т. е файл шаблонов стандартных функций); он будет отыскиваться в стандартных директориях (текущей или указанных в Main Menu/Options/Directories/Include Files).

Вторая форма указывает, что поиск файла осуществляется по маршруту, заданному в " "; если файл там не найден, то просматриваются стандартные директории.

Третья форма предполагает, что существует макроопределение, заменяющее Имя_Макрона спецификацию файла в угловых скобках или двойных кавычках.

2.3.4. Директивы условной компиляции

Они позволяют производить выборочную компиляцию программы. Самый простой вид такой директивы:

#if ЛогическоеВыражение

TRUE-секция

#else

FALSE-секция

#endif

Пример: В зависимости от того, определен ли макрос NAME, регулируется значение макроса BUF.

#ifdef NAME

#define BUF 135

#else

#define BUF 80

#endif

2.415. Многофайловые си-программы

2.4.1. Структура программы на Си. Область действия переменных

Программа на Си состоит из одного или нескольких файлов (текстовых). Исходные текстовые файлы программы содержат описания функций, одна из которых обязательно main, прототипы (шаблоны) функций, директивы препроцессора и описания глобальных переменных, констант, типов (т. е. описания глобальных имен, отличных от функций).

Локальное имя- описанное внутри функции; может использоваться только в этой функции.Глобальное имя- описанное вне функций; доступно в части программы от точки описания до конца файла.

Существует термин область действия имени. Это часть программы, в которой понятие, обозначенное этим именем, доступно. Таким образом, область действия локального имени - блок функции, в которой оно объявлено; глобального - от места объявления до конца файла.

Если требуется воспользоваться глобальным именем вне области его действия (в области от начала файла до объявления имени или в другом файле), то нужно повторить объявление имени, предварив его описателем extern. Объявлениеextern не предусматривает распределение памяти; оно лишь делает нужное имя доступным.

Пример.

файл 1

файл 2

float a;

externfloat a;

int i;

f3()

main ()

{a=...;

{int i;extern float b;

}

a=...; b=...;

extern int c;

}

f4()

float f1()

{ a=...

{int i; a=...

}

}

f5()

float b; {a=...;

float f2()

}

{int i;a=...; b=...;

int c;

}

. . .

Глобальная переменная аможет использоваться во всех функциях файла 1, т. к. она описана в самом начале файла 1; она также доступна всем функциям файла 2, потому что объявлениеextern float aстоит в начале файла 2.

Глобальная переменная iфайла 1 недоступна ни одной функции этого файла, так как каждая функция имеет локальную переменнуюi. Описаниеint iприводит к выделению ячейки памяти под переменнуюi каждый раз при входе в блок {...},где стоит это описание; при выходе из блока эта ячейка освобождается. Локальныеiдоступны только в блоке своей функции, а глобальнаяi - во всем файле 1, за исключением этих функций.

Глобальная переменная bфайла 1 может использоваться в функции f2, т. к. объявлена до описания f2. В функциях, описанных выше объявленияb, эта переменная недоступна. Объявление extern float bв блоке функцииmain, позволяет этой функции использоватьb; тем не менее, для f1 переменнаяbостается недоступной.

В файле 2 вместо двух объявлений int cи extern int cможно было бы оставить толькоint c, поместив его на местоextern int c.

Рекомендации.

1. По возможности описания глобальных переменных, в том числе иextern, следует ставить в начало файла.

  1. Не стоит делать глобальными промежуточные переменные (например, iв программе, приведенной ниже), потому что:

  1. это делает подпрограмму менее универсальной, так как приводит к появлению непонятного пользователю "стыка" - промежуточной глобальной переменной;

  2. приводит к неэкономному расходованию памяти, так как глобальные переменные занимают память в течение всего времени работы программы.

Однако допустимо использование глобальных переменных для передачи данных между подпрограммами(если не требуется подстановка параметров). Так, если бы в примере 1 п.2.2.4 требовалось обработать одну матрицу, то можно было бы использовать функции без параметров:

#include <stdio.h>

#include <math.h>

void masout();

void matrin();

void minmatr();

float a[3][5],min[3];

void main()

{matrin(); minmatr(); masout();

}

void minmatr ()

{int i,j;

for (i=0; i<3; i++)

{min[i]=a[i][0];

for (j=1;j<5; j++)

if (a[i][j]<min[i])

min[i]=a[i][j];

}

}

void matrin()

{int i,j;

printf(" Введите матpицу pазмеpом 3*5 \n");

for (i=0;i<3;i++)

for (j=0;j<5;j++)

scanf("%f",*(a+i)+j);

}

void masout()

{int i;

printf(" Миним.элементы стpок матpицы \n");

for (i=0;i<3;i++)

printf("%4.1f ",min[i]); printf("\n");

}

Замечания.

1. Невозможно было бы в приведенном примере использование глобальных матриц, если с помощью одной процедуры надо было обработать несколько матриц. Тогда один формальный параметр надо было бы последовательно заменять на несколько фактических.

2. В объявлении externневозможна инициализация.

  1. Имена функций - это особые глобальные имена. Они видимы из всех файлов одного проекта. Однако шаблон функции действует только в пределе одного файла. Поэтому приходится помещать в каждый файлпрограммы директивыincludeпрепроцессора, подключающие прототипы библиотечных функций, неоюходимых в этом файле.

  2. Компилятор Си по описаниям глобальных переменных не только дает им место в памяти, но и обнуляет их. Локальные переменные при описании не обнуляются; их значения считаются неопределенными (если, конечно, они не заданы инициализацией, вводом или присваиванием).