《C 和 指针》 第8章 编程 题 第 5 题 ,矩阵相乘 ,参考答案疑似有误

题目是大概如下:

后来去看了一下书里的参考答案,感觉有点不大对(但是没有验证过)。原型给的好像就不大对,这个原型:

void matrix_multiply(int *m1, int *m2, int *r, int x, int y, int z);

一般如果在参数里面是指针数组的话,需要指明这个指针指向的数组的大小,例如int(*m1)[10] ,所以对于题目给出的原型比较疑惑,而参考答案也没有那样做。参考答案也和题目本身的原型不一样,把int *r改成了register类型。所以我感觉把原型改了,只要出来的结果一样,也算解答对了。当然效率问题以后再说(等学完汇编)

因为可变参数,需要先声明数组大小的int(根据刚学的《C Primer Plus》,所以我给出的原型:

void matrix_mutiplay(int x, int y, int z, int (*m1)[y], int (*m2)[z], int (*r)[z]);

矩阵相乘以前是学过,现在差不多都忘光了。好在根据题目,大概能猜出意思。

看一个3X2的矩阵 与一个 2X 4 的矩阵相乘 ,这里前一个矩阵的列要和 后一个矩阵的行相等,不然就不配了, 就会生成一个3X4的矩阵。 然后这个3X4的矩阵地每个元素, 就是对应元素相乘后的和,例如(00,01的前一个矩阵,和00,10的后一个矩阵相配,然后后一个矩阵的00位置上的数等于 00*00 + 01 * 10 ).

根据生成矩阵的结果,来一个3X4的两层循环,然后考虑每个元素是怎么得来的。

void matrix_mutiplay(int x, int y, int z, int (*m1)[y], int (*m2)[z], int (*r)[z]){
	int i,j, k;
	for(i = 0 ; i < x ; i++){
		for(j = 0 ; j < z ; j++){
			for(k = 0 ;k < y ; k++){
				*(*(r + i)+ j ) += (*(*(m1+i)+ k))* (*(*(m2 + k) + j));
			}
		}
	}
}

最内层循环就是当i=0,j=0(对应 r矩阵 0,0位置), 当k=0,就是 00*00 ,当k =1 ,就是 01* 10 (因为y = 2)

初始化 m1,m2 后测试

#include <stdio.h>

void matrix_mutiplay(int x, int y, int z, int (*m1)[y], int (*m2)[z], int (*r)[z]);

int main(int argc, const char *argv[])
{
	int m1[3][2] = {
			{2, -6},
			{3, 5},
			{1, -1}
	};
	int m2[2][4] = {
		{4,-2,-4,-5},
		{-7,-3,6,7}
	};
	int r[3][4] = {
		{0},
		{0},
		{0}
	};
	matrix_mutiplay(3, 2, 4, m1, m2, r);
	int i ,j;
	for(i = 0 ;  i < 3; i++){
		for(j = 0 ;j < 4; j++){
			printf("%d ", *(*(r + i)+j));
		}
		puts("");
	}
	return 0;
}

void matrix_mutiplay(int x, int y, int z, int (*m1)[y], int (*m2)[z], int (*r)[z]){
	int i,j, k;
	for(i = 0 ; i < x ; i++){
		for(j = 0 ; j < z ; j++){
			for(k = 0 ;k < y ; k++){
				*(*(r + i)+ j ) += (*(*(m1+i)+ k))* (*(*(m2 + k) + j));
			}
		}
	}
}

 得到的结果和书中的一样:

50 14 -44 -52 
-23 -21 18 20 
11 1 -10 -12 

顺便说一下编译过程中出现错误

/usr/bin/ld: /usr/lib/gcc/i686-linux-gnu/4.8/../../../i386-linux-gnu/crti.o: unrecognized relocation (0x2b) in section `.init'
/usr/bin/ld: final link failed: Bad value
collect2: error: ld returned 1 exit status

看意思是链接过程出现错误,根据网上的建议升级了一下gnu的版本。

sudo apt-get install binutils,然后就解决了。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值