C语言提高-36讲: 二维数组及其指针内容的实践

任务和代码(一):

/*
*All rights reserved
*文件名称:main.c
*作者: Osseyda
完成日期:2017.10.28
*版本号:v2.
*问题描述:矩阵相加
两个矩阵相加,要求其行、列数均相等。运算规则为:一个n行m列的矩阵A加上另一个n行m列的矩阵,得到的结果是一个n行m列的矩阵C,C中的第i行第j列位置上的数等于A和B矩阵第i行第j列上数相加的和。
*/
#include <stdio.h>
#define N 4
#define M 3
int main(){
    int i,j;
    int a[N][M],b[N][M],c[N][M];
    //键盘输入矩阵元素的值
    printf("请输入矩阵a元素的值:\n");
    for(i=0;i<N;i++){
        for(j=0;j<M;j++)
            scanf("%d",&a[i][j]);
    }
    printf("请输入矩阵b元素的值:\n");
    for(i=0;i<N;i++){
        for(j=0;j<M;j++)
            scanf("%d",&b[i][j]);
    }

    //进行加法运算
    printf("相加后的矩阵为:\n");
    for(i=0;i<N;i++){
        for(j=0;j<M;j++){
            c[i][j]=a[i][j]+b[i][j];
            printf("%5d",c[i][j]);
        }
        printf("\n");
    }
    return 0;
}

运行结果:



任务和代码(二):

/*
*All rights reserved
*文件名称:main.c
*作者: Osseyda
完成日期:2017.10.28
*版本号:v2.
*问题描述:矩阵相乘
一个n行m列的矩阵可以乘以一个m行p列的矩阵,得到的结果是一个n行p列的矩阵,其中的第i行第j列位置上的数等于前一个矩阵第i行上的m个数与后一个矩阵第j列上的m个数对应相乘后所有m个乘积的和。
*/
#include <stdio.h>
#define N 2
#define M 3
#define P 4
int main(){
    int i,j,k;
    int a[N][M],b[M][P],c[N][P];
    //键盘输入矩阵元素的值
    printf("请输入矩阵a元素的值:\n");
    for(i=0;i<N;i++){
        for(j=0;j<M;j++)
            scanf("%d",&a[i][j]);
    }
    printf("请输入矩阵b元素的值:\n");
    for(i=0;i<M;i++){
        for(j=0;j<P;j++)
            scanf("%d",&b[i][j]);
    }

    //进行相乘运算
    printf("相乘后的矩阵为:\n");
    for(i=0;i<N;i++){
        for(j=0;j<P;j++){
            c[i][j]=0;
            for(k=0;k<M;k++)
                c[i][j]+=a[i][k]*b[k][j];
            printf("%5d",c[i][j]);
        }
        printf("\n");
    }
    return 0;
}
运行结果:



任务和代码(三):

       定义一个函数来完成对参数数组中元素的求和工作,函数声明如下:

int sum(int array[ ][4],int m,int n);  //该函数完成对array数组中的前m行和n列元素求和 
       在给定主函数的基础上,完成对sum函数的定义。
    #include <stdio.h>
    int sum(int array[ ][4],int m,int n); //该函数完成对array数组中的前m行和n列元素求和
    int main(){
        int a[4][4]= {{1,2,3,4},{5,6,7,8},{9,10,11,12},{13,14,15,16}}; 
        int row,col;
        scanf("%d %d", &row, &col);       //输入行数和列数
        printf("%d\n", sum(a, row, col)); //输出二维数组前row行前col列的元素的和
        return 0;
    }
    int sum(int array[ ][4],int m,int n){
        int i,j;
        int sum=0;
        for(i=0;i<m;i++){
            for(j=0;j<4;j++)
                sum+=array[i][j];         //计算m行之前的所有元素和
        }
        for(j=0;j<=n;j++)
            sum+=array[m][j];             //加上从第m行首元素到第n个元素的和
        return sum;
    }
运行结果:




任务和代码(四):

/*
*All rights reserved
*文件名称:main.c
*作者: Osseyda
完成日期:2017.10.28
*版本号:v2.
*问题描述:某班不超过100名同学。用二维数组score[][4]保存同学们的高数、英语、C语言成绩及总成绩(在此假设学生的学号为整型的连续值,用数组的行下标作学号)。在此基础上,完成下面的操作:
(1)输入学生的实际人数num,在输入各科的成绩时,输入3科成绩后可以自动求出总分,并将数据全保存到数组中;
(2)输出各门课及总分的最高成绩、最低成绩、平均成绩。
*/
#include <stdio.h>
void input(double s[][4],int n);        //输入成绩
void output(double s[][4],int n);       //输出成绩
double max(double s[][4],int n,int i);  //求第i门课的最高成绩,i=3时是总分
double min(double s[][4],int n,int i);  //求第i门课的最低成绩
double avg(double s[][4],int n,int i);  //求第i门课的平均成绩

int main(){
    int i,num;
    double score[100][4];               //设一个班最多100人,实际按输入来
    char course[4][10]= {"高等数学","英语","C++","总分"};
    printf("输入学生人数:");
    scanf("%d", &num);
    input(score,num);                   //(1)输入成绩并求出总分
    output(score,num);                  //(2)输出成绩
    //(3)输出各门课及总分的最高成绩、最低成绩、平均成绩;
    for(i=0; i<4; ++i){
        printf("%s的最高成绩是%.2f, ", course[i], max(score,num,i));
        printf("最低成绩是%.2f, ", min(score,num,i));
        printf("平均成绩是%.2f ", avg(score,num,i));
        printf("\n");
    }
    return 0;
}

void input(double s[][4],int n){
    int i,j;
    for(i=0;i<n;i++){
        for(j=0;j<3;j++)
            scanf("%lf",&s[i][j]);
    }
}

void output(double s[][4],int n){
    int i,j;
    for(i=0;i<n;i++){             //求每一行第四个元素的值(各个学生的总分)
        s[i][3]=0;
        for(j=0;j<3;j++)
            s[i][3]+=s[i][j];
    }
    for(i=0;i<n;i++){             //输出各个学生的成绩每门课成绩及总分
        for(j=0;j<4;j++)
            printf("%.2f\t",s[i][j]);
        printf("\n");
    }
}

double max(double s[][4],int n,int i){
    int k,max=0;
    for(k=0;k<n;k++){             //找出不同行同一列中最大的元素
        if(max<s[k][i])
            max=s[k][i];
    }
    return max;
}

double min(double s[][4],int n,int i){
    int k,min=300;
    for(k=0;k<n;k++){             //找出不同行同一列中最小的元素
        if(min>s[k][i])
            min=s[k][i];
    }
    return min;
}

double avg(double s[][4],int n,int i){
    int k;
    double sum=0;
    for(k=0;k<n;k++)              //求该门课的平均分
        sum+=s[k][i];
    return sum/n;
}
运行结果:




任务和代码(五):

/*
*All rights reserved
*文件名称:main.c
*作者: Osseyda
完成日期:2017.10.28
*版本号:v2.
*问题描述:定义一个8行8列的二维数组a[8][8]。
(1)为二维数组中的数据赋50以内的随机数;
(2)设计函数out()按行输出二维数组中的数据;
(3)设计函数outDiagonal()输出从左上到右下对角线上的元素的值,再输出从右上到左下对角线上的值;
(4)将此数组视为“扫雷”游戏的界面(实际上扫雷游戏的界面一般就用二维数组保存其界面),通过键盘输入一个位置,输出其周围八个格子中的数据,这项功能由函数mine()完成。
(5)设计函数change()改变数组中的值。改变的规则是:从第2行(即a[1]行)开始到最后一行,每一元素是其正上方元素和右上方元素之和。
*/
#include <stdio.h>
#include <time.h>
#include <stdlib.h>
void setdata(int a[8][8]);           //设置随机数
void out(int a[8][8]);               //输出数组
void outDiagonal(int a[8][8]);       //输出对角线元素的值
void mine(int a[8][8],int x, int y); //按“扫雷”游戏的规则输出相邻格子
void change(int a[8][8]);            //按要求改变数值
int main(){
    int a[8][8], x, y;
    setdata(a);
    out(a);
    outDiagonal(a);
    printf("输入一个位置:");
    scanf("%d %d", &x, &y);
    mine(a,x,y);
    change(a);
    printf("元素值改变后的数组:");
    printf("\n");
    out(a);
    return 0;
}
void setdata(int a[8][8]){
    int i,j;
    srand(time(NULL));        //需要用当前时间作“种子”,以便每次运行取得的序列不同
    for(i=0; i<8; i++)
        for(j=0; j<8; j++)
            a[i][j]=rand()%50+1;
    return;
}
//按行序优先输出数组
void out(int a[8][8]){
    int i,j;
    for(i=0;i<8;i++){
        for(j=0;j<8;j++)
            printf("%5d",a[i][j]);
        printf("\n");
    }
}
//输出对角线元素的值(从左上到右下、从右上到左下)
void outDiagonal(int a[8][8]){
    int i;
    printf("左对角线的元素为:");
    for(i=0;i<8;i++)
        printf("%5d",a[i][i]);
    printf("\n");
    printf("左对角线的元素为:");
    for(i=0;i<8;i++)
        printf("%5d",a[i][7-i]);
    printf("\n");
}
//按扫雷游戏规则,输出a[x][y]周围的8个数字
void mine(int a[8][8],int x, int y){
    //输出第x-1行
    if(x-1>=0&&y-1>=0&&y+1<8)
        printf("%d\t%d\t%d",a[x-1][y-1],a[x-1][y],a[x-1][y+1]);
    else if(x-1>=0&&y-1<0&&y+1<8)
        printf("\t%d\t%d",a[x-1][y],a[x-1][y+1]);
    else if(x-1>=0&&y-1>=0&&y+1==8)
        printf("%d\t%d",a[x-1][y-1],a[x-1][y]);
    printf("\n");
    //输出第x行
    if(y-1>=0&&y+1<8)
        printf("%d\t\t%d",a[x][y-1],a[x][y+1]);
    else if(y-1<0&&y+1<8)
        printf("\t\t%d",a[x][y+1]);
    else
        printf("%d",a[x][y-1]);
    printf("\n");
    //输出第x+1行
    if(x+1<8&&y-1>=0&&y+1<8)
        printf("%d\t%d\t%d",a[x+1][y-1],a[x+1][y],a[x+1][y+1]);
    else if(x+1<8&&y-1<0&&y+1<8)
        printf("\t%d\t%d",a[x+1][y],a[x+1][y+1]);
    else if(x+1<8&&y-1>=0&&y+1==8)
        printf("%d\t%d",a[x+1][y-1],a[x+1][y]);
    printf("\n");
}

//按题目中所言规则更改元素的值
void change(int a[8][8]){
    int i,j;
    for(i=1;i<8;i++){
        for(j=0;j<7;j++)    
            a[i][j]=a[i-1][j]+a[i-1][j+1];   
        a[i][7]=a[i-1][7]+a[i-1][0];       //最后一列的元素单独计算
    }
}
运行结果:



知识点总结:

       二维数组作为函数参数的传递;

       任务(四)中,在处理成绩时,运用到了字符型二维数组;

       任务(五)中,为每行每列设置1~50的随机数


心得:

       在二维数组进行传参的时候,没必要硬改成指针,简单明了就行;

       任务(三)中,在完成对array数组中的前m行和n列元素求和  借鉴了利用数组求某日是该年的第几天的思想;

       任务(二)中,有关矩阵乘法 c[i][j]+=a[i][k]*b[k][j]; 这个表达式是根据例子,然后写出通相表达式后描述出来的;

       同样,任务(五)中,通过键盘输入一个位置,输出其周围八个格子中的数据,也是根据写出通相表达式后慢慢描述出来的
       如果仅要求一行输出周围的元素,可以避免用很多个if 语句实现,而用if中的条件将不可以输出的所有元素“屏蔽”掉。

//按扫雷游戏规则,输出a[x][y]周围的8个数字
void mine(int a[8][8],int x,int y){
    int i,j,sum=0;
    printf("a[%d][%d]周围的数是:\n", x, y);
    for (i=x-1;i<=x+1;i++){
        for (j=y-1;j<=y+1;j++){
            if ((i>=0)&&(i<=7)&&(j>=0)&&(j<=7)&&!((i==x)&&(j==y))) 
                printf("%d\t",a[i][j]);
        }
    }
}


 


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值