
- •1.Фундаментальные типы данных. Структуры
- •Демонстрационный пример
- •1.2. Задачи для самостоятельного решения
- •Фундаментальные типы данных. Объединения
- •2.1. Демонстрационный пример
- •А.Пуанкаре Приведем пример использования объединения: составить программу, выполняющую требуемые операции для заданной фигуры.
- •2.2. Задачи для самостоятельного решения
- •3.Ссылочные типы
- •3.1. Указатели и адреса
- •3.2. Адресная арифметика
- •3.3. Операции new и delete
- •3.4. Демонстрационные примеры Чтение и переработка являются ключевыми в программировании. Б.Керниган, ф.Плоджер
- •3.5. Задачи для самостоятельного решения
- •3.4. Дано описание переменных: int *p,*q; char *r;. Какие из следующих операторов неправильны и почему?
- •4. Линейные однонаправленные списки
- •4.1. Задачи для самостоятельного решения
- •Г.Остер. Задачник
- •Построение
- •Модификация
- •Предикаты
- •Подсчет
- •5. Ортогональные списочные структуры ("гирлянды" и "висюльки")
- •5.1. Фрагмент теории
- •5.2. Задачи для самостоятельного решения
- •6. Кольцевые списки на базе однонаправленных списков
- •6.1. Фрагмент теории
- •6.2.Задачи для самостоятельного решения
3.Ссылочные типы
3.1. Указатели и адреса
Нетрудно свести лошадь к воде. Но если вы заставите ее плавать на спине - вот это значит, что вы чего-то добились!
Первый закон Хартли
Указатель - это переменная, содержащая адрес другой переменной, то есть значением переменной типа указатель является целое число, равное адресу того объекта, на который ссылается указатель.
Указатель существенно связан с типом объекта, на который он ссылается. Если в описании перед обозначением объекта поставить символ "*", то оно будет описывать указатель на объект того же типа и класса памяти, которые соответствуют данному обозначению без звездочки.
Указатели и целые переменные не являются взаимозаменяемыми объектами. Константа 0 - единственное исключение из этого правила: ее можно присвоить указателю и указатель можно сравнить с нулевой константой. Чтобы показать, что 0 - это специальное значение для указателя, вместо числа 0, как правило, записывают NULL - константу, определенную в файле stdio.h.
Унарная операция "*", называемая операцией косвенной адресации, рассматривает свой операнд как адрес объекта и обращается по этому адресу, возвращая его содержимое.
Унарная операция "&", называемая операцией нахождения адреса, примененная к переменной, возвращает ее адрес.
Например, рассмотрим последовательность операторов:
int x,y,*px;//Описание целочисленных переменных x,y и
//указателя на целое значение px.
px = &x; //Значением переменной px станет адрес переменной x.
y = *px; //Переменная y приобретает значение "того",
// на что указывает px, то есть значение переменной x.
Таким образом, два оператора присваивания в примере эквивалентны одному оператору y=x; и *px может появляться в любом выражении, в котором может встретиться х, например, продолжим рассмотрение предыдущего примера:
*px = 0;//Переменная х получает значение 0.
y = *px + 1; //Переменная y получает значение на 1 больше x.
*px += 1;//Увеличение содержимого x на единицу.
*px++;//Увеличение содержимого x на единицу, при
// этом постфиксная операция ++ не изменяет px,
//пока объект по адресу px не будет получен.
*++px; //Префиксная операция ++(--) увеличивает
*--px; //(уменьшает) px до получения значения x.
py = px; //Копирование содержимого указателя px в указатель
//py в результате чего py указывает на то же, что и px.
Замечания
1. Операция "&" применима только к переменным: конструкции вида &(х-3) или &5 запрещены.
2. Нельзя получить адрес регистровой переменной.
3.2. Адресная арифметика
В известном смысле недостатки любого произведения сводятся к одному - оно слишком длинно.
Вовенарг. Размышления и максимы. Дополнения
Вначале заметим, что ни один "правильный" указатель не может иметь значения 0, поэтому равенство нулю значения указателя может служить сигналом о ненормальном завершении выполнения функции.
Допустимы:
присваивание значения указателя другому указателю того же типа;
"операция" инициализации указателя. "Операторы":
char a;
char *pa=&a;
описывают символьную переменную a и указатель pa на объект типа char, а также инициализируют pa так, чтобы он указывал на a;
операция вычитания указателей одного и того же типа;
операции сложения и вычитания указателя и целого. Приведем несколько примеров:
пусть p - указатель на объект любого типа. Тогда оператор p++; увеличивает p так, что он указывает на следующий объект того же типа;
пусть i - переменная целого типа. Оператор p += i; увеличивает указатель p так, чтобы он указывал на объект, отстоящий на i "единиц" памяти, занимаемых объектом данного типа, от объекта, на который указывает p;
Операции сравнения указателей одного и того же типа. Если p и q - указатели на объекты одного типа, то к ним применимы операции отношения (<, >=, >, <=, !=, ==). Например:
отношение p!=q истинно, если p и q указывают на разные объекты;
отношение p==q истинно, если p и q указывают на один и тот же объект;
отношение p!=NULL истинно, если указатель p отличен от NULL;
Присваивание указателю нуля (NULL) и сравнение указателя с нулем (NULL).
Ниже мы будем часто пользоваться следующими стандартными операциями, используемыми для выделения и освобождения блоков памяти.