4.加减法
加法:
template <class T>
CMatrix<T> CMatrix<T>::operator+(CMatrix<T>& a)
{
int i, j;
CMatrix<T> t(m, n);
if (m == a.GetM() && n == a.GetN())
{
for (i = 0; i < m; i++)
{
for (j = 0; j < n; j++)
{
t[i][j] = p[i][j] + a[i][j];
}
}
}
return t;
}
函数首先创建一个临时对象,如果*this对象和a对象为同型矩阵则在for循环里用p[i][j]和a[i][j]的和填充t[i][j],否则返回的t将是一个0阵。此函数返回的类型是一个对象,在返回的时候将会调用一次拷贝构造函数。也许你可能学着形参的方式把返回类型改成引用,以为这样会进一步提高效率,那你就犯大错了,一定要注意千万不能返回临时对象的引用。临时对象在函数体外是不存在的,引用它将会出现严重错误。
减法和加法就差一个符号:
template <class T>
CMatrix<T> CMatrix<T>::operator-(CMatrix<T>& a)
{
int i, j;
CMatrix<T> t(m, n);
if (m == a.GetM() && n == a.GetN())
{
for (i = 0; i < m; i++)
{
for (j = 0; j < n; j++)
{
t[i][j] = p[i][j] - a[i][j];
}
}
}
return t;
}
5.乘法
乘法分两种,一种是矩阵与常数相乘,一种是矩阵与矩阵相乘。先看前一种:
template <class T>
CMatrix<T> CMatrix<T>::operator*(double k)
{
int i, j;
CMatrix<T> t(m, n);
for (i = 0; i < m; i++)
{
for (j = 0; j < n; j++)
{
t[i][j] = k * p[i][j];
}
}
return t;
}
为什么形参用double型?因为用int类型,如果有aMatrix * 3.5。那么3.5将会被隐式转换成int型,也就是3,造成了精度损失,所以这里简单的用一个double型的参数。其他就没什么难度了。
矩阵与矩阵相乘:
template <class T>
CMatrix<T> CMatrix<T>::operator*(CMatrix<T>& a)
{
int i, j, k;
CMatrix<T> t(m, a.GetN());
if (n == a.GetM())
{
for (i = 0; i < m; i++)
{
for (j = 0; j < a.GetN(); j ++)
{
for (k = 0; k < n; k++)
{
t[i][j] += p[i][k] * a[k][j];
}
}
}
}
return t;
}
只有一个m1 x n型的矩阵和n x m2型的矩阵才能相乘,并最终得到一个m1 x m2的新矩阵。也就是说左面矩阵的列必须等于右面矩阵的行才能相乘,程序先定义了一个m x a.GetN()大小的0阵,然后用n == a.GetM()判断是否能相乘,相乘则用三层for循环计算结果,否则也返回0阵。
矩阵与矩阵相乘基本上就是这么个算法,只要对矩阵乘法有清晰的认识,理解这段程序也没什么难度。
好了,我们的矩阵类写完了,最终程序清单可以在这里下载,本文可以点这里下载。全文和问题回复发在软组织社区上WWW.RZZ.CN,具体地址为http://bbs.rzz.cn/bbs/dispbbs.asp?boardid=3&star=1&replyid=35481&id=3857&skin=0&page=1虽然文章很长,算代码将近一万字了,不过还是有很多讲的不够的地方。同时程序也有很多不足,比如对算术运算就缺乏出错处理,只是简单的返回0阵。成员函数也有很多应该写的没写,比如逆阵的实现,求行列式等等。不过这些完全可以由大家完成,也希望大家能互相交流。我写这个矩阵类只用了不到两天,而写这篇东西花了整整10天,只是为了起到抛砖引玉的作用,希望所有同学能把自己的所掌握的知识讲给大家听,那样就相等于有很多很多的老师在教课,而且我们之间的交流是真诚的,这种学习效果将会非常明显!累了,不多说了,晚安~~
2005-10-10 23:47 WAKU