- •Оглавление
- •1.2. Свойства языков программирования
- •1.3. Основные парадигмы программирования Процедурное программирование
- •Модульное программирование
- •Абстракция данных
- •Объектно-ориентированное программирование
- •Непечатные символы
- •Тема 2 Типы данных
- •2.1. Понятие переменной и объявление переменных
- •Объявление переменных
- •Встроенные типы данных
- •Размер памяти, выделяемой под встроенные типы данных
- •2.2. Константы и перечисления Константные переменные
- •Перечисления
- •2.3. Операции и выражения
- •Мультипликативные операции
- •Операции сравнения
- •Побитовые логические операции
- •Побитовые операции
- •Комментарии
- •Оператор while(пока)
- •Оператор do/while(выполнять/пока)
- •Оператор for(цикл)
- •Оператор множественного выбора switch
- •Операторы breakиcontinue
- •Тема 4 Массивы
- •4.1.Определение, объявление и инициализация массивов
- •Объявления и инициализация массивов в программе
- •4.2. Сортировка массивов Пузырьковая сортировка
- •Сортировка вставками
- •4.3. Поиск в массивах Линейный поиск
- •Двоичный поиск
- •4.4. Многомерные массивы
- •Тема 5 Указатели Объявления и инициализация переменных указателей
- •5.1. Операции над указателями
- •5.2. Выражения и арифметические действия с указателями
- •5.3. Взаимосвязи между указателями и массивами
- •5.4. Массивы указателей
- •5.5. Динамическое выделение памяти под массивы
- •Тема 6 Функции
- •6.2. Определения функций
- •Генерация случайных чисел
- •6.3. Классы памяти и область действия Классы памяти
- •Область действия
- •6.4. Рекурсия
- •6.5. Ссылки и ссылочные параметры
- •Вызов функций по ссылке с аргументами указателями
- •6.6. Использование спецификатораconstс указателями
- •6.7. Перегрузка функций
- •Аргументы по умолчанию
- •6.8. Передача массивов в функции
- •6.9. Указатель на функцию
- •6.10. Командная строка аргументов
- •6.11 Неопределенное количество аргументов
- •Тема 7 Введение в обработку строк
- •7.1. Работа со строками в с
- •Понятие символов и строк в с
- •Функции для работы со строками
- •Определение длины строки
- •Сложение двух строк (конкатенация)
- •Добавление к исходной строке указанного количества символов.
- •Копирование строки в другую строку
- •Сравнение строк
- •Получение строки от пользователя
- •Тема 8 Работа с файлами
- •Открытие файла
- •Чтение из файла символа или строки символов
- •Запись символа или строки символов в файл
- •Смещение внутри файла
- •Значения параметра fromwhereфункцииfseek
- •Закрытие файла
- •Тема 9 Компоновка программ и препроцессор
- •9.1. Компоновка программ
- •Проблема использования общих функций и имен
- •Использование включаемых файлов
- •9.2. Препроцессор
- •Определение макросов
- •Условная компиляция
- •Дополнительные директивы препроцессора
- •Тема 10 Структуры
- •10.1. Определение структур и доступ к элементам
- •Доступ к элементам структур
- •Использование структур
- •10.2. Битовые поля
- •10.3. Объединения
- •10.4. Построение связных списков на основе структур с самоадресацией
- •Создание простого связного списка
- •Очереди
- •Деревья
- •Список рекомендуемой литературы
5.4. Массивы указателей
Массивы могут содержать указатели [1]. Типичным использованием такой структуры данных является формирование массива строк. Каждый элемент такого массива – строка, но в С строка является, по существу, указателем на ее первый символ. Таким образом, каждый элемент в массиве строк в действительности является указателем на первый символ строки (см. рис. 5.3.). Рассмотрим объявление массива строкsuit
char *suit[4] = {“весна”, “лето”, “осень”, “зима”};
Элемент объявления suit[4]указывает массив из четырех элементов. Элемент объявленияchar*указывает, что тип каждого элемента массиваsuit– «указатель наchar». Четыре значения, размещаемые в массиве – это «весна», «лето», «осень», «зима». Каждое из них хранится в памяти как строка, завершающаяся нулевым символом, которая на один символ длиннее, чем число символов текста, указанного в кавычках. Эти четыре строки имеют длину 6, 5, 6 и 5 символов соответственно. Хотя это и выглядит так, словно эти строки помещены в массивsuit, на самом деле в массиве хранятся лишь указатели. Таким образом, хотя размер массиваsuitфиксирован, он обеспечивает доступ к строкам символов любой длины.
suit[0] |
|
|
‘в' |
‘е' |
‘с' |
‘н' |
‘а' |
‘\0' |
suit[1] |
|
|
‘л' |
‘е' |
‘т' |
‘о' |
'\0' |
|
suit[2] |
|
|
‘о' |
‘с' |
‘е' |
‘н' |
‘ь' |
'\0' |
suit[3] |
|
|
‘з' |
‘и' |
‘м' |
‘а' |
'\0' |
|
Рис. 5.3. Выделение памяти под массивы указателей
Строки символов могут быть размещены в двумерном массиве, в котором каждая строка представляет одно время года, а каждый столбец представляет одну букву имени времени года. Такая структура должна иметь фиксированное количество столбцов на строку и это количество должно быть таким большим, как самая длинная строка. Поэтому затраты памяти на хранение большого количества строк, большинство из которых короче, чем самая длинная строка, будут значительными.
5.5. Динамическое выделение памяти под массивы
Иногда заранее неизвестны размеры массивов. Тогда необходимо применять динамические массивы. При использовании массивов в предыдущих программах на этапе компиляции определялось, сколько места в памяти займет этот массив. И память под массив выделялась до выполнения самой программы, как под любые другие переменные.
int i,k;
char c;
char * MyArr;
cout << "Enter a number" << endl;
cin >> i;
//выделение памяти под массив символьного типа
MyArr = new char[i];
for (k=0;k<i;k++)
{
MyArr[k] = k+60;
c = MyArr[k];
printf("%c\n", c);
}
//освобождение памяти из-под массив
delete [] MyArr;
Рис. 5.4. Работа с одномерным динамическим массивом
В случае если заранее неизвестны размеры массивов, тогда необходимо выделять память под массивы уже в процессе выполнения программы, получив от пользователя или рассчитав размер массива (рис. 5.4, 5.5 и 5.6).
int i,j, k, c;
int ** MyArr;
cout << "Enter two numbers" << endl;
cin >> i >> j;
//выделение памяти под двумерный массив
//сначала под массив указателей
MyArr = new int*[i];
//потом под каждый из подмассивов
for (k=0;k<i;k++)
{
MyArr[k] = new int[j];
}
//******************************************
Рис. 5.5. Выделение памяти под двумерный динамический массив
//вывод на экран элементов массива
for (c=0;c<i;c++)
{
for (k=0; k<j;k++)
{
MyArr[c][k] = c+k;
cout << MyArr[c][k] << '\t';
}
cout << endl;
}
//***************************************
//освобождение памяти
//сначала у каждого подмассива
for (k=0; k<i;k++)
delete []MyArr[k];
//потом у массива указателей
delete [] MyArr;
//************************************
Рис. 5.6. Работа с двумерным массивом и освобождение памяти из-под двумерного динамического массива