头歌链表实训4

第4关:创建M×N的二维动态数组,存放输入的M×N个整数,然后求这M×N个数中的最大值


任务描述

本关任务:创建M×N的二维动态数组,存放输入的M×N个整数,然后求这M×N个数中的最大值。

相关知识

C 语言有三种方法创建二维动态数组:

  • 利用一个二级指针来实现
  • 利用数组指针来实现
  • 利用一维数组来模拟二维数组

利用一个二级指针来实现创建二维动态数组

实际上,C 语言中没有二维数组,至少对二维数组没有直接的支持,取而代之的是“数组的数组”,二维数组可以看成是由指向数组的指针构成的数组。基于这个原理,可以通过分配一个指针数组,再对指针数组的每一个元素分配空间,实现动态分配二维数组。    现在有指针p定义如下:int **p;,因为p是指针的指针,需要两次内存分配才能使用其最终内容。

  1. p = ( int ** ) malloc ( M * sizeof( int *) ); //动态分配M个类型为int*的内存空间

p指向长度为M的指针数组,再为指针数组的M个数组元素分配内存单元,即:

  1. for(i=0; i<M; i++)
  2. {
  3. p[i]=(int *)malloc( N *sizeof ( int ) ); //动态分配长度为N的int数组
  4. }

p[i]中存放的是长度为N的一个int型数组的首地址,即p[i]的值是指针,这时才可以使用下标用法p[i][j]存放一个int型数据。    这样分配的二维数组同一行中元素地址是连续的,不同行中元素地址不一定是连续的。    如果没有第一次内存分配,p是个野指针,是不能使用的;如果没有第二次内存分配,则p[0]p[1]等也是个野指针,也是不能用的。申请了内存空间后,M×N的二维动态数组p的输入输出和普通静态的二维数组一样:

 
  1. for(i=0; i<M; i++)
  2. for(j=0; j<N; j++)
  3. scanf("%d", &p[i][j] )
  4. for(i=0; i<M; i++)
  5. for(j=0; j<N; j++)
  6. printf("%d ",p[i][j] )

最后在使用结束后,要将申请的内存资源全部释放:

  1. for(i=0; i<M; i++)
  2. {
  3. free(p[i]); //首先释放M行的N个类型为int的内存空间
  4. }
  5. free(p); //释放长度为M类型为int*的内存空间

利用数组指针来实现创建二维动态数组

数组指针和指针数组是不同的。数组指针是指针变量,其本质仍然是一个变量。指针数组其本质是一个数组,存放的元素类型是指针类型。

例如,申请一个3×4的二维动态数组:

  1. int(*p)[4];
  2. p = (int(*)[4]) malloc( 3 * sizeof(int (*)[4]) ); //申请一个3行4列的二维动态数组
  3. for (int i = 0; i < 3; ++i)
  4. {
  5. for (int j = 0; j < 4; ++j)
  6. {
  7. scanf("%d", &p[i][j] ) //输入数组每个元素
  8. }
  9. }
  10. for (int i = 0; i < 3; ++i)
  11. {
  12. for (int j = 0; j < 4; ++j)
  13. {
  14. printf("%d ", p[i][j]); //输出数组每个元素
  15. }
  16. }
  17. free(p); //释放所有空间

利用数组指针来实现申请二维动态数组,只需申请一次地址空间,并且数组元素的地址始终是连续的,一次可以释放所有的地址空间。

利用一维数组来模拟二维数组

例如,定义一个长度为了12的一维数组来模拟3×4的二维动态数组:

  1. int *p;
  2. p = (int *)malloc(sizeof(int) * 3 * 4);
  3. for (int i = 0; i < 3 ++i)
  4. {
  5. for (int j = 0; j < 4; ++j)
  6. {
  7. scanf("%d", &p[i*4+j]); //此处& p[i*4+j]不可以写成&p [i][j]
  8. }
  9. }
  10. for (int i = 0; i < 3 ++i)
  11. {
  12. for (int j = 0; j < 4; ++j)
  13. {
  14. printf("%d ",p[i*4+j]); //此处p[i*4+j]不可以写成p [i][j]
  15. }
  16. }

p是一个一级指针,只能接收二维数组的元素的首地址,系统只能靠整数34 来划分二维数组的行数和列数。

编程要求

根据提示,在右侧编辑器 Begin-End 区间补充代码,创建M×N的二维动态数组,存放输入的M×N个整数,然后求这M×N个数中的最大值。具体要求如下:

  • 定义函数 input(),从后台获取数据,实现二维数组的输入;
  • 定义函数 maxnum(),找出二维数组的最大值,并返回结果;
  • 定义函数 output(),根据测试说明的预期输出格式输出二维数组;
  • 完善函数 main(),创建二维动态数组,最后释放内存。

测试说明

平台会对你编写的代码进行测试。

测试输入: 3 4

54 21 36 58 4 78 46 2 35 47 69 28

输入说明: 第一行为二维数组的行数和列数; 第二行为二维数组的具体值。

预期输出:

max=78

54 21 36 58

4 78 46 2

35 47 69 28

#include <stdio.h>
#include <stdlib.h>

void input(int **p,int m,int n);
int maxnum(int **p,int m,int n);
void output(int **p,int m,int n);
int main()
{ 
	int **p,i;
	int  m,n;
	//printf("input m,n=");
	scanf("%d%d",&m,&n);     //m存储二维数组的行数,n存储列数
	/********** 申请m*n的二维动态数组 **********/ 
	/********** Begin **********/
    p=(int **)malloc(m*sizeof(int *));
    for( i=0;i<m;i++) 
	p[i]=(int *)malloc(n*sizeof(int));
	/********** End **********/
	input(p,m,n);
	printf("max=%d\n",maxnum(p,m,n));
	output(p,m,n);
	/********** 释放二维动态数组 **********/ 
	/********** Begin **********/ 
    for(i=0;i<m;i++)
    free(p[i]);
    free(p);
	/********** End **********/
	return 0;
}
    /********** 定义3个子函数 **********/ 
    /********** Begin **********/ 
//函数一
void input(int **p,int m,int n)
{
    for(int i=0;i<m;i++)
    for(int j=0;j<n;j++)
       scanf("%d",&p[i][j]);
}
//函数二
int maxnum(int **p,int m,int n)
{
    int max=0;
    for(int i=0;i<m;i++)
    for(int j=0;j<n;j++)
        if(max<p[i][j])
        max=p[i][j];
    return max;
}
//函数三
void output(int **p,int m,int n)
{
    for(int i=0;i<m;i++)
    {
    for(int j=0;j<n;j++)
    {
        printf("%d ",p[i][j]);  
    }
    printf("\n");
    }
 }
     /********** End **********/
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值