|
Программирование >> Аргументация конструирования
эта переменная доступна для всех функций и существует на протяжении всего времени работы программы (глобальная область видимости) int intGlobal, переменная intChild доступна только в функции child I и существует во время выполнения функции child О или вызываемой ею (область видимости функции) void Chi Id(void) int intChild; переменная arent имеет область видимости функции void pareint (void) int intParent = 0; childo ; int intLater = 0; intEarent = intLater; in (int nArgs, char* pArgs [ ] ) parent(); Программа начинает выполнять функцию main (). В первой же строке main () вызывает функцию parent (). В этой функции выполняется объявление переменной intParent, которая имеет область видимости, ограниченную функцией. Такая переменная называется локальной и доступна только в этой функции. Во второй строке parent О вызывается функция child(). Эта функция также объявляет локальную цеременную - intChild, областью видимости которой являются функция childO, При этом intParent функции child() недостунна (и область видимости intParent не распространяется на функцию child О), но сама переменная продолжает существовать. После окончания работы функции child() неременная intChild выходит из области видимости и уничтожается, т.е. она не только недоступна, но и не существует (память, которую занимала эта переменная, возвращена в пул свободной памяти для дальнейшего использования). После возврата из функции () продолжается выполнение подпрограммы parent (), и в следующей строке объявляется переменная intLater, которая имеет область видимости, ограниченную функцией (). В момент возврата в функ- цию main О неременные intLater и intParent выходят из области видимости и уничтожаются. Кроме локальных переменных, программист может объявлять переменные вне всех функций. Такие переменные называются глобальными и доступны из любого места программы (их область видимости - вся программа). Поскольку intGlobal в приведенном коде объявлена глобально, она доступна на протяжении работы всей программы и внутри любой из трех функций. Проблемы области видимости Приведенный ниже фрагмент программы будет скомпилирован, но не будет корректно работать. double child(void) double dLocalVariable; return fidLocalVariable; void parent(void) double* pdLocal; pdLocal = child () ; *pdLocal = 1.0; Проблема в том, что переменная dLocalVanable объявлена внутри функции child(). Следовательно, в момент возврата адреса dLocalVariable из child() самой переменной уже не существует и адрес ссылается на память, которая вполне мо-жст быть занята для каких-то других целей. Ошибки такого типа встречаются довольно часто, а способы их появления весьма разнообразны. К сожалению, такой тип ошибки пропускается компилятором и зачастую не вызывает аварийной остановки программы. Программа может отлично работать большую часть времени, пока память, которая в прошлом выделялась под dLocalVariable, не будет выделена другой переменной. Труднее всего найти ошибки, проявляющиеся спонтанно. Использование блока памяти Ошибки области видимости возникают потому, что C + + освобождает выделенную для локальных переменных память автоматически. Для решения этой проблемы необходим блок памяти, контролируемый непосредственно программистом. В этом блоке можно выделять память под переменные и удалять их независимо от того, что по этому поводу думает С + + . Такой блок памяти называется кучей (heap). Память в куче можно выделить, используя оператор new; он пишется вместе с типом объекта, под который нужно выделить память. Приведенный ниже пример выделяет из кучи память для переменной типа double. double* child(void) double* pdLocalVariable = new double; return pdLocalVariable; Теперь, несмотря на то что переменная pdLocalVariable имеет область видимости в пределах функции child(), память, на которую указывает эта переменная, не будет освобождена после выполнения функции. Выделение и освобождение памяти в куче осуществляется только явно. Освобождение памяти в куче выполняется с помощью команды delete. void parent(void) { функция child о возвращает адрес переменной в куче double* pdMyDouble = child(); сохранение значения в созданной переменной *pdMyDouble = 1.1; . . . памяти куче delete pdMyDouble; = 0; . . . В этой программе указатель, возвращенный функцией используется для записи значения типа double в память, выделенную в куче. После того как функция выполнила все необходимые действия с этой памятью, она освобождается, а указатель pdMyDouble устанавливается равным нулю. Обнуление указателя не обязательно, но крайне желательно. В этом случае, если программист ошибется и попытается опять записать что-либо по адресу, на который указывает pdMyDouble, произойдет аварийный останов программы. Ошибку, в результате которой происходит аварийный останов программы, найти гораздо проще, чем проявляющуюся спонтанно.
|
© 2006 - 2025 pmbk.ru. Генерация страницы: 0
При копировании материалов приветствуются ссылки. |