Стивен Прата - Язык программирования C. Лекции и упражнения (6-е изд.) 2015
- Название:Язык программирования C. Лекции и упражнения (6-е изд.) 2015
- Автор:
- Жанр:
- Издательство:Вильямс
- Год:0101
- ISBN:нет данных
- Рейтинг:
- Избранное:Добавить в избранное
-
Отзывы:
-
Ваша оценка:
Стивен Прата - Язык программирования C. Лекции и упражнения (6-е изд.) 2015 краткое содержание
Язык программирования C. Лекции и упражнения (6-е изд.) 2015 - читать онлайн бесплатно полную версию (весь текст целиком)
Интервал:
Закладка:
const char * рс = "Это строковый литерал!";
Оно приводит к тому, что программа сохраняет в памяти содержимое строкового литерала, и этот массив символьных значений является объектом. Каждый символ в массиве также представляет собой объект, т.к. к нему можно обращаться индивидуально. Объявление также создает объект, который имеет идентификатор рс и хранит адрес данной строки. Идентификатор рс — это модифицируемое 1-значение, поскольку его можно переустанавливать для указания на другие строки. Ключевое слово const предотвращает изменение содержимого строки, на которую указывает рс, но не изменение того, на какую строку он указывает. Таким образом, выражение *рс, обозначающее объект данных с символом 'Э', является 1-значением, но не модифицируемым 1-значением. Аналогично, сам строковый литерал, указывая на объект, который содержит символьную строку, представляет собой 1-значение, не допускающее модификации.
Объект можно описать в терминах его продолжительности храпения, которая указывает, насколько долго он остается в памяти. Идентификатор, применяемый для доступа к этому объекту, может быть описан посредством его области видимости и связывания, которые вместе указывают, в какой части программы этот идентификатор разрешено использовать. Разные классы хранения предлагают различные сочетания области видимости, связывания и продолжительности хранения. Допускается существование идентификаторов, совместно используемых в нескольких файлах исходного кода, идентификаторов, которые могут применяться в любых функциях внутри одного файла, идентификаторов, используемых только внутри отдельной функции, и даже идентификаторов, применяемых лишь в каком-то разделе функции. Одни объекты могут существовать на протяжении времени жизни целой программы, а другие — только во время выполнения функции, которая их содержит. В параллельном программировании можно иметь объекты, которые существуют в течение выполнения отдельного потока. Можно также хранить данные в памяти, которая явно выделяется и освобождается посредством вызовов функций. Давайте посмотрим, что означают термины область видимости, связывание и продолжительность хранения. После этого приступим к изучению конкретных классов хранения.
Область видимости
Область видимости описывает участок или участки программы, где можно обращаться к идентификатору. Переменная в С имеет одну из следующих областей видимости: в пределах блока, в пределах функции, в пределах прототипа функции и в пределах файла. В рассмотренных до сих пор примерах программ для переменных использовалась в основном область видимости на уровне блока. Как вы помните, блок — это часть кода, содержащаяся между открывающей фигурной скобкой и соответствующей ей закрывающей скобкой. Например, блоком является все тело функции. Любой составной оператор внутри функции также считается блоком. Переменная, определенная в блоке, имеет область видимости в пределах блока, и она видна от места, где она определена, до конца блока, содержащего определение. Кроме того, формальные параметры функции, хотя они появляются до открывающей фигурной скобки функции, имеют область видимости в пределах блока и принадлежат блоку, содержащему тело функции. Таким образом, все локальные переменные, которые применялись до сих пор, включая формальные параметры функций, располагали областью видимости в пределах блока. Следовательно, переменные cleo и patrick в приведенном ниже
482 глава 12
коде имеют область видимости в пределах блока, простирающегося до закрывающей фигурной скобки:
double blocky(double cleo)
{
double patrick = 0.0; return patrick;
}
Переменные, объявленные во внутреннем блоке, получают область видимости, ограниченную только этим блоком:
double blocky(double cleo)
{
double patrick = 0.0; int i;
for (i = 0; i < 10; i++)
{
double q = cleo * i; // начало области видимости для q patrick *= q;
} // конец области видимости для q
return patrick;
}
В этом примере область видимости q ограничена внутренним блоком, и доступ к q может иметь только код вггутри этого блока.
По традиции переменные с областью видимости в пределах блока должны объявляться в начале блока. В стандарте С99 это требование было ослаблено, и переменные разрешено объявлять в любом месте блока. Одна из новых возможностей связана с объявлением внутри управляющего раздела цикла for. То есть теперь можно поступать так:
for (int i = 0; i < 10; i++)
printf("Возможность C99: i = %d", i);
Как часть этой новой возможности, стандарт С99 расширил концепцию блока путем включения в нее кода, управляющего циклами for, while, do while или оператором if, даже если фигурные скобки при этом не используются. Таким образом, в предыдущем цикле for переменная i считается частью блока цикла for. Следовательно, ее область видимости ограничена циклом for. После того, как выполнения покинет цикл for, эта переменная i больше не видна программе.
Область видимости в пределах функции применяется только к меткам, применяемым с операторами goto. Это означает, что если метка впервые появляется во внутреннем блоке функции, ее область видимости простирается на всю функцию. Если бы можно было использовать одну и ту же метку внутри двух отдельных блоков, возникла бы путаница, поэтому область видимости в пределах функции для меток предотвращает такую ситуацию.
Область видимости в пределах прототипа функции применяется к именам переменных, используемым в прототипах функций, как в следующем случае:
int mighty (int mouse, double large);
Область видимости в пределах прототипа функции распространяется от места определения переменной до конца объявления прототипа. Это значит, что при обработ-
Классы хранения, связывание и управление памятью 483
ке аргумента прототипа функции компилятор интересует только тип аргумента. Если указаны имена, то обычно они не играют никакой роли и не обязательно должны совпадать с именами, которые применяются в определении функции. Имена играют небольшую роль в случае параметров, имеющих типы массивов переменной длины:
void use_a_VLA(int n, int m, ar[n] [m] );
При использовании имен в скобках это должны быть имена, объявленные ранее в прототипе.
Переменная, определение которой находится за рамками любой функции, имеет область видимости в пределах файла. Переменная, располагающая областью видимости в пределах файла, видна от места ее определения и до конца файла, который содержит ее определение. Взгляните на показанный ниже пример:
Читать дальшеИнтервал:
Закладка: