►Использование кучи...113
Куча ( heap ) — это блок памяти изменяемого размера, который при необходимости может использоваться программой. Далее в этом разделе поясняется, зачем нужна куча и как ею пользоваться.
«Visual С++ .NET позволяет программисту писать код, который работает в т.н. управляемом режиме ( managed mode ), когда выделение и освобождение памяти обрабатывает компилятор. Поскольку таким режимом отличается только Visual С++ .NET, в данной книге он не рассматривается.»
[Атас!]
Очевидно, что если можно передать функции указатель, то можно и вернуть его как результат работы функции. Функция, которая должна вернуть некоторый адрес, объявляется следующим образом:
double* fn( void ) ;
При работе с возвращаемыми указателями следует быть очень осторожным. Чтобы понимать, чем чревато неаккуратное использование указателей, следует познакомиться с концепцией области видимости переменных ( т.е. с тем, где именно от переменных остаётся только видимость... ).
Область видимости...113
Кроме значения и типа, переменные в С++ имеют ещё одно свойство — область видимости, т.е. часть программы, в которой эта переменная определена. Рассмотрим следующий фрагмент кода:
/* Эта переменная доступна для всех функций и существует на протяжении всего времени работы программы ( глобальная область видимости ) */
int intGlobal ;
/* Переменная intChild доступна только в функции child( ) и существует только во время выполнения функции child( ) или вызываемой ею ( область видимости функции ) */
_________________
113 стр. Глава 8. Первое знакомство с указателями в С++
void child( void )
{
int intChild ;
}
/* Переменная intParent имеет область видимости функции */
void parent( void )
{
int intParent = 0 ;
child( ) ;
int intLater = 0 ;
intParent = intLater ;
}
int main( int nArgs , char* pArgs[ ] )
{
parent( ) ;
}
Программа начинает выполнять функцию main( ). В первой же строке main( ) вызывает функцию parent( ). В этой функции объявляется переменная intParent, которая имеет область видимости, ограниченную функцией. Такая переменная называется локальной и доступна только в этой функции.
Во второй строке parent( ) вызывается функция child( ). Эта функция также объявляет локальную переменную — intChild, областью видимости которой является функция child( ). При этом intParent функции child( ) недоступна ( и область видимости intParent не распространяется на функцию child( ) ), но сама переменная продолжает существовать.
После окончания работы функции child( ) переменная intChild выходит из области видимости и уничтожается, т.е. она не только недоступна, но и не существует ( память, которую занимала эта переменная, возвращена в пул свободной памяти для дальнейшего использования ).
После возврата из функции child( ) продолжается выполнение подпрограммы parent( ), и в следующей строке объявляется переменная intLater, которая имеет область видимости, ограниченную функцией parent( ). В момент возврата в функцию main( ) переменные intLater и intParent выходят из области видимости и уничтожаются.
Кроме локальных переменных, программист может объявлять переменные вне всех функций. Такие переменные называются глобальными, они доступны из любого места программы ( их область видимости — вся программа ).
Поскольку intGlobal в приведённом коде объявлена глобально, она доступна на протяжении работы всей программы и внутри любой из трёх функций.
Проблемы области видимости...114
Приведённый ниже фрагмент программы будет скомпилирован, но не будет корректно работать.
double* child( void )
{
double dLocalVariable ;
return&dLocalVariable ;
}
void parent( void )
{
double* pdLocal ;
pdLocal = child( ) ;
*pdLocal = 1.0 ;
}
_________________
114 стр. Часть 2. Становимся функциональными программистами