c语言学习 第二次

来源:互联网 发布:四大名著 知乎 编辑:程序博客网 时间:2024/05/17 21:53

第二次
掌握指针和结构、文件的结合使用。掌握形参与5实参
首先通过读书,掌握c语言文本文件的基本概念和基本操作。熟悉文本文件的读写及fopen/fclose,fscanf/fprintf等函数。
上机练习1:将几个数字及字符串写入文件。读出并显示。
作业:使用读写文件的矩阵乘法
要求:读出指定文本文件中各矩阵,计算多矩阵相乘后结果,并将结果写入另一文本文件中。
文件名任意;如输入文件:input.txt; 输出文件out.txt
输入文件格式:将多个矩阵记录在文件中,多个矩阵以空行分隔。类似:
1 3 2
2 5 4

3
8
12
(上述文件包括2个矩阵,分别为2*3和3*1的)
(提示:对于多矩阵,可使用结构数组/结构指针)

#define _CRT_SECURE_NO_DEPRECATE#include <stdio.h>#include <stdlib.h>int M;typedef struct Size{    int m;    int n;}SIZE, Mat, *Matp;typedef struct Matrix{    int m;    int n;    int **p;}Matrix,*Matrixp;void ReadSize(Matp p, FILE *fp);                     /*读取矩阵size*/void ReadMatrix(Matrixp p1, Matp psize, FILE *fp);   /*读取矩阵内容*/void MultiMatrix(Matrixp p1, Matrixp p2, Matrixp p3);/*矩阵相乘*/void Assign_Space(Matrixp p1, int m, int n);        /*指针内存分配*/void Free_Space(Matrixp matrix);                    /*指针内存释放*/int main(){    Matrixp matrix1, matrix2, matrix3;    Matp mat;    long int offset;    mat = (Matp)malloc(sizeof(Mat));    matrix1 = (Matrixp)malloc(sizeof(Matrix));    matrix2 = (Matrixp)malloc(sizeof(Matrix));    matrix3 = (Matrixp)malloc(sizeof(Matrix));    FILE *fp, *fp1;    fopen_s(&fp, "D:\\input.txt", "r");    for (int i = 0; !feof(fp); i++)    {        offset = ftell(fp);        ReadSize(mat, fp);        Assign_Space(matrix1, mat->m, mat->n);        fseek(fp, offset, SEEK_SET);        ReadMatrix(matrix1, mat, fp);        if (i == 0)        {            M = mat->m;            Assign_Space(matrix2, mat->m, mat->n);            Assign_Space(matrix3, mat->m, mat->n);            for (int k = 0; k < mat->m; k++)            {                for (int j = 0; j < mat->n; j++)                    matrix2->p[k][j] = matrix1->p[k][j];            }        }        else        {            Assign_Space(matrix3, M, mat->n);            MultiMatrix(matrix1, matrix2, matrix3);            Free_Space(matrix2);            Assign_Space(matrix2, M, mat->n);            for (int k = 0; k < matrix3->m; k++)            {                for (int j = 0; j < matrix3->n; j++)                {                    matrix2->p[k][j] = matrix3->p[k][j];                }            }            Free_Space(matrix1);            Free_Space(matrix3);        }    }    fclose(fp);    fopen_s(&fp1, "D:\\output.txt", "w");   //输出结果到output.txt    for (int k = 0; k < M; k++)    {        for (int j = 0; j < matrix2->n; j++)            fprintf(fp1, "%d ", matrix2->p[k][j]);        fprintf(fp1, "\n");    }    fclose(fp1);    free(mat);    printf("Done!Press Enter to close the window!\n");    getchar();    return 0;}/*读取矩阵的行和列数*/void ReadSize(Matp p, FILE *fp){    int m = 1, n = 1, flag = 0, n1 = 0, m1 = 0;    char ch;    while (!feof(fp))    {        fscanf(fp, "%c", &ch);        if (feof(fp) == 1)            /*读到文末*/        {            p->m = m++;            p->n = n;        }        else if (ch == '\n')          /*未读到文末*/        {            if (flag == 1)            {                flag = 0;                p->m = m1;                p->n = n1;                break;            }            else            {                flag = 1;                m1 = m;                m++;                n1 = n;                n = 1;            }        }        else if (ch == ' ')        {            flag = 0;            n++;        }        else if (ch != ' ')        {            flag = 0;        }    }}void ReadMatrix(Matrixp p1, Matp psize, FILE *fp){    int i, j;    int ch;    char c;    p1->m = psize->m;    p1->n = psize->n;    for (i = 0; i < psize->m; i++)    {        for (j = 0; j < psize->n; j++)        {            fscanf(fp, "%d", &ch);            p1->p[i][j] = ch;        }    }    fscanf(fp, "%c", &ch);    fscanf(fp, "%c", &ch);//有两个回车。。。。}void MultiMatrix(Matrixp p1, Matrixp p2, Matrixp p3){    int i, j, k;        for (i = 0; i < M; i++)        {            for (j = 0; j < p1->n; j++)            {                p3->p[i][j] = 0;                for (k = 0; k < p2->n; k++)                {                    p3->p[i][j] += ((int)p2->p[i][k]) * ((int)p1->p[k][j]);                }            }        }}void Assign_Space(Matrixp p1, int m, int n){    p1->m = m;    p1->n = n;    p1->p =(int **)malloc(sizeof(int *) * m);    for (int i = 0; i < m; i++)    {        p1->p[i] = malloc(sizeof(int) * n);    }}void Free_Space(Matrixp matrix){    for (int i = 0; i < matrix->m; i++)    {        free(*(matrix->p + i));    }    free(matrix->p);}

1.学习了结构体的定义和使用;
2.此题关键点之一是矩阵size的读取,起始思路是利用字符读取size后发现其存在无法区分多位数字的size,思考后利用了空格和回车符以及立flag进行size的读取,注意读取到文末时行数和列数的确定;
3.关键点之二是内存的占用问题,初始思路是读取整体文件后进行乘法计算。在屈老师指导之后更改程序为在计算矩阵乘法的时候每进行一次乘法后及时释放前面一个矩阵申请的内存,以减少不必要的内存占用;
4.读取文件时ftell和fseek来回到读取size前的位置以便读取矩阵内容;
5.初步具备了写程序之前先构思框架结构的思想。