- •Структуры и алгоритмы обработки данных Введение
- •1. Структуры данных
- •1.1 Уровни структур данных
- •1.2 Классификация структур данных
- •1.3. Информация и ее представление в памяти эвм
- •2. Простые структуры данных
- •2.1. Понятие о типах данных
- •2.2. Перечисляемый тип данных
- •2.3. Стандартные типы данных
- •2.3.1. Целочисленные типы
- •2.3.2. Вещественные числа
- •2.3.3. Представление и структуры хранения логической информации
- •2.4. Указатели
- •2.4.1. Назначение и смысл указателей
- •2.4.2 Операции с адресами
- •2.4.3 Указатели на указатели
- •2.5. Алгоритмы обработки простых структур данных
- •3. Линейные статические структуры данных
- •3.1 Массивы
- •3.2. Динамические массивы
- •3.3. Многомерные массивы
- •3.4. Связь массивов с указателями
- •3.5. Строки
- •3.6. Массивы указателей
- •3.7. Интерпретация составных описателей
- •3.8 Алгоритмы обработки статических линейных струткур
- •4. Ссылки
- •5. Интегральные типы данных (структуры, битовые поля, объединения)
- •5.1. Структуры
- •5.2. Битовые поля
- •5.3. Объединения
- •6. Файлы
3.8 Алгоритмы обработки статических линейных струткур
Алгоритмы обработки статических линейных струткур чаще всего также носят линейный характер и представляют собой циклы, подобные циклам создания и удаления двумерного динамического массива (§3.3). Наряду с операциями, используемыми для простых структур данных – просмотр, модификация, ввод и вывод, – к массивам и другим линенйным структрурам (не только статическим) применяются более сложные операции, например, поиск, реверсирование (обращение).
Алгоритмы поиска, в том числе, в линейных структурах, будут рассмотрены позднее.
Операция реверсирования представляет собой перестановку элементов структуры данных, например, массива, в обратном порядке. Реверсирование может оказаться полезным в случае, когда массив упорядочен, например, по убыванию, и требуется переупорядочить его по возрастанию.
const int N = 10; // Размер массива
float mas[N] = {9., 8., 7., 6., 5., 4., 3., 2., 1., 0. };
float buf;
void main()
{
//…
for(int a = 0; a< N/2; a++)
{
buf = mas[a];
mas[a] = mas[N–a];
mas[N–a] = buf;
}
//…
}
Часто требуется скопировать содержимое одного массива в другой. Наиболее просто такая операция выполняется, если массив-приёмник по размерам не превосходит массив-источник. Удобно оформить эту операцию в виде отдельной процедуры.
float mas1[N];
void MasCopy(float* a, float* b, int n)
{
for(int x = 0; x<n; x++)
b[x] = a[x];
}
4. Ссылки
Ссылки представляют собой второе имя (или псевдоним) объекта; объявляются при помощи символа &, при объявлении обязательно должны быть инициализированы именами тех объектов, псевдонимами которых они будут являться.
double agent = .028;
double &bond = agent;
// …
bond /= 4.0 // agent ~ .007
В общем случае в качестве инициализирующего выражения должно выступать имеющее значение L-выражение (имя объекта, реально существующего в памяти). Значением ссылки после определения с инициализацией становится адрес этого объекта. Повторное присвоение значения ссылке не допускается, т.е. невозможно сделать так, чтобы некоторая конкретная ссылка ссылалась на другой объект.
В определении ссылки символ & не является частью типа, т.е. имя bond имеет тип double.
Могут существовать ссылки на любые используемые в программе типы, как стандартные, так и созданные программистом (записи, классы и т.п.), кроме перечисленных ниже.
Функционально ссылка ведет себя подобно обычной переменной того же типа.
Ссылки повышают эффективность программ при передаче больших объектов в функции, поскольку не требуют копирования объекта в стек;
– предоставляют функциям механизм изменения значения передаваемого им аргумента (за счёт передачи адреса объекта, подобно указателю, а не копии объекта);
– используются, главным образом, при определении компонентных функций классов;
– не являются самостоятельными объектами и существуют только после инициализации; какие-либо операции выполняются не над ссылками, а над объектами, на которые они ссылаются;
int i;
int &ir = i;
ir = 3; // i = 3
int j;
j = i * ir; // j ~ 9
ip = &ir; // ip получает адрес i
– не могут ссылаться на другую ссылку или на битовое поле. Не может быть ни массивов ссылок, ни указателей на ссылку, но может быть объявлена ссылка на указатель.
int *&rpi;
Если тип инициализированной ссылки не совпадает с типом объекта, то создается анонимный объект, для которого ссылка является псевдонимом, инициализирующее значение преобразуется к типу ссылки и используется установки значения анонимного объекта.
double d;
int &ir = d; // несовпадение типов => анонимный объект
ir = 3.0; // значение d не изменилось, анонимный объект получил значение 3
Ссылка не может иметь тип void, для ссылки нельзя выделить участок памяти операцией new. Значение ссылки не может изменяться. Но любой объект может быть адресован любым количеством ссылок (также как и указателей).
Можно определить ссылку на константу, используя модификатор const. Ссылка на константу не позволяет изменить значение того объекта, с которым она связана.
double agent = .028;
const double &Bond = agent;
agent = 0.035; // правильно
Bond = .008; // ошибка