@C/C++学习-二维动态数组的创建,与传参
1.C语言方式
利用malloc,free 创建及释放二维数组;
本文以简单的检验二维矩阵是否为幻方矩阵的例题为例。幻方矩阵即每行/每主对角线/每副对角线的元素和均相等.
其中创建二维动态数字的部分为:
`int n = 0;
scanf("%d", &n);
int **array = (int **)malloc(sizeof(int) * n * n); //n阶方阵
assert(array != NULL);
memset(array,0,sizeof(int) * n * n);//这句其实没用
for (int i = 0; i < n; i++)
{
array[i] = (int *)malloc(sizeof(int) * n);
assert(array[i] != NULL);
memset(array[i], 0, sizeof(int) * n); //真正的初始化
}`
我用了assert()做对申请空间失败的检测;(这种方法是我一开始使用的方法,后来发现是错的,详情见https://www.cnblogs.com/ywliao/articles/8116622.html)即new delete 语句对不应该用assert()判断。因为new 语句不会返回NULL,应该用
try
{
int *array=new int [n];
}
catch(bad_alloc)
{
;//代码块1
}
catch(...)
{
;
}
另外,assert函数仅适用于调试阶段,发布阶段不适用,因此不适合用于此处对空指针的检测,以避免产品上线后可能产生的bug.
最基础的
```c
if(NULL == array)
{
exit(1);//return 1;
}
有它的价值。
二维动态数组的释放也是要遵循规律,先释放循环体内的,再释放最大二维数组。
```c
for (int i = 0; i < n; i++)
{
free(array[i]);
array[i]=NULL;
}
free(array);
array = NULL;
释放之后指针置空防止野指针。
//《C++程序设计实践教程》
//exp12_6 by 随志同 2020-3-28
//判定N*N的矩阵是否为幻方
//每行/每主对角线/每副对角线 元素和相等
//编译器:g++ (x86_64-posix-seh-rev0, Built by MinGW-W64 project) 8.1.0
#include <stdio.h>
#include <assert.h>
#include <windows.h>
int Is_Huanfang(int **array, const int arraySize);
int Is_Huanfang(int **array, const int arraySize)
{
int *sum_row = (int *)malloc(sizeof(int) * arraySize);
assert(sum_row != NULL);
memset(sum_row, 0, sizeof(int) * arraySize);
int sum_line1 = 0;
int sum_line2 = 0;
for (int i = 0; i < arraySize; i++)
{
for (int j = 0; j < arraySize; j++)
{
sum_row[i] += array[i][j];
printf("%d ", array[i][j]);
if (i == j)
{
sum_line1 += array[i][j];
}
if ((i + j + 1) == arraySize)
{
sum_line2 += array[i][j];
}
}
printf("\n");
}
for (int i = 0; i < arraySize; i++)
{
printf("sum_row[%d]: %d \n", i, sum_row[i]);
}
printf("sum_line1: %d \n",sum_line1);
printf("sum_line2: %d \n",sum_line2);
if (sum_line2 == sum_line1)
{
for (int i = 0; i < arraySize; i++)
{
if (sum_row[i] != sum_line1)
{
return 0;
}
}
free(sum_row);
return 1;
}
else
{
free(sum_row);
return 0;
}
}
int main()
{
int n = 0;
scanf("%d", &n);
int **array = (int **)malloc(sizeof(int) * n * n); //n阶方阵
assert(array != NULL);
memset(array,0,sizeof(int) * n * n);//这句其实没用
for (int i = 0; i < n; i++)
{
array[i] = (int *)malloc(sizeof(int) * n);
assert(array[i] != NULL);
memset(array[i], 0, sizeof(int) * n); //真正的初始化
}
for (int i = 0; i < n; i++)
{
for (int j = 0; j < n; j++)
{
scanf("%d", &array[i][j]);
}
getchar(); //这句为了解决输入时scanf会读入\n的问题
}
printf("矩阵为:");
for (int i = 0; i < n; i++)
{
for (int j = 0; j < n; j++)
{
printf("%d ", array[i][j]);
}
printf("\n");
}
printf("\n");
if (Is_Huanfang(array, n))
{
printf("该矩阵是幻方\n");
}
else
{
printf("该矩阵不是幻方\n");
}
for (int i = 0; i < n; i++)
{
free(array[i]);
}
free(array);
array = NULL;
system("pause");
return 0;
}
2.C++方式
C++对2维动态数组的创建我只会一下两种方法
1.new delete[] 方式
与malloc -free 相对应
代码如下:
1.new[n]申请的空间要用 delete[] 的形式释放。
2.其余与C语言大同小异。
不得不说,cin,cout 确实比printf(),sacnf()用起来方便。
//exp12_6 by 随志同 2020-3-27
//判定N*N的矩阵是否为幻方
//每行/每主对角线/每副对角线 元素和相等
#include <iostream>
#include <iomanip>
#include <vector>
#include <assert.h>
#include <windows.h>
using std::cin;
using std::cout;
using std::endl;
using std::vector;
int Is_Huanfang(int **array, const int arraySize);
int Is_Huanfang(int **array, const int arraySize)
{
int *sum_row = new int[arraySize]{0};
int sum_line1 = 0;
int sum_line2 = 0;
for (int i = 0; i < arraySize; i++)
{
for (int j = 0; j < arraySize; j++)
{
sum_row[i] += array[i][j];
if (i == j)
{
sum_line1 += array[i][j];
}
if ((i + j + 1) == arraySize)
{
sum_line2 += array[i][j];
}
}
cout << endl;
}
if (sum_line2 == sum_line1)
{
for (int i = 0; i < arraySize; i++)
{
if (sum_row[i] != sum_line1)
{
delete[] sum_row;
return 0;
}
}
delete[] sum_row;
return 1;
}
else
{
delete[] sum_row;
return 0;
}
}
int main()
{
int n = 0;
cin >> n;
int **array = new int *[n];
for (int i = 0; i < n; i++)
{
array[i] = new int[n];
}
for (int i = 0; i < n; i++)
{
for (int j = 0; j < n; j++)
{
cin >> array[i][j];
}
}
cout << "test_array" << endl;
for (int i = 0; i < n; i++)
{
for (int j = 0; j < n; j++)
{
cout << array[i][j] << " ";
}
cout << endl;
}
cout << "testover" << endl;
if (Is_Huanfang(array, n))
{
cout << "该矩阵是幻方" << endl;
}
else
{
cout << "该矩阵不是幻方" << endl;
}
for (int i = 0; i < n; i++)
{
delete[] array[i];
}
delete[] array;
array = NULL;
system("pause");
return 0;
}
2.形式
vector形式的容器用来构建二维动态“数组”是最方便的。但我还没学好,代码后补;
二维数组做形参
1.基本形式;
我常见的自定义函数示例
int Fun(int** array,int *arrayColSize,int arraySize);
该形式一般是用,二维数组的指针作为形参进行传递,其中*arraySize参数我看leetcode上是表示每行的长度。arraySize参数一般表示,数组大小n,或者其他形式。由程序员自己规定。
2. 函数体内进行的访问
我常用的有两种,一种是 array[i][j]
另一种是*(*(array+i)+j)
,一些其他的帖子说 通过*((int *)array+i*colSize+j)
可以访问,其中colSize表示行的宽度。原理上认为数组连续存储,直接这样访问地址我是理解的,但我个人的实际操作却访问失败了,不知道什么原因,如有了解者望留言讲解。
个人推荐的还是第一种array[i][j]
的形式。拼写的最快
另有const int ** array 做形参保护array不被改变,我暂时还不熟练掌握,以后再做扩展。
另本人系初学者,如有错漏之处,万请告知,再次拜谢。