第4关:创建M×N的二维动态数组,存放输入的M×N个整数,然后求这M×N个数中的最大值
300
- 任务要求
- 参考答案
- 评论3
任务描述
本关任务:创建M×N
的二维动态数组,存放输入的M×N
个整数,然后求这M×N
个数中的最大值。
相关知识
C 语言有三种方法创建二维动态数组:
- 利用一个二级指针来实现
- 利用数组指针来实现
- 利用一维数组来模拟二维数组
利用一个二级指针来实现创建二维动态数组
实际上,C 语言中没有二维数组,至少对二维数组没有直接的支持,取而代之的是“数组的数组”,二维数组可以看成是由指向数组的指针构成的数组。基于这个原理,可以通过分配一个指针数组,再对指针数组的每一个元素分配空间,实现动态分配二维数组。 现在有指针p
定义如下:int **p;
,因为p
是指针的指针,需要两次内存分配才能使用其最终内容。
p = ( int ** ) malloc ( M * sizeof( int *) ); //动态分配M个类型为int*的内存空间
p
指向长度为M
的指针数组,再为指针数组的M
个数组元素分配内存单元,即:
for(i=0; i<M; i++)
{
p[i]=(int *)malloc( N *sizeof ( int ) ); //动态分配长度为N的int数组
}
p[i]
中存放的是长度为N
的一个int
型数组的首地址,即p[i]
的值是指针,这时才可以使用下标用法p[i][j]
存放一个int
型数据。 这样分配的二维数组同一行中元素地址是连续的,不同行中元素地址不一定是连续的。 如果没有第一次内存分配,p
是个野指针,是不能使用的;如果没有第二次内存分配,则p[0]
、p[1]
等也是个野指针,也是不能用的。申请了内存空间后,M×N
的二维动态数组p
的输入输出和普通静态的二维数组一样:
for(i=0; i<M; i++)
for(j=0; j<N; j++)
scanf("%d", &p[i][j] )
for(i=0; i<M; i++)
for(j=0; j<N; j++)
printf("%d ",p[i][j] )
最后在使用结束后,要将申请的内存资源全部释放:
for(i=0; i<M; i++)
{
free(p[i]); //首先释放M行的N个类型为int的内存空间
}
free(p); //释放长度为M类型为int*的内存空间
利用数组指针来实现创建二维动态数组
数组指针和指针数组是不同的。数组指针是指针变量,其本质仍然是一个变量。指针数组其本质是一个数组,存放的元素类型是指针类型。
例如,申请一个3×4
的二维动态数组:
int(*p)[4];
p = (int(*)[4]) malloc( 3 * sizeof(int (*)[4]) ); //申请一个3行4列的二维动态数组
for (int i = 0; i < 3; ++i)
{
for (int j = 0; j < 4; ++j)
{
scanf("%d", &p[i][j] ) //输入数组每个元素
}
}
for (int i = 0; i < 3; ++i)
{
for (int j = 0; j < 4; ++j)
{
printf("%d ", p[i][j]); //输出数组每个元素
}
}
free(p); //释放所有空间
利用数组指针来实现申请二维动态数组,只需申请一次地址空间,并且数组元素的地址始终是连续的,一次可以释放所有的地址空间。
利用一维数组来模拟二维数组
例如,定义一个长度为了12
的一维数组来模拟3×4
的二维动态数组:
int *p;
p = (int *)malloc(sizeof(int) * 3 * 4);
for (int i = 0; i < 3 ++i)
{
for (int j = 0; j < 4; ++j)
{
scanf("%d", &p[i*4+j]); //此处& p[i*4+j]不可以写成&p [i][j]
}
}
for (int i = 0; i < 3 ++i)
{
for (int j = 0; j < 4; ++j)
{
printf("%d ",p[i*4+j]); //此处p[i*4+j]不可以写成p [i][j]
}
}
p
是一个一级指针,只能接收二维数组的元素的首地址,系统只能靠整数3
和 4
来划分二维数组的行数和列数。
编程要求
根据提示,在右侧编辑器 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 **********/