Обращение к матрице с помощью указателей C++
Вот матрица, заданная и обращаемая с помощью индексов, нужно чтоб индексов не было, только указатели. Если кратко, то вводится матрица, производится сдвиг на 1 строку вверх (1 строка стаёт последней) и в новосформированной матрице ищется строка, в которой произведение элементов наименьшее. В общем, нужно сделать её с помощью указателей.
#define _CRT_SECURE_NO_WARNINGS
#include <stdio.h>
#include <stdlib.h>
int main() {
system("chcp 1251");
const int n = 4, m = 3;
int i, j, ind = 0, p = 1, P = 0;
float matrix[n][m], matrix_2[n][m];
puts(" Задайте матрицу");
for (i = 0; i < n; i++) {
for (j = 0; j < m; j++) {
scanf("%f", &matrix[i][j]);
}
puts("");
}
puts("");
puts("\tЗаданная матрица");
for (i = 0; i < n; i++) {
for (j = 0; j < m; j++) {
printf("%8.2f", matrix[i][j]);
}
puts("");
}
puts("");
for (j = 0; j < m; j++) {
for (i = n - 1; i >= 0; i--) {
if (i == 0)
matrix_2[n - 1][j] = matrix[i][j];
else
matrix_2[i - 1][j] = matrix[i][j];
}
}
puts("\tСформированная матрица");
for (i = 0; i < n; i++) {
for (j = 0; j < m; j++) {
printf("%8.2f", matrix_2[i][j]);
}
puts("");
}
puts("");
for (i = 0; i < n; i++) {
for (j = 0; j < m; j++) {
p *= matrix_2[i][j];
}
if (i == 0)
P = p;
else {
if (p < P) {
ind = i;
P = p;
}
}
p = 1;
}
printf("Номер строки, произведение елементов которой наименьшее - %d\n", ind + 1);
return 0;
}
Ответы (2 шт):
Если у вас например двумерная матрица определённая как int a[N][M]; либо через int * a = (int*)malloc(N * M * sizeof(int)); то вместо индексации int x = a[i][j]; можно делать тот же доступ но указателями через int x = *((int*)a + i * M + j);.
Ниже весь ваш код только с заменой всей индексации на указательную.
Для удобства я это индексирование через указатели реализовал у себя в коде ниже через AT(...) макрос, увидите как его использовать по коду. Если согласно поставленной задаче нужно именно оставить в виде указателей, то просто замените использование float x = AT(a, float, m, i, j); на выражения вида float x = *((float*)a + i * m + j);.
Конечно раз это С++, то я бы мог написать вместо AT удобную шаблонную inline функцию. Но раз у вас задача перейти от индексации к указателям, т.е. чисто низкоуровневый Си подход, то думаю вам шаблонные функции и другие фишки С++ точно не нужны.
Код ниже использует AT, но я сделал по этой ссылке вариант кода полностью без AT, чисто указатели как вы просили.
#define _CRT_SECURE_NO_WARNINGS
#include <stdio.h>
#include <stdlib.h>
#define AT(a, t, cols, i, j) (*(((t*)a) + (i) * (cols) + (j)))
int main() {
system("chcp 1251");
const int n = 4, m = 3;
int i, j, ind = 0, p = 1, P = 0;
float matrix[n][m], matrix_2[n][m];
puts(" Задайте матрицу");
for (i = 0; i < n; i++) {
for (j = 0; j < m; j++) {
scanf("%f", &AT(matrix, float, m, i, j));
}
puts("");
}
puts("");
puts("\tЗаданная матрица");
for (i = 0; i < n; i++) {
for (j = 0; j < m; j++) {
printf("%8.2f", AT(matrix, float, m, i, j));
}
puts("");
}
puts("");
for (j = 0; j < m; j++) {
for (i = n - 1; i >= 0; i--) {
if (i == 0)
AT(matrix_2, float, m, n - 1, j) = AT(matrix, float, m, i, j);
else
AT(matrix_2, float, m, i - 1, j) = AT(matrix, float, m, i, j);
}
}
puts("\tСформированная матрица");
for (i = 0; i < n; i++) {
for (j = 0; j < m; j++) {
printf("%8.2f", AT(matrix_2, float, m, i, j));
}
puts("");
}
puts("");
for (i = 0; i < n; i++) {
for (j = 0; j < m; j++) {
p *= AT(matrix_2, float, m, i, j);
}
if (i == 0)
P = p;
else {
if (p < P) {
ind = i;
P = p;
}
}
p = 1;
}
printf("Номер строки, произведение елементов которой наименьшее - %d\n", ind + 1);
return 0;
}
Вход:
Задайте матрицу
4 5 6
1 2 3
7 8 9
10 11 12
Выход:
Заданная матрица
4.00 5.00 6.00
1.00 2.00 3.00
7.00 8.00 9.00
10.00 11.00 12.00
Сформированная матрица
1.00 2.00 3.00
7.00 8.00 9.00
10.00 11.00 12.00
4.00 5.00 6.00
Номер строки, произведение елементов которой наименьшее - 1
Когда звездочки нравятся больше, чем скобочки, или вариант с двойным указателем:
#include <iostream>
#include <iomanip>
#include <limits>
#define ROWS 4
#define COLS 3
using namespace std;
void shift(float** matrix, int rows)
{
float* row = *matrix;
for (int i = 0; i < rows - 1; i++)
*(matrix+i) = *(matrix + i + 1);
*(matrix + rows - 1) = row;
}
void print(float** matrix, int rows, int cols)
{
for (int i = 0; i < rows; i++)
{
for (int j = 0; j < cols; j++)
cout << fixed << setprecision(3) << setw(10) << *(*(matrix + i)+j) << " ";
cout << endl;
}
}
void input(float** matrix, int rows, int cols)
{
for (int i = 0; i < rows; i++)
for (int j = 0; j < cols; j++)
cin >> *(*(matrix + i) + j);
}
int leastMulti(float** matrix, int rows, int cols)
{
int idx = 0;
float min = numeric_limits<float>::max(), multi;
for (int i = 0; i < rows; i++)
{
multi = 1;
for (int j = 0; j < cols; j++)
multi *= *(*(matrix + i) + j);
if (multi < min)
{
min = multi;
idx = i;
}
}
return idx;
}
int main()
{
setlocale(LC_ALL, "Russian");
float** matrix = new float* [ROWS];
for (int i = 0; i < ROWS; i++)
*(matrix + i) = new float[COLS];
input(matrix, ROWS, COLS);
shift(matrix, ROWS);
print(matrix, ROWS, COLS);
cout << "Номер строки с наименьшим произведением: " << leastMulti(matrix, ROWS, COLS) + 1;
return 0;
}
Стоит отметить, что обращение *(*(matrix + i) + j) - не обязательное, а лишь навеяно неполным вопросом автора. К float ** типу можно все также обращаться и с помощью matrix[i][j].
Преимущество, кстати, такого подхода в том, что вы можете не использовать дополнительный массив для сдвига, а двигать строки прямо внутри имеющейся матрицы, меняя местами указатели на первый элемент строки, что занимает и меньше памяти, и меньше операций (см. метод shift).