- •Министерство образования Республики Беларусь
- •1. Что такое программа на языке программирования
- •2. Общее знакомство с языком с
- •3. Структура простой программы на языке с
- •4. Что такое программа на языке с
- •5. Представление информации и типы данных в языке с
- •6. Константы
- •7. Переменные
- •8. Элементарный вВод и вывод информации
- •9. Выражения и операции
- •9.1. Арифметические операции
- •9.2. Операция изменения знака
- •9.3. Операции инкремента и декремента
- •9.4. Операция присваивания
- •9.6. Поразрядные логические операции
- •9.8. Логические операции и операции отношения
- •9.9. Условная операция «? :»
- •9.10. Операция последовательного вычисления
- •9.11. Операция определения требуемой памяти в байтах sizeof
- •9.12. Операция приведения типа (type)
- •10. Операторы управления вычислительным процессом
- •10.1. Операторы ветвления if и else
- •10.2. Оператор switch
- •10.3. Оператор цикла while
- •10.4. Оператор цикла do…while
- •10.5. Оператор цикла for
- •10.6. Бесконечные циклы
- •10.7. Другие управляющие средства языка с
- •10.8. Стандартные математические функции
- •11. Вычисление выражений и побочные эффекты
- •11.1. Преобразования типов при вычислении выражений
- •11.2. Побочные эффекты при вычислении выражений
- •12. Массивы
- •12.1. Описание массива
- •12.2. Инициализация массива
- •12.3. Ввод-вывод массива
- •12.4. Двумерные массивы (массивы массивов)
- •13. Указатели
- •14. Адресная арифметика
- •15. Массивы и указатели
- •15.1. Указатели и одномерные массивы
- •15.2. Указатели и двумерные массивы
- •16. Строки
- •17. Массивы строк
- •18. Функции
- •18.1. Определение функции в языке с
- •18.2. Возвращение значений из функции
- •18.3. Формальные и фактические параметры функции
- •18.4. Вызов функции
- •18.5. Объявление и определение функции: прототип функции
- •19. Передача параметров в функции
- •19.1. Способы передачи параметров в функции
- •19.2. Передача параметров в функции в языке с
- •19.3. Передача указателей в функции
- •20. Классы хранения и видимость переменных
- •20.1. Общие положения
- •20.2. Спецификаторы класса памяти
- •20.3. Область видимости функций
- •20.4. Глобальные переменные
- •20.5. Глобальные статические переменные
- •20.6. Локальные переменные
- •20.7. Статические локальные переменные
- •20.8. Регистровые переменные
- •20.9. Выводы
- •21. Организация памяти программы
- •22. Многофайловая компиляция (проекты)
- •23. Передача в функции массивОв
- •23.1. Передача одномерных массивов в функции
- •23.2. Передача двумерных массивов в функции
- •23.3. Передача в функции символьных строк
- •23.4. Возвращение указателей из функций
- •24. Функции с переменным количеством аргументов
- •24.1. Соглашения о вызовах: модификаторы функций
- •24.2. Объявление списка параметров переменной длины
- •25. Передача параметров в функцию main()
- •26. Указатели на функцию
- •27. Стандартные функцИи языка с
- •27.1. Функции для работы со строками
- •27.2. Функции для проверки символов и преобразования данных
- •27.3. Функция быстрой сортировки – gsort()
- •27.4. Функция двоичного поиска – bsearch()
- •28. Работа с файлами
- •28.1. Основные понятия
- •28.2. Основные функции для работы с файлами
- •28.3. Открытие и закрытие файлов
- •28.4. Ввод/вывод символов
- •28.5. Ввод/вывод строк
- •28.6. Форматированный ввод/вывод
- •28.7. Ввод/вывод блоков данных
- •28.8. Другие средства для работы с файлами
- •28.9. Ввод/вывод низкого уровня (префиксный доступ к файлам)
- •29. Типы, определяемые пользователем: Перечисления, структуры и объединения
- •29.1. Переименование типов – оператор typedef
- •29.2. Перечисления (enum)
- •29.3. Основные сведения о структурах
- •29.4. Структурные переменные в памяти компьютера
- •29.5. Доступ к полям структуры
- •29.6. Массивы структур
- •29.7. Структуры и функции
- •29.8. Объединения (union)
- •30. Динамическая память
- •30.1. Понятие динамического объекта
- •30.2 Создание и уничтожение динамических объектов
- •30.3 Динамическое размещение одномерных массивов и строк
- •30.4 Динамическое размещение двумерных массивов
- •30.5. Функции для работы с блоками памяти
- •31. Динамические структуры данных
- •31.1. Понятие структуры данных
- •31.2. Структуры, ссылающиеся на себя
- •31.3. Связанные списки
- •31.5. Очереди
- •Ниже приводятся примеры функций для очереди (структура элемента очереди совпадает со структурой элемента стека в примере выше):
- •32. Препроцессор языка с
- •32.1 Директива включения файлов
- •32.2. Директива определения макрокоманд (макросов)
- •32.3 Директива условной компиляции
- •32.4 Дополнительные директивы препроцессора
20.5. Глобальные статические переменные
Спецификатор static в определении глобальной переменной заставляет компилятор создать глобальную переменную, видимую только в том файле, в котором она объявлена. Статическая глобальная переменная, таким образом, подвергается внутреннему связыванию. Это значит, что хоть эта переменная и глобальная, тем не менее процедуры в других файлах не увидят ее и не смогут случайно изменить ее значение. Этим снижается риск нежелательных побочных эффектов.
Глобальная переменная может быть определена только один раз в пределах своей области видимости. В другом исходном файле может быть объявлена другая глобальная переменная с таким же именем и с классом памяти static, конфликта при этом не возникает, так как каждая из этих переменных будет видимой только в своем исходном файле.
20.6. Локальные переменные
Переменные, определенные внутри блока (в том числе и функции), являются локальными и имеют по умолчанию класс памяти auto. Переменная с классом памяти auto имеет локальное время жизни и видна только в блоке, в котором объявлена (точнее, от места определения до конца блока). Память для такой переменной выделяется в стеке при входе в блок и освобождается при выходе из блока. При повторном входе в блок этой переменной может быть выделен другой участок памяти. Таким образом, локальная переменная, например, не может сохранять свое значение в промежутках между вызовами функции.
void f1 () {
int a = 0;
a = a + 1;
}
В данном примере, сколько бы раз не вызывалась функция, переменная a никогда не станет больше единицы.
Переменная с классом памяти auto автоматически не инициализируется. Она может быть проинициализирована явно при определении путем присвоения ей начального значения. Значение неинициализированной переменной с классом памяти auto считается неопределенным (точнее, случайным). При входе в блок под нее просто отводится память, прямо с тем содержимым, которое в ней было. В результате в неинициализированных локальных переменных оказывается «мусор» – непредсказуемые значения, которые к тому же могут меняться от вызова к вызову функции, поскольку зависят от предистории работы программы.
Формальные параметры функции находятся в ее области действия. Это значит, что параметры доступны внутри всей функции. Параметры создаются в начале выполнения функции и уничтожаются при выходе из нее. По своей сути формальные параметры являются локальными переменными функции и тоже располагаются в стеке.
void f1 () {
int a; // объявление локальной переменной
f2(100);
}
void f2 (int b) {
b = 10;
a = 3; // ошибка, отсутствует объявление переменной
}
Описание локальных переменных возможно не только в начале, но и в произвольном месте в функции. Тогда эту переменную можно использовать от момента определения до конца функции.
Также можно объявить локальную переменную в блоке: в начале блока или в середине. Переменная, объявленная в блоке, «прячет» любую другую переменную с таким же именем, описанную вовне.
void main() {
int x = 10;
int a = 5, b = 7;
if (a<b) { // начало вложенного блока
int y; // локальная для блока переменная
y = x+7;
printf("x = %d\n", x); // x = 10
printf("y = %d\n", y); // y = 17
int x; // описание новой переменной внутри блока
x = 20;
y = x+7;
printf("x = %d\n", x); // x = 20
printf("y = %d\n", y); // y = 27
}
printf("x = %d\n", x); // x = 10
// printf("y = %d\n", y); // ошибка – неопределенная переменная y
}
Переменная, объявленная локально с классом памяти extern, является ссылкой на переменную с тем же самым именем, определенную глобально в одном из исходных файлов программы. Цель такого объявления состоит в том, чтобы сделать определение переменной глобального уровня из другого файла видимым внутри блока. Также объявление с классом памяти extern требуется при необходимости использовать глобальную переменную, описанную в текущем исходном файле, но ниже по тексту программы, т.е. до выполнения ее глобального определения.
void main () {
...
}
void f1 () {
extern int x;// объявляем глобальную переменную, теперь ее можно
// использовать в этой функции, иначе компилятор выдал бы
x = 15; // ошибку, что переменная ещё не определена
}
int x = 5; // определение глобальной переменной
int getX () {
return x; // getХ видит переменную x
}
Обратить внимание! В область видимости блока (в том числе и функции) входят все глобальные переменные, объявленные до начала блока, а также локальные переменные объявленные в этом блоке и локальные переменные, объявленные во всех охватывающих блоках (другими словами, локальная переменная видна в блоке, в котором описана, в также во всех вложенных блоках при условии, что во вложенном блоке нет своей локальной переменной с таким же именем (если есть, то такая переменная делает недоступной переменную с таким же именем из внешнего блока, в том числе и глобальную) ).
int getZ(void); // описание прототипа функции
int x = 5; // определение глобальной переменной
void main () { // БЛОК 1
extern int y; // объявляем глобальную переменную y
int a, b; // описываем локальные a и b
scanf("%d%d", &a, &b);
if (a < b) { // БЛОК 2
extern int z; // объявляем глобальную переменную z
int i = x + y + z; // описываем локальную i
printf("i = %d\n", i); // при вводе 1 и 2 получим 8
}
else { // БЛОК 3
int x = 0; // перекрывает глобальную x локальной x
int i; // это совсем другая локальная i, а не из блока 2
for (i=0; i<5; i++) { // БЛОК 4
int a = getZ()*i; // перекрывает переменную а из main()
x += a;
}
printf("x = %d\n", x); // при вводе 2 и 1 получим 20
}
}
int y = 1; // определение глобальной переменной
int z = 2; // определение глобальной переменной
int getZ () { // БЛОК 5
return z;
}
Вложенность блоков и локальные переменные блоков:
БЛОК |
Доступные локальные переменные |
Доступные глобальные переменные |
1 |
a b |
x y |
2 |
a b i |
x y z |
3 |
a b x i |
y |
4 |
b x i a |
y |
5 |
|
x y z |