Как выполнить сглаживание матрицы через указатели? Язык Си

Нужно выполнить сглаживание матрицы через указатели. Подскажите каким способом это реализовать, так как мои попытки приводят к выводу неверных значений или выходу за границы массива.

P.S. Массив должен быть динамическим, в данном коде число 10 взято для проверки.

#include <stdio.h>
#include <time.h>
#include <stdlib.h>
#include <math.h>
#include <locale.h>

double sum(double** pmatrix, int rows, int columns);
void subtraction (double **pmatrix, int rows, int columns);
int main(void) {
    setlocale(LC_ALL, "RU");
    int rows = 10, columns = 10;
    int i, j;
    double matrix[rows][columns];
  double **pmatrix;

    srand(time(NULL));



  pmatrix = (double**)malloc(rows * sizeof(double*));
  for (i = 0; i<rows; i++){
      pmatrix[i] = (double*)malloc(columns * sizeof(double));

  }
//ЗАПОЛНЕНИЕ МАССИВА
    for (i = 0; i < rows; i++) {
        for (j = 0; j < columns; j++) {
            *(*(pmatrix+i)+j) = rand() % 10;
        }
    }

    //ВЫВОД МАССИВА ДЛЯ ПРОСМОТРА
    for (i = 0; i < rows; i++) {
        printf("\n\n");
        for (j = 0; j < columns; j++) {
            printf("%lf\t", *(*(pmatrix+i)+j));

        }
    }
    //СГЛАЖИВАНИЕ МАТРИЦЫ (don't work!)
    for (i = 0; i < rows; i++) {
        for (j = 0; j < columns; j++) {
            if ((i > 0) && (j > 0) && (i < rows-1) && (j < columns - 1)) {
                *(*(pmatrix + i)+j) = (*(*(pmatrix + (i + 1))+j) + *(*(pmatrix + i)+(j +1)) + *(*(pmatrix + (i - 1))+j) + *(*(pmatrix + i)+(j -1 ))) / 4; // внутренний квадрат
            }
            else if ((i == 0) && (j > 0) && (j < columns - 1)) {
                *(*(pmatrix + i)+j) = (*(*(pmatrix + i)+(j -1 )) + *(*(pmatrix + i)+(j + 1)) + *(*(pmatrix + i)+(j + 1))) / 3; // верхний внутренний ряд
            }
      else if ((i == 0) && (j == 0)) {
                *(*(pmatrix + i)+j) = (*(*(pmatrix + i)+(j + 1)) + *(*(pmatrix + i)+(j + 1))) / 2;
            } // левый верхний угол
            else if ((i == 0) && (j == columns - 1)) {
                *(*(pmatrix + i)+j) = (*(*(pmatrix + i)+(j + 1)) + *(*(pmatrix + i)+(j - 1))) / 2;
            } // правый верхний угол
            else if ((j == 0) && (i > 0) && (i < rows-1)) {
                *(*(pmatrix + i)+j) = (*(*(pmatrix + (i - 1))+j) + *(*(pmatrix + i)+(j + 1)) + *(*(pmatrix + i)+(j + 1))) / 3;
            } // левый внутренний ряд
            else if ((i == rows - 1) && (j == 0)) {
                *(*(pmatrix + i)+j) = (*(*(pmatrix + (i - 1))+j) + *(*(pmatrix + i)+(j + 1))) / 2;
            } // левый нижний угол
            else if ((i == rows - 1) && (j == columns - 1)) {
                *(*(pmatrix + i)+j) = (*(*(pmatrix + (i - 1))+j) + *(*(pmatrix + i)+(j - 1))) / 2;
            } // правый нижний угол
            else if ((i == rows - 1) && (j > 0) && (j < columns - 1)) {
                *(*(pmatrix + i)+j) = (*(*(pmatrix + (i - 1))+j) + *(*(pmatrix + i)+(j - 1)) + *(*(pmatrix + i)+(j + 1))) / 3;
            } // нижний внутренний ряд 
      else if ((i < rows - 1) && (i > 0) && (j == columns - 1)) {
                *(*(pmatrix + i)+j) = (*(*(pmatrix + (i - 1))+j) + *(*(pmatrix + i)+(j - 1)) + *(*(pmatrix + (i+ 1))+j)) / 3;
      } // правый внутренний ряд
        }
    }
    printf("\n\t ВЫВОД СГЛАЖЕННОЙ МАТРИЦЫ\n");
    for (i = 0; i < rows; i++) {
        printf("\n\n");
        for (j = 0; j < columns; j++) {
            printf("%lf\t", *(*(pmatrix + i ) + j));

        }
    }
  //ВЫЧИСЛЕНИЕ СУММЫ МОДУЛЕЙ ЭЛЕМЕНТОВ МАТРИЦЫ НИЖЕ ГЛАВНОЙ ДИАГОНАЛИ
  sum(pmatrix, rows,columns);

  //ПОЭЛЕМЕНТНОЕ ВЫЧИТАНИЕ ПОСЛЕДНЕЙ СТРОКИ ИЗ ВСЕХ СТРОК КРОМЕ ПОСЛЕДНЕЙ
  subtraction(pmatrix, rows, columns);



  printf("\n\t ВЫВОД МАТРИЦЫ ПОСЛЕ ВЫЧИТАНИЯ ПОСЛЕДНЕЙ СТРОКИ\n");
    for (i = 0; i < rows; i++) {
        printf("\n\n");
        for (j = 0; j < columns; j++) {
            printf("%lf\t", *(*(pmatrix + i ) + j));

        }
    }
    //ОСВОБОЖДЕНИЕ ПАМЯТИ
    for (i = 0; i < rows; i++)
    {
        free(*(pmatrix+i));
    }
    free(pmatrix);

    return 0;
}


    //ВЫЧИСЛЕНИЕ СУММЫ МОДУЛЕЙ ЭЛЕМЕНТОВ МАТРИЦЫ НИЖЕ ГЛАВНОЙ ДИАГОНАЛИ
  double sum (double **pmatrix, int rows, int columns ){
    double s = 0;
    for (int i = 1; i < rows; i++) {
          for (int j = 0; j < i ; j++) {
        s += fabs(*(*(pmatrix + i)+j));
          }
    }
    printf("\n\n сумма модулей элементов матрицы ниже главной диагонали = %lf\n", s);
  return (s);
  }
    //ПОЭЛЕМЕНТНОЕ ВЫЧИТАНИЕ ПОСЛЕДНЕЙ СТРОКИ ИЗ ВСЕХ СТРОК КРОМЕ ПОСЛЕДНЕЙ
  void subtraction (double **pmatrix, int rows, int columns){ 
    for (int i = 0; i < rows - 1; i++) {
      for (int j = 0; j < columns; j++) {
        *(*(pmatrix + i) + j) = *(*(pmatrix + i) + j) - *(*(pmatrix + rows - 1) + j);
      }
    }
  }```

Ответы (1 шт):

Автор решения: becouse
  1. Выполнение сглаживания по указанному правилу без вспомогательной матрицы очень и очень трудоемкая задача, и все равно без вспомогательных массивов не обойтись, так как нужно хранить предыдущие значения элементов.

  2. Вы совершенно зря выделяете такое количество классов элементов матрицы. Давайте заведем временную переменные, в одну будем сохранять сумму доступных элементов, а в другую их количество. А потом посчитаем среднее арифметическое.

  3. Предлагаю функцию сглаживания

    double** matrix_smooth(double** pmatrix, int rows, int columns) {
    
    double **res;
    double tmp;
    int count;
    res = (double**)malloc(rows * sizeof(double*));
    for (int i = 0; i < rows; i++) {
        res[i] = (double*)malloc(columns * sizeof(double));
    }
    for (int i = 0; i < rows; i++) 
        for (int j = 0; j < columns; j++) {
            count = 0;
            tmp = 0;
            if (i - 1 >= 0) { tmp = tmp + pmatrix[i-1][j]; count++; }
            if (i + 1 < rows) { tmp = tmp + pmatrix[i + 1][j]; count++; }
            if (j - 1 >= 0) { tmp = tmp + pmatrix[i][j-1]; count++; }
            if (j + 1 < columns) { tmp = tmp + pmatrix[i][j+1]; count++; }
            tmp = tmp / count;
            res[i][j] = tmp;
        }
    return res;
    }
    
→ Ссылка