矩阵乘法 - C
Posted
技术标签:
【中文标题】矩阵乘法 - C【英文标题】:Matrix Multiplication - C 【发布时间】:2016-10-14 18:44:08 【问题描述】:我创建了一个执行矩阵加法、减法和乘法的程序。我已经处理了加法和减法部分,但是当我达到乘法时,我无法输出正确的值。下面我只放了乘法函数的代码。
#define _CRT_SECURE_NO_WARNINGS
#include <stdio.h>
#include <stdlib.h>
typedef struct
int *elements;
int rows;
int columns;
matrix;
void main()
matrix a, b, c;
void read_matrix(matrix *);
void deallocate(matrix *);
void print(matrix);
matrix add(matrix, matrix);
matrix subtract(matrix, matrix);
matrix multiply(matrix, matrix);
read_matrix(&a);
read_matrix(&b);
/*
c = add(a, b);
printf("The answer of Matrix (a + b) is \n\n");
print(a);
printf("\n +\n\n");
print(b);
printf("\n =\n\n");
print(c);
printf("\n");
deallocate(&c);
c = subtract(a, b);
printf("The answer of Matrix (a - b) is \n\n");
print(a);
printf("\n -\n\n");
print(b);
printf("\n =\n\n");
print(c);
printf("\n");
deallocate(&c);
*/
c = multiply(a, b);
printf("The answer of Matrix (a * b) is \n\n");
print(a);
printf("\n *\n\n");
print(b);
printf("\n =\n\n");
print(c);
printf("\n");
void read_matrix(matrix *z)
int d1, d2, allc, i, x, y, j, val;
int res;
printf("\nWhat is the first dimension of the array? ");
res = scanf("%d", &d1);
if (res != 1)
fprintf(stderr, "Something went wrong with your first dimension!");
return;
printf("What is the second dimension of the array? ");
res = scanf("%d", &d2);
if (res != 1)
fprintf(stderr, "Something went wrong with your second dimension!");
return;
printf("Matrix Dimension is %dx%d\n", d1, d2);
allc = d1*d2;
(*z).elements = (int *)calloc(allc, sizeof(int));
(*z).rows = d1;
(*z).columns = d2;
x = 0;
j = 0;
printf("\n");
for (i = 0; i < d1; i++)
x++;
for (y = 0; y < d2; y++)
printf("Enter the value for row %d column %d: ", x, y + 1);
res = scanf("%d", &val);
if (res != 1)
fprintf(stderr, "Something went wrong while reading value %d\n", x);
return;
(*z).elements[j++] = val;
void deallocate(matrix *c)
free((*c).elements);
(*c).elements = NULL;
(*c).rows = 0;
(*c).columns = 0;
void print(matrix z)
int i, j, x;
x = 0;
for (i = 0; i < z.rows; i++)
printf("[ ");
for (j = 0; j < z.columns; j++)
printf("%-4d", z.elements[x++]);
printf("]\n");
matrix multiply(matrix a, matrix b)
matrix c;
int a1, a2, b1, b2, allc, i, j, x, y, z, alc, addval, val;
i = 0;
j = 0;
alc = 0;
val = 0;
addval = 0;
a1 = a.rows;
a2 = a.columns;
b1 = b.rows;
b2 = b.columns;
allc = (a1 * b2);
c.elements = (int *)calloc(allc, sizeof(int));
c.columns = a1;
c.rows = b2;
if (a2 != b1)
printf("\n\nThe inner dimensions of your matrices do not match! Multiplication cannot be done!\n\n");
exit(1);
for (x = 0; x < c.rows; x++)
for (y = 0; y < c.rows; y++)
for (z = 0; z < c.rows; z++)
i = (i * c.rows);
addval = (a.elements[j]) * (b.elements[i]);
val += addval;
j++;
i++;
c.elements[alc] = val;
printf("VAL IS: %d\n\n", val);
val = 0;
i = 0;
alc++;
printf("\n\n");
return c;
在乘法函数中,三重嵌套 for 循环应该经过足够多的时间来打印出新数组维度的正确项数。我知道如何进行矩阵乘法,但我不确定我是否在这里正确表示了它。
一个例子的输出是:
What is the first dimension of the array? 3
What is the second dimension of the array? 3
Matrix Dimension is 3x3
Enter the value for row 1 column 1: 1
Enter the value for row 1 column 2: 2
Enter the value for row 1 column 3: 3
Enter the value for row 2 column 1: 4
Enter the value for row 2 column 2: 5
Enter the value for row 2 column 3: 6
Enter the value for row 3 column 1: 7
Enter the value for row 3 column 2: 8
Enter the value for row 3 column 3: 9
What is the first dimension of the array? 3
What is the second dimension of the array? 3
Matrix Dimension is 3x3
Enter the value for row 1 column 1: 1
Enter the value for row 1 column 2: 2
Enter the value for row 1 column 3: 3
Enter the value for row 2 column 1: 4
Enter the value for row 2 column 2: 5
Enter the value for row 2 column 3: 6
Enter the value for row 3 column 1: 7
Enter the value for row 3 column 2: 8
Enter the value for row 3 column 3: 9
The answer of Matrix (a * b) is
[ 1 2 3 ]
[ 4 5 6 ]
[ 7 8 9 ]
*
[ 1 2 3 ]
[ 4 5 6 ]
[ 7 8 9 ]
=
[ 216847534336951265054271]
[ 1641572693-138635672036124672]
[ 1352368309-50514195286739134]
Press any key to continue . . .
【问题讨论】:
x、y 和 z 都在计算行数。我希望其中至少有一个应该是计数列。并且i
乘以c.rows
,然后在每次通过循环时递增。使用printf
打印i
的值,你会发现它根本不是你想要的。
题外话:在print
函数中,我会将"%-4d"
更改为"%-3d "
。当一些数字超过三位数时,这将防止数字聚集在一起。
【参考方案1】:
以下是我对您进行矩阵乘法的代码的修改。问题出在您的 multiply()
函数上。您可以看到它注定要通过增加变量j
来遍历a
矩阵 - 在一个工作解决方案中,矩阵a
的每个元素都会多次参与乘法。
我还将您的例程更改为所有传递指向矩阵结构的指针,而不是直接按值传递指针和传递/返回矩阵结构的混合。我认为这更加一致且更易于遵循,但这意味着如果您保持这种方式,您将需要更改其他矩阵数学例程以使其工作相同。
#include <stdio.h>
#include <stdlib.h>
typedef struct
int *elements;
int rows;
int columns;
matrix;
void read_matrix(matrix *z)
int d1, d2, val;
printf("\nWhat is the first dimension of the array? ");
int result = scanf("%d", &d1);
if (result != 1)
fprintf(stderr, "Something went wrong with your first dimension!\n");
exit(1);
printf("What is the second dimension of the array? ");
result = scanf("%d", &d2);
if (result != 1)
fprintf(stderr, "Something went wrong with your second dimension!\n");
exit(1);
printf("Matrix Dimension is %dx%d\n", d1, d2);
z->elements = calloc(d1 * d2, sizeof(int));
z->rows = d1;
z->columns = d2;
int x = 0;
int j = 0;
printf("\n");
for (int i = 0; i < d1; i++)
x++;
for (int y = 0; y < d2; y++)
printf("Enter the value for row %d column %d: ", x, y + 1);
result = scanf("%d", &val);
if (result != 1)
fprintf(stderr, "Something went wrong while reading value (%d, %d)\n", x, y + 1);
exit(1);
z->elements[j++] = val;
void deallocate(matrix *c)
free(c->elements);
c->elements = NULL;
c->rows = 0;
c->columns = 0;
void print(matrix *z)
int x = 0;
for (int i = 0; i < z->rows; i++)
printf("[ ");
for (int j = 0; j < z->columns; j++)
printf("%-4d", z->elements[x++]);
printf("]\n");
void multiply(matrix *a, matrix *b, matrix *c)
if (a->columns != b->rows)
fprintf(stderr, "The inner dimensions of your matrices do not match! Multiplication cannot be done!\n");
exit(1);
c->elements = calloc(a->rows * b->columns, sizeof(int));
c->columns = b->columns;
c->rows = a->rows;
int alc = 0;
for (int x = 0; x < a->rows; x++)
for (int y = 0; y < b->columns; y++)
int value = 0;
for (int z = 0; z < b->rows; z++)
value += a->elements[z + x * a->columns] * b->elements[y + z * b->columns];
c->elements[alc++] = value;
int main()
matrix a, b, c;
read_matrix(&a);
read_matrix(&b);
multiply(&a, &b, &c);
printf("The answer of Matrix (a * b) is \n\n");
print(&a);
printf("\n *\n\n");
print(&b);
printf("\n =\n\n");
print(&c);
printf("\n");
deallocate(&a);
deallocate(&b);
deallocate(&c);
return 0;
【讨论】:
对像这样的半透明(仅由函数调用访问)结构的另一个合理解决方案是将typedef
结构作为结构的大小为 1 的数组的名称。 GMP 使用mpz_t
完成此操作,因此您可以使用(大部分)无缝隐式逐指针传递语义来传递它们,避免显式接受指针和传递指针的需要,同时仍然使基本结构的堆栈分配变得简单。
感谢您的回答!所有的功能和他们的合作伙伴都按照我的教授对实验室的要求。如果我可以改变,那么我也会改变。谢谢你的回答!
@T.Gon 有不同的机制来表达对帖子的感谢。如果您认为帖子(问题也需要投票)有用(有帮助?启发性?),upvote it(10 次代表)。如果某个答案解决了您的问题(或对找到解决方案最有帮助),接受它(15 次代表)。如果您认为某个问题的最佳答案值得加分,请发起赏金活动(将声誉从您的帐户转移,也可能转移到其他人的帐户)。以上是关于矩阵乘法 - C的主要内容,如果未能解决你的问题,请参考以下文章