Стивен Прата - Язык программирования C. Лекции и упражнения (6-е изд.) 2015
- Название:Язык программирования C. Лекции и упражнения (6-е изд.) 2015
- Автор:
- Жанр:
- Издательство:Вильямс
- Год:0101
- ISBN:нет данных
- Рейтинг:
- Избранное:Добавить в избранное
-
Отзывы:
-
Ваша оценка:
Стивен Прата - Язык программирования C. Лекции и упражнения (6-е изд.) 2015 краткое содержание
Язык программирования C. Лекции и упражнения (6-е изд.) 2015 - читать онлайн бесплатно полную версию (весь текст целиком)
Интервал:
Закладка:
Область видимости определяет, какие части программы могут иметь доступ к данным. Переменная, определенная вне любых функций, имеет область видимости в пределах файла и видна любой функции, определенной после объявления этой переменной. Переменная, определенная внутри блока или в качестве параметра функции, имеет область видимости в пределах блока и видна только этому блоку и всем вложенным в него блокам.
Связывание описывает диапазон, в пределах которого переменная, определенная в одной единице программы, может быть привязана к какой-то другой ее единице. Переменные с областью видимости в пределах блока, будучи локальными, не имеют связывания. Переменные с областью видимости в пределах файла, имеют внутреннее или внешнее связывание. Внутреннее связывание означает, что переменная может использоваться только в файле, содержащем ее определение. Внешнее связывание означает, что переменная может применяться также и в других файлах.
524 Глава 12
Ниже описаны классы хранения в С (кроме концепций, относящихся к потокам).
• Автоматический. Переменная, объявленная в блоке (или в качестве параметра в заголовке функции) без модификатора класса хранения или с модификатором класса хранения auto, принадлежит к автоматическому классу хранения. Она характеризуется автоматической продолжительностью хранения, областью видимости в пределах блока и отсутствием связывания. Если она не инициализирована, то ее значение не определено.
• Регистровый. Переменная, объявленная в блоке (или в виде параметра в заголовке функции) с модификатором класса хранения register, принадлежит к регистровому классу хранения. Она характеризуется автоматической продолжительностью хранения, областью видимости в пределах блока и отсутствием связывания. Адрес такой переменной получать нельзя. Объявление переменной как регистровой — это подсказка компилятору о необходимости обеспечить насколько возможно быстрый доступ. Если она не инициализирована, то ее значение не определено.
• Статический, без связывания. Переменная, объявленная в блоке с модификатором класса хранения static, принадлежит к классу хранения “статический, без связывания”. Она характеризуется статической продолжительностью хранения, областью видимости в пределах блока и отсутствием связывания. Такая переменная инициализируется только один раз на этапе компиляции. Если она не инициализирована явно, ее биты устанавливаются в 0.
• Статический, внешнее связывание. Переменная, которая определена как внешняя по отношению к любой функции и без использования модификатора класса хранения static, принадлежит к классу хранения “статический, внешнее связывание”. Она имеет статическую продолжительность хранения, область видимости в пределах файла и внешнее связывание. Такая переменная инициализируется только один раз на этапе компиляции. Если она не инициализирована явно, ее биты устанавливаются в 0.
• Статический, внутреннее связывание. Переменная, которая определена как внешняя по отношению к любой функции и с указанием модификатора класса хранения static, принадлежит к классу хранения “статический, внутреннее связывание”. Она имеет статическую продолжительность хранения, область видимости в пределах файла и внутреннее связывание. Такая переменная инициализируется только один раз на этапе компиляции. Если она не инициализирована явно, ее биты устанавливаются в 0.
Выделение памяти обеспечивается функцией malloc() (или родственной ей), которая возвращает указатель на блок памяти, имеющий запрошенное количество байтов. Эту память можно сделать доступной для повторного использования, вызвав функцию free() с передачей адреса в качестве аргумента.
Квалификаторами типа являются const, volatile и restrict. Квалификатор const указывает на константные данные. В случае применения с указателями const может определять, что константным является сам указатель или же данные, на которые указатель ссылается, в зависимости от места его размещения внутри объявления. Квалификатор volatile говорит о том, что данные могут изменяться процессами, внешними по отношению к программе. Он предназначен для предупреждения компилятора о том, что он должен избегать оптимизаций, которые предполагались бы в от сутствие volatile. Квалификатор restrict также введен по причинам, связанным с оптимизацией. Указатель, помеченный с помощью restrict, идентифицируется как единственное средство доступа к блоку данных.
Классы хранения, связывание и управление памятью 525
Вопросы для самоконтроля
Ответы на вопросы для самоконтроля приведены в приложении А.
1. Какие классы хранения создают переменные, локальные по отношению к функции, которая их содержит?
2. Какие классы хранения создают переменные, которые сохраняются на протяжении выполнения содержащей их программы?
3. Какой класс хранения создает переменные, которые могут использоваться в нескольких файлах? Только в одном файле?
4. Какой вид связывания имеют переменные с областью видимости в пределах блока?
5. Для чего используется ключевое слово extern?
6. Взгляните на следующий фрагмент кода:
int * p1 = (int *) malloc(100 * sizeof(int));
Чем от него отличается показанный ниже оператор в смысле конечного результата?
int * p1 = (int*) calloc(100, sizeof(int));
7. Каким функциям известна каждая переменная в следующем коде? Если ли в коде ошибки?
8. Что выведет следующая программа?
526 глава 12
int main(void)
{
extern char color;
printf("color в main() равно %c\n", color); first();
printf("color в main() равно %c\n", color); second();
printf("color в main!) равно %c\n", color); return 0;
}
void first(void)
{
char color; color = 'R';
printf("color в first() равно %c\n", color);
void second(void)
{
color = 'G';
printf("color в second(); равно %c\n", color);
}
9. Файл начинается со следующих объявлений:
static int plink;
int value_ct(const int arr[], int value, int n);
а. Что говорят эти объявления о намерениях программиста?
б. Увеличит ли защиту значений в вызывающей программе замена объявлений
int и int n объявлениями const int и const int n?
Упражнения по программированию
1. Перепишите программу из листинга 12.4 так, чтобы в ней не использовались глобальные переменные.
2. Расход бензина обычно измеряется в милях на один галлон в США и в литрах на 100 километров в Европе. Ниже приведена часть программы, которая предлагает пользователю выбрать режим (метрический или американский), а затем выполняет сбор данных и вычисляет расход топлива:
// pel2-2b.с
// компилировать вместе с ре12-2а.с #include
#include "pel2-2a.h" int main(void)
{
int mode;
printf ("Введите 0 для метрического режима или 1 для американского режима: "); scanf("%d", &mode); while (mode >= 0)
{
set_mode(mode); get_infо(); show_infо();
printf ("Введите 0 для метрического режима или 1 для американского режима"); printf(" (-1 для завершения): "); scanf("%d", &mode);
Читать дальшеИнтервал:
Закладка: