一、利用malloc函数分两步实现
一个m行n列的二位数组的动态申请可以分为三步,第一步,申请一个长度为m*sizeof(int*)的一维数组,用来存放放一级指针;第二步,用for循环结构,申请m个长度为n的一维数组,用来存放二维数组中的元素,每循环一次,申请一列元素的空间;第三步,释放。
代码实现:
(下面代码为牛客网上一个关于计算N行M列二维数组中不大于0的元素和的代码)
//描述
//输入NxM矩阵,矩阵元素均为整数,计算其中大于零的元素之和。
//输入描述:
//第一行为N M(N: 矩阵行数;M: 矩阵列数, 且M, N <= 10),接下来的N行为矩阵各行。
//输出描述:
//一行,其中大于零的元素之和。
//示例1
//输入:
//3 3
//2 3 4
//- 5 - 9 - 7
//0 8 - 4
//输出:
//17
#include <stdio.h>
#include <stdlib.h>
//函数功能:计算二维数组中大于0的元素之和
int Sum(int** arr, int n, int m)
{
int i = 0;
int j = 0;
int ret = 0;
for (i = 0; i < n; i++)
{
for (j = 0; j < m; j++)
{
if (arr[i][j] > 0)
ret += arr[i][j];
}
}
return ret;
}
int main()
{
int N = 0;
int M = 0;
scanf("%d%d", &N, &M);
//动态申请一个N行M列的二维数组
int** arr = (int**)malloc(sizeof(int*) * N);
int i = 0;
for (i = 0;i < N;i++)
{
arr[i] = (int*)malloc(sizeof(int) * M);
}
for (i = 0; i < N; i++)
{
int j = 0;
for (j = 0; j < M; j++)
{
scanf("%d", &arr[i][j]);
}
}
//计算二维数组中大于0的元素之和
int sum = Sum(arr, N, M);
printf("%d\n", sum);
//释放
for (i = 0;i < N;i++)
free(arr[i]);
free(arr);
return 0;
}
其中,下面的部分即为用malloc函数申请一个N行M列二维数组的具体代码:
注意:不同行之间的地址不一定连续
二、利用malloc函数申请一步到位
原理:因为二维数组在内存中也是连续的,所以,可以直接申请一个长度为行数*列数的一维数组,输出是按行输出即可。
代码实现:
//动态申请一个行和列均为常数的二维数组
//方法:直接申请一个长度为行数*列数的一维数组
//以一个三行四列的二维数组为例
#include <stdio.h>
#include <stdlib.h>
int main()
{
//动态申请
int* arr = (int*)malloc(sizeof(int) * 3 * 4);
//依次输入二维数组的各元素的值
printf("请输入一个3行4列的二维数组中各元素的值:\n");
for (int i = 0;i < 3;i++)
{
for (int j = 0;j < 4;j++)
{
scanf("%d", &arr[i * 4 + j]);
}
}
//输出各元素的值
printf("该二维数组为:\n");
for (int i = 0;i < 3;i++)
{
for (int j = 0;j < 4;j++)
{
printf("%d ", arr[i*4+j]);
}
printf("\n");
}
//释放
free(arr);
return 0;
}
注意:不同行之间地址连续
三、利用指针数组申请一步到位
原理:指针数组是数组,数组的各元素是指针,对于m行n列的二维数组,创建一个长度为m的指针数组,数组元素依次指向各行。
代码实现:
//利用指针数组动态申请一个二维数组
#include<stdio.h>
#include<stdlib.h>
int main()
{
//申请一个3行4列的二维数组
int(*p)[4] = (int(*)[4])malloc(sizeof(int) * 3 * 4);
for (int i = 0; i < 3; ++i)
{
for (int j = 0; j < 4; ++j)
{
//输出数组每个元素地址
printf("%p\n", &p[i][j]);
}
}
free(p);
return 0;
}
运行结果:
观察可知,地址连续。
总结:上述三种方法对于行和列是否为变量或常量都适用,第一种方法中的代码实现使用的是变量的举例,第二、三种方法中的代码实现使用的是常量的举例,实际两者皆适用。(但一般只有当行和列为变量时需要用到)