- •Аннотация
- •Предисловие
- •Г л а в а 1. Введение в указатели
- •§1. Понятие указателя. Операции разыменования и разадресации
- •§2. Инициализация и присваивание указателей
- •§3. Передача параметров функций с помощью указателей.
- •§4. Распределение динамической памяти.
- •4.1. Операция new
- •4.2. Операция delete
- •Упражнения, тесты.
- •Указатели и массивы
- •§1. Связь указателей и массивов
- •1.1. Указатели и одномерные массивы
- •1.2. Указатели и матрицы
- •Int MyFun (int *X, int n)
- •§3. Операции над указателями при работе с массивами.
- •3.1. Арифметические операции
- •3.2. Операции сравнения.
- •§4. Использование операций над указателями при работе с одномерными массивами
- •4.1. Использование индексов
- •4.2. Указатель в качестве параметра цикла
- •4.3. Использование указателя и индекса
- •§5. Строки.
- •5.1. Общая характеристика строк.
- •5.2. Примеры алгоритмов работы со строками.
- •5.3. Анализ строковых функций.
- •§6. Использование операций над указателями при работе со статической матрицей.
- •Упражнения, тесты.
- •Массивы указателей
- •§1. Статический массив указателей
- •§2. Частично динамическая матрица.
- •Int arr_of_size[n];
- •§3. Статический массив строк
- •§4. Динамический массив указателей
- •4.1. Указатель на указатель
- •4.2. Динамические “матрицы”.
- •Int *arr_of_size;
- •4.3. Передача матрицы в функцию
- •Int a[10]; FunArr1(a, 10,…);
- •Упражнения, тесты.
- •Задачи второго среднего уровня.
- •Структуры и другие типы, определяемые пользователем
- •§1. Структуры
- •Объявление структуры
- •1.2. Работа со структурой.
- •1.3. Вложенные структуры и статические массивы в структурах
- •1.4. Статический массив структур
- •§2. Cтруктуры и указатели
- •2.1. Указатели в структуре.
- •2.2. Указатели на структуру
- •2.3. Динамический массив структур
- •2.4. Ссылка на структуру.
- •2.5. Указатели и вложенные структуры
- •§3. Cтруктуры и функции
- •3.1. Передача полей структуры в функцию.
- •Void MyFun1 (int X, float &y, int *u1, float *u2, char *s);
- •3.2. Передача всей структуры в функцию
- •Void Fun1 (tst s,…);
- •Void Fun2 (tst & s,…);
- •Void Fun3 (tst* s,…);
- •§4. Cтруктуры и классы.
- •§5. Объединения.
- •Представление вещественных чисел в памяти компьютера.
- •§6. Поля битов (битовые поля)
- •Ввод в ы в о д
- •Symbol Code16 Code10 Code2
- •§7. Перечисления
- •Какие из строк (//1 – //9) правильные?
2.2. Указатели на структуру
Можно определять указатели на структуру по обычным правилам:
имя_структурного_типа *имя_указателя_на_структуру;
Значением указателя на структуру является адрес структуры указанного типа, т.е. номер байта, начиная с которого структура размещается в памяти.
Например, используя определённый в предыдущем пункте тип и структурную переменную, можно так объявить указатель на структуру: tst*pS;
Инициализацию указателя на структуру можно выполнить одним из следующих способов.
a) Адрес структуры можно определить с помощью операции new. Это можно сделать вместе с объявлением
tst *pS1=new tst;
или раздельно
tst *pS1; pS1=new tst.
b) Можно определить указатель на другую структуру такого же типа pS2 и ему присвоить значение адреса одной из ранее определённой структуры (S1, см. 2.1) такого же типа tst. Например,
tst*pS2 =&S1; или tst*pS2; pS2 =&S1;
c) Для инициализации указателя на структуру можно использовать ранее опредлённый указатель на структуру такого же типа:
tst *pS3=pS1; или tst *pS3; pS3=pS1;
d) Можно использовать имя предварительно объявленного статического массива структур:
const n=10; tst ars[n]; tst *pS4=ars; или tst *pS4; pS4=ars;
Для доступа к полям структуры с помощью указателей имеются две возможности.
1) Вместо операции “.” (точка) следует использовать операцию “–>” (стрелка). Она образована из знака “минус” и символа ”больше”, между которыми не должно быть пробелов. Например, pS1–>m=random(9)+2; определяет поле m с помощью датчика случайных чисел; pS1->t=new char[20]; резервирует память для строки. Создание динамического массива внутри структуры выполняется так:
pS1–>ard=new float [pS1–>m];
for (int j=0; j< pS1–>m; j++) cin>>(pS1–>ard[j]);
2) Вторая возможность — это разыменование указателя и формирование уточнённого имени по следующему правилу:
(*имя_указателя).имя_поля.
Например, (*pS).per=25.5; Важна правильная расстановка скобок. Операция разыменование (‘*’) должна относиться к имени указателя, а не к уточнённому имени элемента структуры.
Из двух приведенных возможностей чаще используется первая (см. например, визуальную систему Builder).
Но если в переменной указателе хранится адрес начала массива (pS4), то доступ к полю i – й структуры, т.е. i – го элемента этого массива осуществляется с использованием операции “.”(точка). Это связано с тем, что pS4 — это указатель, а pS4[i] — i – я структура, а не адрес. Поэтому правильным будет следующий фрагмент программы:
for (int i=0; i<n;i++)
{ pS4[i].m=random(5)+1;
pS4[i].ard=new float [pS4[i].m];
for (int j=0; j< pS4[i].m; j++)
cin>>( pS4[i].ard[j]);
…
}
Здесь массив структур pS4 статический, а массив в структуре ard динамический.
2.3. Динамический массив структур
Из объявления tst *arSd; ещё не видно, будет создан указатель на одну структуру или динамический массив структур. Это зависит от того, как будет проинициализирован этот указатель. Если, как в предыдущем пункте, выполнить операцию arSd=new tst; то будет создан указатель на одну структуру.
С помощью этой же операции new можно выделить память для динамического массива структур. Это выполняется следующим образом:
int n; cin>>n; // или const n=5;
arSd=new tst[n];
Адрес начала массива структур присваивается переменной указателю arSd. Доступ к полям i– й структуры осуществляется следующим образом:
for (int i=0; i<n;i++)
{ arSd [i].m=random(5)+1;
arSd [i].ard=new float [arSd [i].m];
for (int j=0; j< arSd [i].m; j++)
cin>>( arSd [i].ard[j]);
…
}
Здесь и массив структур arSd, и массив в структуре ard динамические.