Указатели и массивы в языке С
Задание 5
- Промежуточный размер k примите за 5*Х, где Х – номер компьютера, за которым выполняется лабораторная работа. Предусмотрите корректный вывод результата перемножения двух матриц.
- Вывод результата перемножения выполните на основе операции разыменования.
- Напишите программу умножения матриц с обычной индексацией элементов массивов, т.е. без использования указателей.
- Включите нумерацию строк и столбцов (слева от матрицы и вверху над ней).
- Проверьте работу программы без предварительного обнуления.
Пример 6. Напишите программу формирования трех массивов, состоящих из матриц размерностей 4
8, и заполненных натуральными числами. Заполнение матриц выполнить по строкам последовательно для каждого из массивов. Предусмотрите вывод всех трех массивов на консоль и вывод одного из массивов, номер которого задается пользователем с клавиатуры.
Для решения примера сформируем трехмерный массив размером 3
4
8 с помощью указателя, в котором левый размер будет равен 3, центральный размер равен 4, а крайний правый размер равен 8, например *PTR[3*4*8].
Программный код решения примера:
#include <stdio.h>
#include <conio.h>
#define p 3 // Количество "подшитых" матриц
#define n 4 // Число строк матрицы
#define m 8 // Число столбцов матрицы
int main (void){
int i, j, k, r;
int *PTR[p*n*m], *M2[n*m];
// Заполнение одномерного массива
for (i = 0; i < p*n*m; ++i)
PTR[i] = (int*)(i + 1);
printf("\n An array of dimension %dx%dx%d:\n", p, n, m);
puts("===========================================");
// Разбивка массива
for (k = 0; k < p; ++k){ printf("\n");
for (i = 0; i < n; ++i) { printf(" ");
for (j = 0; j < m; ++j){
printf(" %3d ",PTR[k*n*m + i*m + j]);
}
printf("\n");
}
}
puts("===========================================");
printf("\n Select the number of arrays of a series of numbers (%d...%d): ",1, p);
scanf_s("%d", &r);
printf("\n Matrix number %d from three-dimensional array:\n", r);
// Выбор матрицы из 3-мерного массива
for (k = 0; k < p; ++k)
for (i = 0; i < n; ++i)
for (j = 0; j < m; ++j)
if ( k == (r-1))
{M2[i*m + j] = PTR[k*n*m + i*m + j];}
for (i = 0; i < n; ++i) { printf("\n ");
for (j = 0; j < m; ++j)
printf(" %3d ", M2[i*m + j]);
}
printf("\n\n Press any key: ");
_getch();
return 0;
}Трехмерный массив можно рассматривать как книгу с заданным количеством страниц (размер p = 3 ), размер которых определяется как матрица с заданным числом строк (размер n = 4 ) и с заданным количеством столбцов (размер m = 8 ). Страницы (матрицы) "сшиваются". С помощью указателя *PTR сначала формируется одномерный массив, а затем он разбивается на заданное количество матриц. В функциях puts() допускается перевод на новую строку с помощью символа форматирования \n.
Результат выполнения программы показан на рис. 8.6.
Задание 6
- В программу включите проверку вводимого номера матрицы, т.е. чтобы число r
[1;3]. - В программу введите указатели с многоуровневой адресацией, например ***ptr3, **ptr2. Проверьте работу программы.
- Количество строк матрицы примите n = 2*Х, где Х – номер компьютера, за которым выполняется лабораторная работа.
- Трехмерный массив заполните вещественными числами, равномерно распределенными в интервале [–3*X; 3*X], где Х – номер компьютера, за которым выполняется лабораторная работа.
- С учетом предыдущего пункта определите минимальный и максимальный элементы трехмерного массива. Определите также индексы (k,i,j) этих элементов. Результаты выведите на консоль.
Пример 7.Напишите программу поиска подстроки в строке, сформированной по случайному закону из 15 букв латинского алфавита, с помощью функции strstr(). В качестве подстроки принять первые три буквы своей фамилии.
Для работы с функцией strstr() требуется подключение заголовочного файла string.h.
Программный код решения примера:
#include <stdio.h>
#include <conio.h>
#include <string.h>
#include <stdlib.h>
#include <time.h>
int main (void) {
int i,
k = 0,
n, in;
int numSTR;
int N = 1000;
int numA, numZ;
char str[16];
char sub[4];
char *ptr;
srand((unsigned)time(NULL));
numA = (int)'a';
numZ = (int)'z';
printf("\n Enter the three letters: ");
in = scanf_s("%s", sub, sizeof(sub));
if (in == 0)
{
printf("\n Error input. Press any key: ");
_getch();
exit(1);
}
printf("\n\t substring is \"%s\"\n", sub);
for (n = 0; n < N; n++) {
for (i = 0; i < 15; i++)
str[i] = numA + rand() % (numZ - numA) + 1;
str[i] = '\0';
ptr = strstr(str, sub);
if (ptr != NULL)
{
numSTR = (int)(ptr - str +1);
k++;
break;
}
}
if (k == 0)
printf("\n\t Substring \"%s\" not found", sub);
else
printf("\n\t Substring \"%s\" found at positions %d, %d, %d", \
sub, numSTR, numSTR+1, numSTR+2);
puts("\n");
for (i = 0; i < 15; i++)
printf(" %3d)", i+1);
puts("");
for (i = 0; i < 15; i++)
printf(" %3c ", str[i]);
printf("\n\n ... Press any key: ");
_getch();
return 0;
}Подобный пример рассматривался в предыдущей работе. Видно, что применение указателя и функции strstr() существенно привело к уменьшению программного кода.
Возможный положительный результат работы программы показан на рис. 8.7.
Задание 7
- Объясните процесс вычисления правой части выражения с переменной numSTR.
- Примените вместо операторов цикла for операторы цикла while.
- Подсчитайте количество итераций формирования строки (из 15 символов), когда в ней будет найдена задаваемая подстрока (например, три латинские буквы вашей фамилии).
- Включите допустимо возможное для вашего компилятора количество итераций поиска подстроки в строке.
- Напишите программу имитации взлома пароля, состоящего из трех букв латинского алфавита. Если при трехкратном ручном вводе пароля, он не будет разгадан, то включите автоматический поиск.
Контрольные вопросы
- Как рассматривает имя массива компилятор языка С?
- На какое место в памяти компьютера указывает имя массива?
- Какая связь между указателями и массивами в языке С?
- Как формируется массив указателей в языке С?
- Как следует организовать посимвольное формирование строки символов с помощью указателя?
- Как с помощью одного указателя произвести инициализацию и вывод результата на консоль двухмерного (трехмерного) числового массива?
- Как изменяется значение типизированного указателя при применении к нему операции адресного сложения?
- Как производится вычитание указателей?

