Создать матрицу переменного размера - PullRequest
0 голосов
/ 10 февраля 2019

Я пытаюсь создать переменную матрицу, используя функцию, которая вводит пустой указатель массива m и выводит указатель массива int m со значениями 1,2,3,4,...n элементов в матрице.Я использую переменную k и увеличиваю значение вверх для достижения этой цели (не уверен, что это лучший способ).

Я получаю subscripted value is not an array, pointer, or vector в моем цикле for здесь matrix[i][j] = k++;, и я не совсем уверен, почему он появляется только внутри цикла for и больше нигде.

Если я ввожу указатель массива int, называемый матрицей, я не должен получить эту ошибку правильно?

int *create_matrix(int* matrix) {
    int i,j;
    int k = 0;

    // 'total' will be 70 = 10 * 7
    int total = sizeof(matrix);

    // 'column' will be 7 = size of first row
    int column = sizeof(matrix[0]);

    // 'row' will be 10 = 70 / 7
    int row = total / column;


    for (i=0; i < row; i++) {
        for (j=0; j < column; j++) {
            matrix[i][j] = k++;
        }
    }
    return matrix;
}

int main(void) {

    // Creating a custom matrix.
    int m[3][4] = {0};
    create_matrix(*m);
    return 0;
}

Ответы [ 3 ]

0 голосов
/ 10 февраля 2019

Делать

int m[3][4] = {0};
create_matrix(*m);

эквивалентно

int m[3][4] = {0};
create_matrix(m[0]);

, поэтому эквивалентно наличию

int m[4] = {0};
create_matrix(m);

// 'total' will be 70 = 10 * 7
int total = sizeof(matrix);

матрицы - это int *, sizeof(matrix) значения 4, если адрес использует 32b и 8, если адрес использует 64b

Эффективный размер матрица в main не имеет значения


// 'column' will be 7 = size of first row
int column = sizeof(matrix[0]);

matrix[0] - это int , поэтому вы получите размер int (4 или 8, вероятно)


matrix[i][j] = k++;

, поскольку matrix является int * форма matrix[i][j] недопустима.

Чтобы назвать ее matrix бесполезно.


Ваша программа может быть:

#include <stdio.h>

void fill_matrix(int matrix[][4], size_t row) {
  size_t i, j;
  int k = 0;

  for (i=0; i < row; i++) {
    for (j=0; j < sizeof(matrix[0])/sizeof(int); j++) {
      matrix[i][j] = k++;
    }
  }
}

int main(void) {

  // Creating a custom matrix.
  int m[3][4] = {0};

  fill_matrix(m, sizeof(m)/sizeof(m[0]));

  size_t i, j;

  for (i=0; i < sizeof(m)/sizeof(m[0]); i++) {
    for (j=0; j < sizeof(m[0])/sizeof(int); j++) {
      printf("matrix[%d][%d] = %d\n", i, j, m[i][j]);
    }
  }


  return 0;
}

Компиляция и выполнение:

pi@raspberrypi:/tmp $ gcc -pedantic -Wextra m.c
pi@raspberrypi:/tmp $ ./a.out
matrix[0][0] = 0
matrix[0][1] = 1
matrix[0][2] = 2
matrix[0][3] = 3
matrix[1][0] = 4
matrix[1][1] = 5
matrix[1][2] = 6
matrix[1][3] = 7
matrix[2][0] = 8
matrix[2][1] = 9
matrix[2][2] = 10
matrix[2][3] = 11

Возможно, это более заметно, если выинициализируйте каждую ячейку матрицы с i*10+j, а не с k++, в этом случае будет напечатано:

matrix[0][0] = 0
matrix[0][1] = 1
matrix[0][2] = 2
matrix[0][3] = 3
matrix[1][0] = 10
matrix[1][1] = 11
matrix[1][2] = 12
matrix[1][3] = 13
matrix[2][0] = 20
matrix[2][1] = 21
matrix[2][2] = 22
matrix[2][3] = 23
0 голосов
/ 10 февраля 2019

Ваша попытка является разумной, но выявляет некоторые неправильные представления о том, как работают объекты в Си.Ничего страшного.Ваш хороший пример обучения, и я верю, что вы будете рады, что сделали это.Теперь попробуйте это:

static const int NO_ROWS    = 3;
static const int NO_COLUMNS = 4;

int *create_matrix(
  int *const matrix, const int no_rows, const int no_columns
) {
    int k = 0;
    for (int i = 0; i < no_rows; i++) {
        for (int j = 0; j < no_columns; j++) {
            matrix[no_columns*i+j] = k++;
        }
    }
    return matrix;
}

int main(void) {
    // Creating a custom matrix.
    int m[NO_ROWS][NO_COLUMNS];
    create_matrix(m[0], NO_ROWS, NO_COLUMNS);
    return 0;
}

Ваша матрица построена как массив массивов.Однако в C массив - это просто область хранения, в которой может храниться последовательность объектов одного типа (в вашем случае int).Символ m интерпретируется компилятором C как

  • , означая адрес начального элемента матрицы или, точнее, потому что ваша матрица представляет собой массив массивов, адрес начального элемента матрицыстрока;и
  • , относящийся к типу начальной строки матрицы, которая сама по себе является типом массива, int[NO_COLUMNS].

Проблема в том, что не существует действительно аккуратного, прямого пути кукажите предварительно скомпилированной функции тип int[NO_COLUMNS], если вы не хотите жестко кодировать тип.Следовательно, одним из относительно простых способов обработки матрицы в create_matrix() будет использование одного линейного массива, как показано на рисунке.

Здесь необходимо понять, что C не понимает форму вашей матрицы.Вместо строк и столбцов C видит линейную область памяти.

Еще один момент, требующий внимания, заключается в том, что функция, в которую передается массив, получает только начальный адрес массива.Если ему нужен размер, он должен быть передан отдельно.

0 голосов
/ 10 февраля 2019

Вам нужно узнать разницу между массивами и указателями.Вы можете указать указатель на матрицу, но информация о размере и количестве измерений будет потеряна, если вы обращаетесь к массиву только через указатель.

Вам нужно будет сделать что-то вроде этого:

int *create_matrix(int* matrix, size_t size_x, size_t size_y) {
   ...
}

int main()
{
    int m[3][6];
    size_t size_y=sizeof m[0]/sizeof m[0][0];
    size_t size_x=sizeof m / sizeof m[0];
    create_matrix(m);
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...