- Любовные романы
- Фантастика и фэнтези
- Ненаучная фантастика
- Ироническое фэнтези
- Научная Фантастика
- Фэнтези
- Ужасы и Мистика
- Боевая фантастика
- Альтернативная история
- Космическая фантастика
- Попаданцы
- Юмористическая фантастика
- Героическая фантастика
- Детективная фантастика
- Социально-психологическая
- Боевое фэнтези
- Русское фэнтези
- Киберпанк
- Романтическая фантастика
- Городская фантастика
- Технофэнтези
- Мистика
- Разная фантастика
- Иностранное фэнтези
- Историческое фэнтези
- LitRPG
- Эпическая фантастика
- Зарубежная фантастика
- Городское фентези
- Космоопера
- Разное фэнтези
- Книги магов
- Любовное фэнтези
- Постапокалипсис
- Бизнес
- Историческая фантастика
- Социально-философская фантастика
- Сказочная фантастика
- Стимпанк
- Романтическое фэнтези
- Ироническая фантастика
- Детективы и Триллеры
- Проза
- Юмор
- Феерия
- Новелла
- Русская классическая проза
- Современная проза
- Повести
- Контркультура
- Русская современная проза
- Историческая проза
- Проза
- Классическая проза
- Советская классическая проза
- О войне
- Зарубежная современная проза
- Рассказы
- Зарубежная классика
- Очерки
- Антисоветская литература
- Магический реализм
- Разное
- Сентиментальная проза
- Афоризмы
- Эссе
- Эпистолярная проза
- Семейный роман/Семейная сага
- Поэзия, Драматургия
- Приключения
- Детская литература
- Загадки
- Книга-игра
- Детская проза
- Детские приключения
- Сказка
- Прочая детская литература
- Детская фантастика
- Детские стихи
- Детская образовательная литература
- Детские остросюжетные
- Учебная литература
- Зарубежные детские книги
- Детский фольклор
- Буквари
- Книги для подростков
- Школьные учебники
- Внеклассное чтение
- Книги для дошкольников
- Детская познавательная и развивающая литература
- Детские детективы
- Домоводство, Дом и семья
- Юмор
- Документальные книги
- Бизнес
- Работа с клиентами
- Тайм-менеджмент
- Кадровый менеджмент
- Экономика
- Менеджмент и кадры
- Управление, подбор персонала
- О бизнесе популярно
- Интернет-бизнес
- Личные финансы
- Делопроизводство, офис
- Маркетинг, PR, реклама
- Поиск работы
- Бизнес
- Банковское дело
- Малый бизнес
- Ценные бумаги и инвестиции
- Краткое содержание
- Бухучет и аудит
- Ораторское искусство / риторика
- Корпоративная культура, бизнес
- Финансы
- Государственное и муниципальное управление
- Менеджмент
- Зарубежная деловая литература
- Продажи
- Переговоры
- Личная эффективность
- Торговля
- Научные и научно-популярные книги
- Биофизика
- География
- Экология
- Биохимия
- Рефераты
- Культурология
- Техническая литература
- История
- Психология
- Медицина
- Прочая научная литература
- Юриспруденция
- Биология
- Политика
- Литературоведение
- Религиоведение
- Научпоп
- Психология, личное
- Математика
- Психотерапия
- Социология
- Воспитание детей, педагогика
- Языкознание
- Беременность, ожидание детей
- Транспорт, военная техника
- Детская психология
- Науки: разное
- Педагогика
- Зарубежная психология
- Иностранные языки
- Филология
- Радиотехника
- Деловая литература
- Физика
- Альтернативная медицина
- Химия
- Государство и право
- Обществознание
- Образовательная литература
- Учебники
- Зоология
- Архитектура
- Науки о космосе
- Ботаника
- Астрология
- Ветеринария
- История Европы
- География
- Зарубежная публицистика
- О животных
- Шпаргалки
- Разная литература
- Зарубежная литература о культуре и искусстве
- Пословицы, поговорки
- Боевые искусства
- Прочее
- Периодические издания
- Фанфик
- Военное
- Цитаты из афоризмов
- Гиды, путеводители
- Литература 19 века
- Зарубежная образовательная литература
- Военная история
- Кино
- Современная литература
- Военная техника, оружие
- Культура и искусство
- Музыка, музыканты
- Газеты и журналы
- Современная зарубежная литература
- Визуальные искусства
- Отраслевые издания
- Шахматы
- Недвижимость
- Великолепные истории
- Музыка, танцы
- Авто и ПДД
- Изобразительное искусство, фотография
- Истории из жизни
- Готические новеллы
- Начинающие авторы
- Спецслужбы
- Подростковая литература
- Зарубежная прикладная литература
- Религия и духовность
- Старинная литература
- Справочная литература
- Компьютеры и Интернет
- Блог
Язык программирования Си для персонального компьютера - C. Бочков
Шрифт:
Интервал:
Закладка:
Возможно наличие в одном исходном файле на внешнем уровне нескольких объявлений переменной с одним и тем же именем. Следующая таблица позволяет определить реакцию компилятора языка Си в различных ситуациях изменения спецификации класса памяти в объявлении. Слово "пусто" в таблице означает ситуацию отсутствия спецификации класса памяти. Очевидно, что компилятор СП MSC строже ограничивает возможность переопределения класса памяти переменной.
Класс 1 Класс 2 СП TC СП MSC extern static static static static пусто static ошибка static extern static static пусто static static ошибкаПример: /* ИСХОДНЫЙ ФАЙЛ 1 */
/* объявление i, ссылающееся на данное ниже определение i */
extern int i;
main()
{
i = i + 1;
printf("%dn", i); /* значение i равно 4 */
next();
}
int i = 3; /* определение i */
next()
{
printf("%dn", i); /* значение i равно 5 */
other());
}
/* ИСХОДНЫЙ ФАЙЛ 2 */
/* объявление i, ссылающееся на определение i в первом исходном файле */
extern int i;
other()
{
i = i + 1;
printf("%dn", i); /* значение i равно 6 */
}
Два исходных файла в совокупности содержат три внешних объявления i. Только в одном объявлении содержится инициализация:
int i = 3; — глобальная переменная i определена с начальным значением 3.
Самое первое объявление extern в первом исходном файле делает глобальную переменную i доступной прежде ее определения в файле. Без этого объявления функция main не могла бы использовать глобальную переменную i. Объявление переменной i во втором исходном файле делает глобальную переменную i доступной во втором исходном файле.
Все три функции выполняют одно и то же действие: увеличивают i на 1 и печатают полученное значение. Значения распечатываются с помощью стандартной библиотечной функции printf. Печатаются значения 4, 5 и 6.
Если бы переменная i не была инициализирована ни в одном из объявлений, она была оы неявно инициализирована нулевым значением при компоновке. В этом случае программа напечатала бы значения 1, 2 и 3.
Объявление переменной на внутреннем уровне
Любая из четырех спецификаций класса памяти может быть использована для объявления переменной на внутреннем уровне. Если спецификация класса памяти опущена в объявлении переменной на внутреннем уровне, то подразумевается класс памяти auto. Как правило, ключевое слово auto опускается. Понятия объявления и определения для переменных внутреннего уровня совпадают, если только в объявлении не задана спецификация класса памяти extern.
Спецификация класса памяти auto объявляет переменную с локальным временем жизни. Область действия переменной распространяется на блок, в котором она объявлена, (и на все вложенные в него блоки). Переменные класса памяти auto автоматически не инициализируются, поэтому в случае отсутствия инициализации в объявлении значение переменной класса памяти auto считается неопределенным. Память под переменные класса памяти auto отводится в стеке.
Спецификация класса памяти register требует, чтобы компилятор языка Си выделил переменной память в регистре микропроцессора, если это возможно. Использование регистровой памяти обычно ускоряет доступ к переменной и уменьшает размер выполняемого кода программы. Переменные, объявленные с классом памяти register, имеют ту же самую область действия, что и переменные auto.
Число регистров, которое может быть использовано для хранения переменных, зависит от компьютера и от реализации компилятора языка Си. Если компилятор языка Си обнаруживает спецификацию класса памяти register в объявлении переменной, а свободного регистра не имеется, или переменная данного типа не может быть размещена в регистре, то переменной выделяется память класса auto. В СП MSC регистровая память всегда выделяется переменным в том порядке, в котором они объявляются в исходном файле. В СП TC, при наличии нескольких переменных класса памяти register в одном объявлении, регистровая память будет выделяться переменным в обратном порядке. Так, по объявлению register i, j; первой получит регистровую память переменная j.
В регистровой памяти может быть размещен объект размером не больше, чем тип int. К переменной, размещенной в регистре, нельзя применять операцию адресации. При вызове функций из блока, в котором определены регистровые переменные, содержимое регистров будет сохранено в памяти, а по возвращении в блок восстановлено.
Для каждого рекурсивного входа в блок порождается новый набор переменных класса памяти auto и register. При этом каждый раз производится инициализация переменных, в объявлении которых заданы инициализаторы.
Переменная, объявленная на внутреннем уровне со спецификацией класса памяти static, имеет глобальное время жизни, но ее область действия распространяется только на блок, в котором она объявлена (и на все вложенные блоки). В отличие от переменных класса памяти auto, переменные, объявленные со спецификацией класса памяти static, сохраняют свое значение при выходе из блока. Переменные класса памяти static могут быть инициализированы константным выражением. Если явной инициализации нет, то переменная класса памяти static автоматически инициализируется нулевым значением. Инициализация выполняется один раз во время компиляции и не повторяется при каждом входе в блок. Все рекурсивные вызовы данного блока будут разделять единственный экземпляр переменной класса памяти static.
Переменная, объявленная со спецификацией класса памяти extern, является ссылкой на переменную с тем же самым именем, определенную на внешнем уровне в любом исходном файле программы. Цель внутреннего объявления extern состоит в том, чтобы сделать определение переменной внешнего уровня (как правило, данное в другом исходном файле) доступным именно внутри данного блока. Внутреннее объявление extern не влияет на область действия объявляемой глобальной переменной в любой другой части программы.
Пример:
inl i = 1; /* определение i */
main()
{
/* объявление i, ссылающееся на данное выше определение */
extern int i;
/* начальное значение а равно нулю; область действия а — функция main */
static int a;
/* b будет (по возможности) помещено в регистр */
register int b = 0;
/* по умолчанию с будет иметь класс памяти auto */
int с = 0;
/* печатаются значения 1, 0, 0, 0*/
printf("%d,%d,%d,%dn", i, a, b, c);
}
other()
/* локальное переопределение переменной i */
int i = 16;
/* область действия переменной а — функция other */
static int a = 2;
a += 2;
/* печатаются значения 16, 4 */
printf("%d,%dn", i, a);
}
Переменная i определяется на внешнем уровне с начальным значением 1; В функции main объявление i является ссылкой на определение переменной i внешнего уровня. Эта ссылка необязательна, поскольку и без нее внешняя переменная i доступна во всех функциях данного исходного файла. Переменная а класса памяти static автоматически инициализируется нулевым значением, так как явная инициализация опущена. Определяется переменная b регистрового класса памяти и переменная с класса памяти auto. Вызывается стандартная функция printf, которая печатает значения 1, 0, 0, 0.
В функции other переменная i переопределяется как локальная переменная с начальным значением 16. Это не влияет на значение внешней переменной i, поскольку эти переменные никак не связаны между собой. Переменная а объявляется со спецификацией класса памяти static и начальным значением 2. Она никак не связана с переменной а, объявленной в функции main, так как область действия переменных класса памяти static на внутреннем уровне ограничена блоком, в котором они объявлены. Значение переменной а увеличивается на 2 и становится равным 4. Если бы функция other была вызвана еще раз в той же функции main, то значение а при входе было бы равно 4, а при выходе—6. Внутренние переменные класса памяти static сохраняют свои значения при входе в блок и выходе из блока, в котором они объявлены. Значение переменной а в функции main при этом не изменилось бы.

