这次的任务是将两个txt文件中的矩阵排列的数组读到两个分别的动态数组中,然后将两个矩阵相乘并且将结果存到第三个动态数组中。之所以要记录这次是因为想要把自己遇到的困难和学到的一些函数等记录下来,慢慢积累。还有一个原因也是这次的成功给了自己很多的信心,我相信这会让我以后对编程的恐惧慢慢减弱。
思路:1.打开txt文件读取数据
? ? ? ? ? ?2.将读取到的数据存到动态数组中
? ? ? ? ? ?3.写矩阵相乘的函数,并且在主函数中引用该函数计算两矩阵相乘的结果,最后将结果存? ? ? ? ? ? ? ? ? 到第三个动态数组中
难点:矩阵的行列数的获取、动态数组的创建以及内存的分配、矩阵相乘的算法、二重指针的使? ? ? ? ? ? ? ?用、函数的定义和声明以及引用
值得记录的函数:fscanf(用法还没搞清楚),fgetc(读取txt文件的字符),rewind(使指针回到文件开? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?头),malloc(分配动态数组的内存)
困难的解决
1.由于之前编程太少,所以我几乎就是小白,也不知道怎么去得到矩阵的行列数,上CSDN搜了别人的代码借鉴了别人的思路,然后得以解决。获取列数是依靠矩阵各列之间的空格来分割,当然最后一列之后是换行并不是空格,所以之后直接写了col++,而行数是在获取列数的方法启发下写出来的,以每一行结尾的换行符作为分割,然后最后指针读到结尾判断是否是EOF,然后row++。具体代码如下:
//1.确定矩阵的行数
rowA = 0;
if(fp1) {
while((chA = fgetc(fp1)) != EOF) //以换行或者来判断行数
if(chA == '\n')
rowA++;
rewind(fp1); //读取列数之前使指针回到文件开头
}
rowA++;
//2.确定矩阵的列数
colA = 0;
chA = fgetc(fp1);
while(chA != '\n') //以空格判断矩阵的列数
{
if(chA == ' ')
colA++;
chA = fgetc(fp1);
}
colA++;
引用如下
https://blog.csdn.net/weixin_33724046/article/details/85645110https://blog.csdn.net/weixin_33724046/article/details/85645110
2.在大一学习c++时,在作业中用到的都是静态数组,老师也没有介绍过动态数组,所以刚开始对动态数组是懵的,但是最后去查了之后发现动态数组相比静态数组其实是有优势的,因为它可以用多少内存就分配多少内存,但是静态数组的话,在使用之前需要分配足够大的内存,其实这样是有一点耗费内存的,也不够灵活,但是动态数组最后一定要记得释放内存,否则会有内存泄漏的伪命题,当然由于我这次作业中涉及到的数据比较小,可能在这方面的隐患体现得不是很明显,但是由于专业会涉及到处理卫星影像的情况,这个时候数据量是很大的,所以是需要警惕的。这里主要用到的是malloc函数,还有其他两个函数,但是还没有完全明白,所以先按照别人的代码写了下来,代码如下:
arrayA = (int**)malloc(rowA * sizeof(int*)); //动态数组的初始化
for(int i = 0; i < rowA; i++) {
arrayA[i] = (int*)malloc(colA * sizeof(int));
}
引用如下
https://jiwangreal.blog.csdn.net/article/details/82081845https://jiwangreal.blog.csdn.net/article/details/82081845
3.大一的时候学过线性代数,后来的课程用到矩阵特别多,所以对矩阵的计算还是很熟悉,但是拿笔杆子算和敲代码实现对我而言还是有区别,我可能脑袋里知道他们怎么算,但是用程序语言写就卡壳了,哎,还是写的太少了。不过这次还有一些缺陷,缺少了一些判断,因为矩阵之间相乘是有条件的,需要A矩阵的列数和B矩阵的行数相等,其次还需要C矩阵的行数等于A矩阵的行数,列数等于B矩阵的列数。但是这次没有进行判断,稍显不严谨。代码如下:
void matrix_Multiplication(int rowA, int colA, int colB, int** arrayA, int** arrayB,int** arrayC)
{
int i, j, k;
//int** arrayC;
//arrayC = (int**)malloc(rowA * sizeof(int*));
//for(i = 0; i < rowA; i++) {
// arrayC[i] = (int*)malloc(colB * sizeof(int));
//}
for(i = 0; i < rowA; i++) //对矩阵c进行处理
{
for(j = 0; j < colB; j++) {
int sum = 0;
for(k = 0; k < colA; k++) //矩阵c中每一个元素的循环计算
{
sum += arrayA[i][k] * arrayB[k][j]; //对矩阵c中的某一元素进行计算
}
arrayC[i][j] = sum; //给矩阵c中的某一元素进行赋值
}
}
}
引用如下
https://blog.csdn.net/qq_46724903/article/details/105990859https://blog.csdn.net/qq_46724903/article/details/105990859
https://blog.csdn.net/qq_46724903/article/details/105990859https://blog.csdn.net/qq_46724903/article/details/105990859
4.之前老师说过C语言和C++中灵魂是指针,也是最难的部分,这次我算是感受到了,而且之前没有学到过二重指针,即使是将代码照搬上去也不懂他的操作流程,所以看了很多关于二重指针的介绍。看完我才知道原来之前有一个误区,那就是二重指针和二维数组是不一样的。这点非常清楚的体现在他们的内存分配上,对于二维数组,内存的分配时连续的,它可以像一维数组一样使用,但是在我的理解中,二重指针的内存不是连续的,所以他们之间并不能直接等同,但是一维数组和一重指针是可以等同的。这里还有一些困扰我的我用例子说明。即像下面的*(arrayA+i)+j这样的地址表示方式,这里也有一篇博客对此进行说明
fscanf(f1, "%d", *(arrayA + i) + j);
https://blog.csdn.net/z735640642/article/details/89224090https://blog.csdn.net/z735640642/article/details/892240905.我当初学习c++的时候没搞懂的东西有很多,其中就有函数,我一度将它的定义、声明和调用搞混,所以这次照着网上的例子自己走了一遍流程。我的感受就是写函数最重要的就是搞清楚这个函数的参数和返回值,至于里面的算法其实没有想象的那么复杂。参数的话就要理解形参和实参,还包括他们之间的传递关系,返回值的话就要确定这个函数需不需要返回值,需要返回的结果的类型等,有返回值和没有返回值函数的调用格式和前面的关键字类型是不一样的。代码如下
//函数定义
//空类型所以没有返回值
void matrix_Multiplication(int rowA, int colA, int colB, int** arrayA, int** arrayB,int** arrayC) {
int i, j, k;
for(i = 0; i < rowA; i++) //对矩阵c进行处理
{
for(j = 0; j < colB; j++) {
int sum = 0;
for(k = 0; k < colA; k++) //矩阵c中每一个元素的循环计算
{
sum += arrayA[i][k] * arrayB[k][j]; //对矩阵c中的某一元素进行计算
}
arrayC[i][j] = sum; //给矩阵c中的某一元素进行赋值
}
}
}
//函数声明
void matrix_Multiplication(int rowA, int colA, int colB, int** arrayA, int** arrayB,int** arrayC);
//函数调用
matrix_Multiplication(rowA, colA, colB, arrayA, arrayB,arrayC);
|