ЦЕЛЬ РАБОТЫ: Изучить новые производные типы данных, такие как указатели на стандартные типы данных и массивы. Познакомится с возможными операциями, которые разрешены над указателями. Изучить основные алгоритмы работы с массивами данных.
- Порядок выполнения работы.
1.1. В программе 1 — массив «a» объявить в классе
памяти static;
— изменить длину массива с.
Изучить отличие результатов исходной программы от модифицирован-
ных.
1.2. В программе 2 изменить взаиморасположение объектов
index, dates, a, bills. Проанализировать отличие между результа-
тами исходной программы и модифицированной.
1.3. Повторить п.1.2 с другим (по отношению к п.1.2) взаимо-
расположением указанных объектов.
1.4. Доказать, что имя массива определяет его первый эле-
мент, т.е. если а[], то а==&a[0].
1.5. В программе 3 в строке А0 массив А[] описать с типом
static. Сравнить результаты работы двух версий программы.
1.6. В функции 4А программы 4 вычислить и вывести на экран
— сумму элементов второй строки массива na;
— сумму элементов третьей строки массива ma;
Текст программ
/* Программа 1 */ // Проверка содержимого массива
#include <stdio.h>
main()
{
int c[282];
int b[2], a[2];
printf(» %d %d %d\n»,a[1],b[1],c[1]);
}
/* Программа 2 */ // Указатели и расположение объектов в памяти
#include <stdio.h>
main()
{
int index,dates[4],*pti,a;
float bills[4],*ptf;
for (index=0;index<4;index++)
printf(«Адреса %d значения массивов %u %u\n»,
index,&dates[index],&bills[index]);
pti=dates;
ptf=bills;
for (index=0;index<4;index++)
printf(«Указатель + %d %u %u\n»,
index,pti+index,ptf+index);
printf («Адрес переменной index = %u\n»,&(index));
printf («Адрес переменной a = %u»,&(a));
}
/* Программа 3 */ // Операции с указателями
#include <stdio.h>
#define PR(x) printf(«x= %u,*x= %d,&x= %u\n»,x,*x,&x)
void main(void)
{
int A[]={100,200,300,400}; // строка А0
int *pt1,*pt2;
pt1=A; // строка А1
printf («A= %u\n»,A);
printf («A[0]= %u\n»,A[0]);
printf («A[2]= %u\n»,*(pt1+2)); // строка А2
pt2=&A[2];
printf («pt2= %u\n»,pt2);
printf («&A[0]= %u\n»,&A[0]);
printf («&A[1]= %u\n»,&A[1]);
printf («&A[3]= %u\n»,&A[3]);
printf («&A[4]= %u\n»,&A[4]);
PR(pt1); PR(pt2);
printf(«Адрес А =%u\n»,&A); // строка А3
pt1++; // строка А4
PR(pt1);
++pt2; PR(pt2);
printf(«pt2-pt1 = %u\n»,pt2-pt1); // строка А5
}
/* Программа 4 */ // передача массива в функцию
#include <stdio.h>
static int ma[][4]={
{2,4,6,8},
{100,200,300,400},
{10,40,60,80}
};
void main(void)
{
void prog4A(int *);
static int na[][5]={
{1,3,5,7,9},
{101,201,301,401},
};
prog4A(na);
printf(«Размер массива ма равен %u\n»,sizeof ma);
printf(«Размер массива nа равен %u\n»,sizeof na);
printf(«%d\n»,ma[2][2]); printf(«%d»,ma[2][2]);
}
void prog4A(int *u)
{
printf(«%d\n»,ma[2][2]);
printf(«%d\n»,*u);
printf(«%d\n»,*(u+1));
printf(«%d\n»,u[2]);
printf(«%d\n»,*(u+3));
printf(«%d\n»,*u+4);
printf(«Размер u = %u\n»,sizeof u);
printf(«%d\n»,*(u+8));
}
ИНДИВИДУАЛЬНЫЕ ЗАДАНИЯ.
- Определить максимальный элемент в квадратной матрице
размером 5х5 выше главной диагонали.
- Поменять местами блоки в матрице размером 7х7 следующим
образом: верхний левый квадрант с правым нижним квадрантом; верхний
правый квадрант с левым нижним квадрантом.
- Получить матрицу порядка 7, элементы которой расположены по
спирали от 1 до 49.
- Дана матрица размером mxn. Найти максимальный элемент матрицы
и преобразовать по следующему правилу: строку к с максимальным элементом
сделать столбцом к, а столбец к строкой к.
5.Составить свою функцию сравнения двух строк символов, по-
лучающую в качестве параметров указатели на строки и возвращаю-
щую 1, если строки одинаковы, или 0, если строки различны.
6.Составить свою функцию выделения подстроки, получающую
указатель на строку, номера символов начала и конца подстроки.
7.Составить свою функцию для выделения n правых символов
из подстроки, получающую указатель на строку и число выделяемых
символов.
8.Составить свою функцию для выделения n левых символов из
подстроки, получающую указатель на строку и число выделяемых сим-
волов.
9.Составить свою функцию для поиска подстроки в строке, по-
лучающую указатель на строку и указатель на подстроку. Возвра-
щается указатель на начало найденной подстроки или 0, если под-
строка не найдена.
10.Составить свою функцию для копирования строки. Передает-
ся указатель на строку-источник и указатель на строку-результат.
11.Мистер Браун, человек со странностями, всегда читает
справо налево.Составить функцию, облегчающую диалог с мистером
Брауном, для которой передается указатель на введенную строку и
которая возвращает указатель на строку, обратную к введенной.
Например: ввод «Галина», вывод «анилаГ».
- Задан массив вещественных чисел размерностью 100. Осу-
ществить сортировку массива по возрастанию по любому известному
алгоритму.
- Задана матрица размерностью 5х7. Осуществить поиск наи-
больших элементов в каждом столбце матрицы и записать их в одно-
мерный массив.
- Содержание отчета.
- Результаты работы программы 1 и двух ее модификаций.
- Измененные тексты программы 2 в соответствии с п.1.2 и
п.1.3. Результаты pаботы трех версий пpогpаммы. Нарисовать побай-
тно взаиморасположение объектов во всех трех версиях.
- Нарисовать побайтно взаиморасположение объектов в двух
версиях программы 3.
- Дополнения к тексту программы 4 и полученные суммы.
- Индивидуальное задание.
- Вопросы к защите лабораторной работы.
- Описать работу программы 1.
- Описать работу программы 2.
- Описать работу программы 3.
- Описать работу программы 4.
- Массивы. (Приложение 1).
- Указатели. (Приложение 2).
ПРИЛОЖЕHИЕ 1.
- Массив — последовательно расположенные в памяти элемен-
ты одного типа, обращение к которым осуществляется по индексу.
Многомерные массивы расположены в памяти так, что последний ин-
декс изменяется быстрее всего.
Скалярные переменные можно инициализировать в описании ти-
па (например, int a=1). Массивы в классах памяти extern и static
(auto и register) инициализировать можно (НЕЛЬЗЯ).
Имя массива определяет его первый элемент, т.е. если ma[]
массив, то ma==&ma[0] и обе части равенства определяют АДРЕС пер-
вого элемента массива. Оба обозначения являются КОНСТАНТАМИ типа
указатель, поскольку они не изменяются на протяжении всей прог-
раммы. Однако их можно присваивать (как значения) ПЕРЕМЕННОЙ ти-
па указатель и изменять значение этой переменной.
Операторы описания int pa[]; и int *pa; идентичны по дей-
ствию: оба объявляют pa как указатель.
Текстовые строки являются одномерными массивами типа char и
заканчиваются символом ‘\0’.
ПРИЛОЖЕНИЕ 2.
- Указатель — переменная, хранящая адрес другой перемен-
ной.
int *pi; // объявляет указатель на целое и тогда pi — АДРЕС
объекта типа int (указатель), а
*pi — СОДЕРЖИМОЕ ячеки памяти, адрес которой хранится
в pi (сам объект типа int).
Если pi объявлен как указатель на массив типа
int A[]={10,20,30}, то
pi указывает на A[0] *pi равно 10;
pi+1 указывает на A[1] *(pi+1) равно 20;
pi+2 указывает на A[2] *(pi+2) равно 30.
Результатом унарной операции &<идентификатор> (взятие
адреса) является адрес объекта <идентификатор> в памяти.
- Программа 3 демонстрирует 5 основных операций, которые
можно выполнять над переменными типа указатель:
строка А1 — присваивание значения ;
строка А2 — определение значения *ptr;
строка А3 — получение адреса указателя &ptr;
строка А4 — увеличение показателя ;
строка А5 — разность (двух указателей) (чтобы определить,
на каком расстоянии друг от друга находятся элементы).