Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
тех прог.doc
Скачиваний:
37
Добавлен:
14.11.2019
Размер:
3.59 Mб
Скачать

16.2.Область действия имен

Имена имеют переменные, функции, структуры, перечисления, классы, элементы классов и структур. Когда программы становятся большими, возрастает вероятность конфликта между именами.

Зоной видимости глобальной переменной является файл. К такой переменной можно обратиться в любом месте программы от точки объявления до конца файла.

Зоной видимости локальной переменной является часть блока, в котором она определена от точки объявления до конца блока.

Локальная переменная может перекрывать глобальную переменной с тем же именем. Пример такого перекрытия демонстрируется в приводимой ниже программе.

Программа 50. Глобальные и локальные имена

В программе использовано одно и то же имя i для двух переменных: глобальной и локальной.

// Файл Glob_Loc.cpp

#include <iostream.h>

int i = 5; // Глобальная переменная

int main()

{

cout << "i = " << i << endl; // Печать глобальной переменной

int i = 1; // Локальная переменная закрывает глобальную

cout << "i = " << i << endl; // Печать локальной переменной

cout << "::i = " << ::i << endl; // Печать глобальной переменной

cin.get();

return 0;

}

Программа выводит:

i = 5

i = 1

::i = 5

Для доступа к глобальной переменной, которая не видима из-за того, что перекрыта локальной переменной с таким же именем, можно использовать оператор разрешения зоны видимости (::). Таким образом, ::i – это имя переменной из внешнего блока.

В одной зоне видимости нельзя объявлять переменные с одинаковыми именами.

Единицей компиляции в языке C++ является файл. Файл может содержать различные объявления и определения, в том числе объявления и определения переменных и функций. В одном файле можно поместить определения нескольких функций. Запрещено помещать части одной функции в различных файлах.

В C++ запрещено определять функции внутри других функций, поэтому имя функции всегда глобально и может быть доступно в любой другой функции при соответствующем объявлении.

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

Статические имена

Рассмотрим схематический пример программы из двух файлов.

// Файл File_1.cpp

int N; // Определение внешней переменной

void f1() // Определение функции f1

{

N = 1; // Использование внешней переменной

}

// Файл File_2.cpp

void f1() ; // Объявление (прототип) функции f1

extern int N; // Объявление внешней переменной

int f2() // Определение функции f2

{

f1(); // Обращение к функции f1

int k = N; // Использование внешней переменной, k = 1

return k;

}

Объявление функции f1 в файле File_2.cpp делает ее известной компилятору, который может сгенерировать ее правильный вызов. Объявление внешней переменной N позволяет использовать ее в любом месте файла File_2.cpp после точки объявления. Если в проект включены оба файла, редактор связей найдет код f1, включит его в рабочую программу и сделает ссылку на него из f2. Аналогично, редактору связей будет известен адрес N, по которому к ней можно обращаться. Недостаток данной программы состоит в том, что не так-то просто понять, почему значением k будет 1. При попытке определить еще одну внешнюю переменную с именем N в файле File_2.cpp возникает ошибка на этапе редактирования связей.

Можно ограничить зону действия имен, сделав их статическими, для чего объявления нужно начинать словом static. Проиллюстрируем это примером.

// Файл File_1.cpp

static int N; // Определение внешней переменной

static void f1() // Определение функции f1

{

N = 1; // Использование внешней переменной

}

// Файл File_2.cpp

void f1() ; // Объявление (прототип) функции f1

extern int N; // Объявление внешней переменной

int f2() // Определение функции f2

{

f1(); // Обращение к функции f1

int k = N; // Использование внешней переменной, k = 1

return k;

}

При компиляции файла File_2.cpp ошибок не будет, так как есть все необходимые объявления, но на этапе компоновки возникнут ошибки, так как компоновщик не найдет f1 и N, из-за ограниченности их зоны действия файлом File_1.cpp. Компоновщик выдаст сообщение об ошибке вида: Linker error…