- •Введение
- •Лабораторная работа № 13 одномерные массивы
- •Порядок выполнения работы
- •Контрольные вопросы
- •Задания для выполнения
- •Часть 1.
- •Часть 2.
- •Лабораторная работа № 14 многомерные массивы
- •Краткие теоретические сведения
- •Порядок выполнения работы
- •Контрольные вопросы
- •Задания для выполнения
- •Часть 1.
- •Часть 2.
- •Лабораторная работа № 15 сортировка и поиск в массивах
- •Краткие теоретические сведения
- •Порядок выполнения работы
- •Контрольные вопросы
- •Задания для выполнения
- •Лабораторная работа № 16 символьные массивы
- •Краткие теоретические сведения
- •Порядок выполнения работы
- •Контрольные вопросы
- •Задания для выполнения
- •Лабораторная работа № 17
- •Порядок выполнения работы
- •Задания для выполнения
- •Часть I
- •Часть II
- •Лабораторная работа № 18 программирование с использованием указателей
- •Краткие теоретические сведения
- •Порядок выполнения работы
- •Контрольные вопросы
- •Задания для выполнения
- •Лабораторная работа № 19 динамическое выделение памяти
- •Краткие теоретические сведения
- •Библиотечные функции
- •Создание одномерного динамического массива
- •Создание двумерного динамического массива
- •Порядок выполнения работы
- •Порядок выполнения работы
- •Порядок выполнения работы
- •Задания для выполнения
- •Лабораторная работа № 22 функции пользователя
- •Краткие теоретические сведения
- •Тип_результата Имя_функции ([Список_параметров]);
- •Порядок выполнения работы
- •Контрольные вопросы
- •Задания для выполнения
- •Лабораторная работа № 23 рекурсивные функции
- •Краткие теоретические сведения
- •Порядок выполнения работы
- •Контрольные вопросы
- •Задания для выполнения
- •Лабораторная работа № 24 передача одномерного массива в функцию
- •Краткие теоретические сведения
- •Порядок выполнения работы
- •Порядок выполнения работы
- •Задания для выполнения
- •Лабораторная работа № 26 указатель как параметр функции
- •Краткие теоретические сведения
- •Порядок выполнения работы
- •Порядок выполнения работы
- •Порядок выполнения работы
- •Контрольные вопросы
- •Задания для выполнения
- •Лабораторная работа № 29 объединения. Битовые поля. Перечисления
- •Краткие теоретические сведения
- •Порядок выполнения работы
- •Контрольные вопросы
- •Задания для выполнения
- •Варианты 1 – 7 задания по асу
- •Варианты 8 – 15 задания по странам
- •Лабораторная работа № 30 создание файла. Запись и чтение данных
- •Краткие теоретические сведения
- •Порядок выполнения работы
- •Порядок выполнения работы
- •Советы по программированию
- •Порядок выполнения работы
- •Задания для выполнения
Создание двумерного динамического массива
Напомним, что имя двумерного массива – указатель на указатель. В данном случае сначала выделяется память на указатели, расположенные последовательно друг за другом, а затем каждому из них выделяется соответствующий участок памяти под элементы.
. . .
int **m, n1, n2, i, j;
puts(" Введите размеры массива (строк, столбцов): ");
scanf(“%d%d”, &n1, &n2);
// Захват памяти для указателей – А (n1=3)
m = (int**)calloc(n1, sizeof(int*));
for (i=0; i<n1; i++)
// Захват памяти для элементов – B (n2=4)
*(m+i) = (int*)calloc(n2, sizeof(int));
for ( i=0; i<n1; i++)
for ( j=0; j<n2; j++)
m[i] [j] = i+j; // *(*(m+i)+j) = i+j;
. . .
for(i=0; i<n; i++)
free(m[i]); // Освобождение памяти
free(m);
. . .
Порядок выполнения работы
1. Изучить теоретические сведения.
2. Ответить на контрольные вопросы.
3. Выполнить задание.
Контрольные вопросы
1. Что понимают под динамическим выделением памяти и в каких случаях оно используется ?
2. В какой области памяти ЭВМ осуществляется ее динамическое выделение?
3. Каково назначение функций calloc(), malloc() и free()?
4. Опишите порядок выделения динамической памяти под переменную.
5. Что такое динамический массив?
6. Опишите порядок создания динамического массива.
Задания для выполнения
Выполнить задания из лабораторной работы № 17, используя динамическое выделение памяти для массивов.
ЛАБОРАТОРНАЯ РАБОТА № 20
СВЯЗЬ УКАЗАТЕЛЕЙ И МАССИВОВ
Цель работы: приобрести практические навыки использования техники указателей при работе с массивами.
Краткие теоретические сведения
Имя массива трактуется как указатель-константа на массив.
Пусть в программе объявлен массив:
int X[10];
В таком случае X является указателем на нулевой элемент массива в памяти компьютера. В связи с этим истинным является отношение
X= =&X[0]
Отсюда следует, что для доступа к элементам массива кроме индексированных имен можно использовать разадресованные указатели по принципу
имя [индекс] тождественно *(имя + индекс)
Например, для описанного выше массива X взаимозаменяемы следующие обозначения элементов:
X[5] или *( X+5) или *(5+ X)
Поскольку X – указатель на величину целого типа, то X+5 увеличивает значение адреса на 10.
В языке Си символ [ играет роль знака операции сложения адреса массива с индексом элемента массива.
Теперь понятно, почему индекс первого элемента массива всегда равен нулю. Его адрес должен совпадать с адресом массива: X[0]= = *( X+0)
Пример.
const int N = 6;
double arr[N]={23.1, -34, 90.7, 34,-45, 10.8};
double *p;
Направить указатель на массив можно двумя способами:
р = агг;
р = &агг[0];
Обращения к элементу массива arr: arr[i] , *(arr+i) и *(p+i) эквивалентны.
Таким образом, для любых указателей можно использовать две эквивалентные формы выражений для доступа к элементам массива: arr[i] и *(аrr+1). Первая форма удобнее для читаемости текста, вторая - эффективнее по быстродействию программы.
Ввод элементов массива через указатели:
const int N = 6;
double arr[N]={23.1, -34, 90.7, 34,-45, 10.8};
double *p;
int ind; //определение индекса массива
for(ind = 0; ind < N; ind++)
{
//Вывод номера ячейки, куда вводится значение
printf(“[%d]=”,ind);
// ввод значения в ind-й номер ячейки
scanf(“%lf(arr+ind));
}
Обращение через указатели к элементам матрицы
for ( i=0; i<n1; i++)
for ( j=0; j<n2; j++)
*(*(m+i)+j) = i+j;