- •Министерство образования Республики Беларусь
- •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 Дополнительные директивы препроцессора
29.4. Структурные переменные в памяти компьютера
Поля структурной переменной располагаются в оперативной памяти последовательно в том порядке, в котором они объявляются: первому элементу соответствует меньший адрес памяти, а последнему – больший. Адрес переменной (поля структуры) – адрес младшего байта этой переменной. Адрес самой структурной переменной совпадает с адресом первого поля.
Обратить внимание! Поля структурной переменной хранятся в памяти друг за другом, между ними нет никаких других данных. Две структурные переменные необязательно расположены в памяти рядом.
При выделении памяти под структурную переменную учитывается такой параметр, как выравнивание структуры. Выравнивание задается опцией компилятора (Options→Compiler→Code generation...→Word alignment). Может быть задано выравнивание структуры или на границе байта, или на границе слова.
При выравнивании на границу байта все поля структуры в памяти располагаются вплотную одно за другим, без дырок. Длина структурной переменной будет равна сумме длин всех ее полей, а адрес может быть как четным, так и нечетным.
При выравнивании на границе слова компилятор при размещении структурной переменной в памяти вставляет между ее полями (а также между элементами массива структур) пустые байты так, чтобы соблюдались следующие правила:
отдельная структурная переменная (элемент массива) начинается на границе слова (с четного адреса);
любое поле не типа char начинается с четного адреса (имеет четное смещение от начала самой переменной);
при необходимости в конце структурной переменной добавляется еще один байт, чтобы общее число байтов для переменной было четным.
struct AAA {
int a;
char c[3];
int b;
};
int x = sizeof(AAA); // x = 8 при выравнивании на границу слова
// x = 7 при выравнивании на границу байта
29.5. Доступ к полям структуры
Для доступа к отдельным полям структурной переменной используется операция '.', а доступ к отдельному полю структуры осуществляется посредством конструкции вида:
имя_структурной_переменной.имя_поля
Сначала мы указываем имя структурной переменной, затем ставим точку и в конце указываем имя поля структуры.
Так как структура – это новый тип, можно описывать указатели на этот тип. Для доступа к полям структуры через указатель (через адрес структуры) используется операция '->' вместо операции '.'.
Ссылка на поле структурной переменной с использованием '.' или '->' может располагаться в любом месте выражения, точно так же, как и простая переменная. Она также обладает всеми свойствами обычной переменной.
Пример:
struct Point {
int x;
int y;
};
struct Point pnt1, pnt2 = {5, 7};
pnt1.x = 1;
pnt1.y = 10;
printf(“Точка 2: x=%d y=%d”, pnt2.x, pnt2.y);
float dist; // расстояние между точками 1 и 2
dist = sqrt((pnt1.x - pnt2.x) * (pnt1.x - pnt2.x)+
(pnt1.y - pnt2.y) * (pnt1.y - pnt2.y));
struct Point *ptr = &pnt2;
ptr->x = 0; // (*ptr).x = 0; pnt2.x = 0; (&pnt2)->x = 0;
ptr->y = 0; // (*ptr).y = 0; pnt2.y = 0; (&pnt2)->y = 0;
dist = sqrt((pnt1.x - ptr->x) * (pnt1.x - pnt2.x)+
(pnt1.y - ptr->y) * (pnt1.y - pnt2.y));
Поля структуры могут иметь любой тип, в том числе и быть другой структурой. Другими словами, структуры могут быть вложены друг в друга. Понятно, что шаблон вкладываемой структуры должен быть уже известен компилятору. Ссылка на поле вложенной структуры формируется из имени структурной переменной, имени структурного поля и имени поля вложенной структуры.
Пример (прямоугольник как пара точек на углах одной из его диагоналей):
struct Point {
int x;
int y;
};
struct Rect {
struct Point pnt1;
struct Point pnt2;
int color;
};
struct Rect t1, t2 = {{0,0}, {5,5}, 2};
struct Rect *p_rect;
struct Point *p_point;
t1.pnt1 = t2.pnt2;
t1.pnt2.x = 11;
t1.pnt2.y = t2.pnt1.y + 10;
t1.color = 4; // t1 = {{5,5}, {11,10}, 4};
p_rect = &t2;
p_point = &t2.pnt2;
p_rect->pnt1 = t1.pnt2;
p_rect->pnt2.x = 55;
p_point->y = 77;
t2.color = 1; // t2 = {{11,10}, {55,77}, 1};
Структура типа S не может содержать элемент, являющийся структурой типа S (структура не может вкладываться сама в себя). Однако структура типа S может содержать элемент, указывающий на структуру типа S. Это позволяет использовать структуры для построения сложных динамических структур данных – стеков, списков, деревьев и т.п.
struct Node {
int data;
struct Node *next; // указатель на объект типа Node
};