void alloc_matrix(int ***mat,int *n,int *m)
В этой строке есть две проблемы. Ни один из них не смертелен, но оба они заслуживают исправления.
Первая проблема: матрица в этой программе представлена как int**
. Почему alloc_matrix
принять int***
? Все стандартные функции, которые выделяют что-то (malloc и friends), возвращают указатель на что-то. Это идиоматический способ делать вещи на C. Это уменьшает количество ваших звезд (будучи трехзвездным программистом на C, не является достижением, которым можно гордиться) и упрощает код. Функция должна быть изменена на
int** alloc_matrix(// but what's inside the() ?
второй проблема, почему функция называется alloc_matrix
подсказки пользователя и читать значение? Эти вещи не связаны с распределением. Функция должна делать одно и делать это хорошо. malloc
предлагает ввести размер? fopen
предлагает ввести имя файла? Эти вещи считались бы абсурдом первой степени, и это справедливо. Рекомендуется, чтобы читал размеры в другом месте и передал их alloc_matrix
в качестве входных аргументов.Следовательно,
int** alloc_matrix(int n, int m) { // but what's inside the {}?
Что остается alloc_matrix
прост:
int** alloc_matrix(int n, int m) {
int** mat; // that's what we will return
int i;
mat = (int**)calloc(n, sizeof(int*));
for(i = 0; i < n; i++)
// here comes the important part.
Поскольку мы упростили alloc_matrix
и уменьшили количество звезд в mat
, что мы должны делать со старым телом цикла? Это было:
*(mat+i) = (int*)calloc(...);
, но если убрать звезду, он становится
(mat+i) = (int*)calloc(...);
, который является очевидной ерундой. Возможно, старая линия была проблемой. Тот факт, что он вызвал предупреждение о компиляторе, конечно, не говорит о его правильности. Итак, как исправить это? Вариантов не так уж много. Оказывается, что для восстановления здравомыслия, мы должны оставить старую левую сторону (написанную для трехзвездочного mat
) нетронутой. Или, еще лучше, использовать эквивалентное, но более идиоматическое обозначение:
mat[i] = (int*)calloc(m, sizeof(int));
Так вся функция теперь становится
int** alloc_matrix(int n, int m) {
int **mat;
int i;
mat = (int**)calloc(n, sizeof(int*));
for(i = 0; i < n; i++)
mat[i] = (int*)calloc(m, sizeof(int));
return mat;
}
и он должен называться как
mat = alloc_matrix(n, m);
Он часто говорил, что не следует делать результат calloc
и друзьями. Но в этом случае бросок активировал предупреждение, которое помогло найти ошибку. Сейчас я оставляю броски на месте.
Нет двухмерного массива, а также указатель на один или что-то, что может его представлять! И быть 3-звездочным программистом C не является комплиментом. – Olaf
Если это был ваш код: пожалуйста, не исправьте его ошибки в вопросе. Если это не так, отправьте весь вопрос с помощью * фактического * кода. –
'alloc_matrix (& mat, int & n, int &m);' this is not legal C. Какой компилятор вы используете? –