#c #matrix
#c #матрица
Вопрос:
Это небольшая программа, которую я написал, чтобы добавить 2 квадратные матрицы.
Когда я ввожу вторую матрицу, значения первой изменяются, и результат впоследствии становится ложным. Это довольно хорошо работает для матриц 2×2, но не для матриц большего размера. Алгоритм хорошо работает без использования функций. Пожалуйста, помогите мне решить эту проблему.
Вот код:
#include <stdio.h>
#include <stdlib.h>
int n;
void PrintMatrix(int P[n][n])
{
int i,j;
for(i=0;i<n;i )
{
printf("n");
for(j=0;j<n;j )
{
printf("%dt", P[i][j]);
}
}printf("n");
}
void ReadMatrix(int P[n][n])
{
int i,j;
for(i=0;i<n;i )
{
printf("input row %dn", i 1);
for(j=0;j<n;j )
{
scanf("%d", amp;P[i][j]);
}
}
}
void AddMatrix(int P[n][n], int Q[n][n], int Result[n][n])
{
int i,j;
for(i=0;i<n;i )
{
for(j=0;j<n;j )
{
Result[i][j]=P[i][j] Q[i][j];
}
}
}
int main()
{
int i,j;
int A[n][n];
int B[n][n];
int Sum[n][n];
printf("input matrix size:");
scanf("%d", amp;n);
printf("input first matrixn");
ReadMatrix(A);
PrintMatrix(A);
printf("input second matrixn");
ReadMatrix(B);
PrintMatrix(B);
AddMatrix(A,B,Sum);
PrintMatrix(Sum);
return 0;
}
Комментарии:
1. C должен знать ширину матрицы во время компиляции, это не может быть переменной.
2. @Barmar За исключением того, что ему не нужно знать ширину во время компиляции, это может быть переменная. VLA, добро пожаловать в 1999 год 🙂 Но, конечно, есть много случаев, когда VLAS не подходят.
3. @Lundin Хорошо, но ему нужно объявить переменные матрицы после чтения
n
, не так ли?4. @Barmar Да, действительно, объявление массива должно быть справа от переменных измерения, смотрите Мой ответ ниже.
5. Я знал о VLA, но думал, что это применимо только к первому измерению.
Ответ №1:
Вы можете определить свой собственный тип матрицы с помощью структуры, такой как, например:
typedef struct
{
int* data;
size_t width;
size_t height
} matrix_t;
Или, если у вас есть современный компилятор C, вы можете написать такие функции, как
void func (size_t width, size_t height, int matrix[width][height])
Но, вероятно, предпочтительнее версия struct.
Редактировать
Что касается того, почему ваша программа глючит, вы должны инициализировать n
значением. Если вы объявите массивы как массивы переменной длины размером [n][n] после момента, когда вы читаете n
от пользователя, все должно работать нормально.
Комментарии:
1.
int matrix[width][height]
—width
иheight
должно быть постоянным или нет? современный стандарт C позволяет использовать массив переменной длины в качестве функционального параметра?2. @ikh Им не обязательно быть постоянными, в современном C есть концепция массивов переменной длины.
3. C99 принимает массив переменной длины в качестве параметра функции, при условии, что параметры длины предшествуют самому массиву. В GNU C специально есть расширение синтаксиса, которое допускает пересылку параметров, например:
void func (size_t width; size_t height; int matrix[width][height], size_t width, size_t height) {...}
; в данном случаеwidth
иheight
являются формальными параметрами, которые должны передаваться ПОСЛЕmatrix
и просто объявляются заранее.4. Это все еще не работает. проблема по-прежнему остается той же. Когда я считываю значения второй матрицы, значения первой изменяются. и я понятия не имею, почему это так.
5. @Gladson Ах, оказывается, это была просто тривиальная ошибка. Смотрите мой обновленный ответ.
Ответ №2:
если вы запустите это под gdb, вот что вы найдете (gdb) p A $ 14 = 0x7fffffffdfb0 (gdb) p B $ 15 = 0x7fffffffdfa0
независимо от того, какое «n» вы выберете, базовый адрес массива всегда отличается на 16, то есть работает целочисленная матрица 2 x 2
но если я введу длину как 3, программа вылетит. Происходит повреждение памяти. перед выполнением ввода (gdb) x / 12 A 0x7fffffffdfb0: 0 0 -255260739 52 0x7fffffffdfc0: -1 -1 -1 0x7fffffffdfd0: -8272 32767 -1 -1
после ввода: x / 12 0x7fffffffdfb0 0x7fffffffdfb0: 1 2 3 4 0x7fffffffdfc0: 5 6 7 8 0x7fffffffdfd0: 9 32767 -1 -1 нормально, поскольку я дал значения 1 2 3 4 5 6 7 8 9
но p A $ 16 = 0x7fff00000009 является ли этот доступ к нему причиной ошибки сегментации в PrintMatrix.
теперь, если вы измените свою программу на это
int main()
{
int i,j;
printf("input matrix size:");
scanf("%d", amp;n);
int A[n][n];
int B[n][n];
int Sum[n][n];
ваши проблемы решены, и вы можете идти
Комментарии:
1. Спасибо за помощь. По крайней мере, это хорошее объяснение ошибки. должен признать, я многого из этого не понял. Я все еще новичок. 🙂