C++入门--动态创建一维、二维数组 静态数组不能扩容(realloc),动态的才可以(如何创建动态数组) 二维数组及多维数组的指针总结

动态创建一维数组

VS2010中输入:

#include <iostream>
using namespace std;
//根据变量动态创建一维数组
int main()
{
	int N=5;
	int *p=new int[N];
	/*初始化方法一*/
	//memset(p,0,sizeof(int)*N);
	/*初始化方法二*/
	for(int i=0;i<N;i++)
		p[i]=0;
	while(N--)
		cout<<p[0]<<endl;
	delete []p;
	return 0;
}

输出5个0

但是如果想用p[6]怎么办?

C语言可以用realloc,C++可以用vector,或者自己重新new一个所需大小的数组,然后把之前的复制过来。

这个博客写的挺好:

静态数组不能扩容(realloc),动态的才可以(如何创建动态数组)


动态创建二维数组

#include <iostream>
using namespace std;
//根据变量动态创建一维数组
int main()
{
	int N=10;
	int **p=new int* [N];
	for(int i=0;i<N;i++)
		p[i]=new int [N];


	/*初始化方法一
	p代表的是指向p[N]
	要注意 p 和 &p 的类型是不同的。p 相当于 &p[0],
	而 &p 是一个指向 int[N] 的指针,类型是 int(*)[N]。*/
	for(int i=0;i<N;i++)
		memset(p[i],0,sizeof(int)*N);
	/*结果不对,不论用	
	memset(p,0,sizeof(int)*N*N);
	memset(p[0],0,sizeof(int)*N*N);
	memset(&p[0][0],0,sizeof(int)*N*N);
	都不对,最后输出,还会报错
	0 0 0 0 0
	-842150451 -842150451 -842150451 -842150451 -842150451
	-842150451 -842150451 -842150451 -842150451 -842150451
	-842150451 -842150451 -842150451 -842150451 -842150451
	-842150451 -842150451 -842150451 -842150451 -842150451
	*/
	/*初始化方法二*/
	for(int i=0;i<N;i++)
		for(int j=0;j<N;j++)
		{
			p[i][j]=0;
		}
	
	for(int i=0;i<N;i++)
	{
		cout<<endl;
		for(int j=0;j<N;j++)
		{
			cout<<&p[i][j]<<" ";
		}
	}	
	for(int i=0; i<N; i++)
	{
	    delete p[i];//为什么不是delete[]p[i]?释放这些指针以及指向的空间
	}
	delete [] p;//释放int*(N)指针
        return 0;
}

代码比较多,知识点也比较多

首先是二维数组的指针类型:

p代表的是指向p[N]
	要注意 p 和 &p 的类型是不同的。p 相当于 &p[0],
	而 &p 是一个指向 int[N] 的指针,类型是 int(*)[N]

也可以看看博客:

二维数组及多维数组的指针总结


然后是初始化:

不能直接用:

memset(p,0,sizeof(int)*N*N);

因为地址不对,比如我将每个元素&p[][]的地址输出出来

&p[0][0]: 

033638D8 033638DC 033638E0 033638E4 033638E8

03363708 0336370C 03363710 03363714 03363718
03363748 0336374C 03363750 03363754 03363758
03363788 0336378C 03363790 03363794 03363798

033637C8 033637CC 033637D0 033637D4 033637D8

&p[4][4]: 

明显可以看出p[0][0]和p[1][0]地址差距为5*16=80个字节,但是咱们数组应该是5*4=20个字节

本来以为是指针的原因。把指针地址输出出来

&p[i]: 032D48D8
&p[i][j]: 032D4928 &p[i][j]: 032D492C &p[i][j]: 032D4930 &p[i][j]: 032D4934 &p[i][j]: 032D4938
&p[i]: 032D48DC
&p[i][j]: 032D4978 &p[i][j]: 032D497C &p[i][j]: 032D4980 &p[i][j]: 032D4984 &p[i][j]: 032D4988
&p[i]: 032D48E0
&p[i][j]: 032D49C8 &p[i][j]: 032D49CC &p[i][j]: 032D49D0 &p[i][j]: 032D49D4 &p[i][j]: 032D49D8
&p[i]: 032D48E4
&p[i][j]: 032D4A18 &p[i][j]: 032D4A1C &p[i][j]: 032D4A20 &p[i][j]: 032D4A24 &p[i][j]: 032D4A28
&p[i]: 032D48E8

&p[i][j]: 032D4A68 &p[i][j]: 032D4A6C &p[i][j]: 032D4A70 &p[i][j]: 032D4A74 &p[i][j]: 032D4A78

发现指针的地址都小于数据地址,可以说先给指针地址,再给数据地址(堆从低地址向高地址扩展)

好了,到现在我已经不动了。

我把N调成10,发现本来应该是4个字节的差距,结果是104.

这个肯定是浪费了太多的空间,所以说以后刷笔试题目,还不如直接用1000的固定数组来做。。。

说多了,回过来再说初始化:

两种方式,必须用for循环。。。

更推荐:

	for(int i=0;i<N;i++)
		for(int j=0;j<N;j++)
			p[i][j]=0;

在说下释放空间

	for(int i=0; i<N; i++)
	{
	    delete p[i];//为什么不是delete[]p[i]?释放这些指针以及指向的空间
	}
	delete [] p;//释放int*(N)指针

程序员的知识点相当多,每次想写一个知识点,发现扩展下去无穷无尽,可能这就是编程的魅力吧。

打好基础,好好学习


猜你喜欢

转载自blog.csdn.net/m0_37561165/article/details/80926358