Стивен Прата - Язык программирования C. Лекции и упражнения (6-е изд.) 2015
- Название:Язык программирования C. Лекции и упражнения (6-е изд.) 2015
- Автор:
- Жанр:
- Издательство:Вильямс
- Год:0101
- ISBN:нет данных
- Рейтинг:
- Избранное:Добавить в избранное
-
Отзывы:
-
Ваша оценка:
Стивен Прата - Язык программирования C. Лекции и упражнения (6-е изд.) 2015 краткое содержание
Язык программирования C. Лекции и упражнения (6-е изд.) 2015 - читать онлайн бесплатно полную версию (весь текст целиком)
Интервал:
Закладка:
void more(int number)
{
int index;
static int ct = 0;
return 0;
}
Здесь переменная ct хранится в статической памяти; она существует с момента загрузки программы в память и вплоть до завершения выполнения программы. Но область видимости ct ограничена блоком функции more(). Только во время выполнения этой функции программа может использовать переменную ct для доступа к объекту, который она обозначает. (Тем не менее, можно разрешить непрямой доступ, позволив функции предоставить адрес хранилища другим функциям, например, с помощью параметра типа указателя или возвращаемого значения.)
Область видимости, связывание и продолжительность хранения используются в С в целях определения нескольких схем хранения для переменных. В этой книге не рассматривается параллельное программирование, поэтому мы не будем касаться данного аспекта. Выделенная продолжительность хранения будет обсуждаться позже в главе. В итоге остаются пять классов хранения: автоматический, регистровый, статический с областью видимости в пределах блока, статический с внешним связыванием и статический с внутренним связыванием. Комбинации представлены в табл. 12.1.
486 Глава 12
Таблица 12.1. Пять классов хранения
Теперь, когда мы раскрыли понятия области хранения, связывания и продолжительности хранения, можно переходить к более детальным исследованиям этих классов хранения.
Автоматические переменные
Переменная, принадлежащая к автоматическому классу хранения, имеет автоматическую продолжительность хранения, область видимости в пределах блока и не имеет связывания. По умолчанию любая переменная, объявленная в блоке или в заголовке функции, относится к автоматическому классу хранения. Однако вы можете совершенно ясно сформулировать свои намерения, явным образом указав ключевое слово auto:
int main(void)
{
auto int plox;
Эго можно делать, скажем, для документирования того факта, что вы намеренно переопределяете внешнюю переменную, или для подчеркивания важности того, что класс хранения переменной не должен изменяться. Ключевое слово auto называется спецификатором класса хранения. В C++ ключевое слово auto предназначено для совер шенно другой цели, поэтому просто не применяйте auto в качестве спецификатора класса хранения, чтобы добиться большей совместимости между С и C++.
Область видимости в пределах блока и отсутствие связывания подразумевает, что доступ к этой переменной по имени может осуществляться только в блоке, где переменная определена. (Конечно, посредством аргументов значение и адрес переменной можно передать в другую функцию, но это будут уже косвенные сведения.) В другой функции может использоваться переменная с тем же самым именем, но это будет независимая переменная, хранящаяся в другой ячейке памяти.
Как вы, возможно, помните, автоматическая продолжительность хранения означает, что переменная начинает свое существование, когда поток управления входит в блок, который содержит объявление этой переменной. После того как поток управления покинет блок, автоматическая переменная исчезнет. Ячейка памяти, которую она занимала, может применяться для чего-то другого, хотя и необязательно.
Классы хранения, связывание и управление памятью 487
Давайте более внимательно посмотрим на вложенные блоки. Переменная известна только в блоке, в котором она объявлена, и в любых блоках, размещенных внутри этого блока:
int loop(int n)
{
int m; // m находится в области видимости
scanf ("%d", &m);
{
int i; // и m, и i находятся в области видимости
for (i = m; i < n; i++)
puts("i is local to a sub-block\n");
}
return m; // m в области видимости, i исчезла
}
В данном коде переменная i является видимой только во внутренних скобках. Если вы попытаетесь воспользоваться этой переменной до или после внутреннего блока, компилятор сообщит об ошибке. Обычно такой прием при проектировании программ не применяется. Тем не менее, временами удобно определять переменную в подблоке, если она не используется в других местах. В этом случае можно документировать назначение переменной близко к месту ее применения.
Кроме того, переменная не будет оставаться неиспользуемой, попусту занимая место, когда она больше не нужна. Так как переменные пит определены в заголовке функции и во внешнем блоке, они находятся в области видимости всей функции и существуют вплоть до ее завершения.
Что, если вы объявите во внутреннем блоке переменную, которая имеет такое же имя, как переменная во внешнем блоке? Тогда имя, определенное внутри блока, соответствует переменной, которая применяется в этом блоке. Мы говорим, что имя скрывает внешнее определение. Однако когда поток управления покидает внутренний блок, внешняя переменная возвращается в область видимости. Эти и другие аспекты проиллюстрированы в листинге 12.1.
Листинг 12.1. Программа hiding . с
// hiding.с -- переменные в блоках #include int main()
(
int x = 30; // исходная переменная x
printf("x во внешнем блоке: %d по адресу %p\n", x, &x);
{
int x = 77; // новая переменная x, скрывающая первую x
printf("x во внутреннем блоке: %d по адресу %p\n", x, &x);
}
printf("x во внешнем блоке: %d по адресу %p\n", x, &x);
while (x++ < 33) // исходная переменная x
{
int x = 100; // новая переменная x, скрывающая первую x
x++;
printf("x в цикле while: %d по адресу %p\n", x, &x);
}
printf("x во внешнем блоке: %d по адресу %p\n", x, &x);
return 0;
488 глава 12
Вот результаты пробного запуска:
х во внешнем блоке: 30 по адресу 0x7fff5fbff8c8 x во внутреннем блоке: 77 по адресу 0x7fff5fbff8c4 x во внешнем блоке: 30 по адресу 0x7fff5fbff8c8 x в цикле while: 101 по адресу 0x7fff5fbff8c0 x в цикле while: 101 по адресу 0x7fff5fbff8c0 x в цикле while: 101 по адресу 0x7fff5fbff8c0 x во внешнем блоке: 34 по адресу 0x7fff5fbff8c8
Первым делом программа создает переменную х со значением 30, как показывает первый оператор printf(). Затем она определяет новую переменную х со значением 77, о чем сообщает второй оператор printf(). Это новая переменная, скрывающая первую переменную х, значение и адрес которой снова выводятся третьим оператором printf(). Данный оператор находится после первого внутреннего блока и отображает первоначальное значение х, демонстрируя тем самым, что эта переменная никуда не исчезала и не изменялась.
Вероятно, наиболее интригующей частью программы является цикл while. В условии проверки цикла while задействована исходная переменная х:
while (х++< 33)
Однако внутри цикла программа видит третью переменную х, т.е. ту, которая определена в рамках блока цикла while. Таким образом, когда в теле цикла используется выражение х+ + , в нем участвует новая переменная х, значение которой инкрементируется до 101 и затем отображается. По завершении каждой итерации цикла эта новая переменная х исчезает.
Читать дальшеИнтервал:
Закладка: