C++指向指针的指针与动态数组


这里以一维字符数组开篇,
#include <iostream>
using namespace std;

void main()
{
	char *pc="abc"; 
	cout<<pc<<endl;  
	cout<<(long)pc<<endl; 
	cout<<*pc<<endl;       
}

输出:

在本例中,字符数组"abc"存在于内存空间的const区域中,指针变量pc存储在内存栈空间内,pc的值为字符数组"abc"的首地址,也就是字符'a'的地址,输出在第二行,而在c++中,输出字符指针就是输出字符串,程序会自动在遇到\0后停止所以在第一行则完整的输出了字符串"abc"。*pc为从内存地址为pc值的空间内取出值,也就是字符'a'。


如果对一个二维字符数组操作,则要用到指向指针的指针。

指针的本质是一个存放其他变量内存地址的unsigned long int型变量,储存于内存栈空间内。这里假设这个变量为a,指针的指针即是存放a在栈空间中地址的long型变量,也储存在栈空间中。


#include <iostream>
using namespace std;

void main()
{
	char *pc[]={"abc","xyz","sun"};
	char **pb=&pc[0];
	for(int i=0;i<3;++i)
	{
		for(int j=0;j<4;++j)
		{
			cout<<*(*(pb+i)+j)<<" ";
		}
	}
        cout<<endl;
}

输出:

下面来逐句解析:

	char *pc[]={"abc","xyz","sun"};

定义了一个指针数组,为pc[0], pc[1], pc[2],分别存放了三个字符数组的首地址,这里pc[0]存放了'a'的地址值,pc[1]存放了'x'的地址值,pc[2]存放了's'的地址值,而这三个存放地址(long型数值)的指针变量也储存在内存中,因为是long型数组,所以它们在内存中的地址是连续的,也就是&p[0]+1=&p[1],&p[1]+1=&p[2]。

	char **pb=&pc[0];

定义了一个指向指针的指针,其本质上指向了内存中一个long型变量,将它的地址储存起来。这样可以理解为,存放'a'地址long型变量的地址被存放在变量pb中,此时,变量pb的值即是指针数组第一个元素pc[0]的地址,pb+1是指针数组第二个元素pc[1]的地址,pb+2是指针数组第三个元素pc[2]的地址。

pb=&pc[0], pb+1=&pc[1], pb+2=&pc[2]

至此,所有的变量在内存中的关系已经建立,可以用一个指向指针的指针pb去访问二维字符数组的任意元素的值与地址。

	cout<<*(*(pb+i)+j)<<" ";

pb+i的值为指针变量pc[i]在内存中的地址,*(pb+i)则把该地址中的值取了出来,比如*(pb+1)=pc[1],这里的pc[1]的值是第二个字符串"xyz"的首地址(即字符'x'的地址、为一long型数值),有了'x'的地址即可访问第二个字符数组的任意成员,如需要输出“xyz"的第三个字符'z',则先取得'z'的地址,*(pb+1)+2,然后从找寻存放于该内存地址中的东西(就是字符'z'),通过*(*(pb+1)+2)取得'z'这个字符。


下面应用指向指针的指针定义动态数组

假设有一个矩阵m×n,其动态数组创建函数如下:

void test4(int m,int n)
{
	int **ppTest=new int *[m];
	for(int i=0;i<m;++i)
	{
		*(ppTest+i)=new int[n];
		//*ppTest++=new int[n];
	}

	//ppTest-=m;

	for(i=0;i<m;++i)
	{
		for(int j=0;j<n;++j)
		{
			*(*(ppTest+i)+j)=i+j;
		}
	}

	for(i=0;i<m;++i)
	{
		for(int j=0;j<n;++j)
		{
			cout<<*(*(ppTest+i)+j)<<'\t';
		}
		cout<<'\n';
	}
	for(i=0;i<m;++i)
	{
		delete [] *(ppTest+i);
	}
	delete [] ppTest;
}

Test(3,4);

输出:

	int **ppTest=new int *[m];

先定义一个具有m个元素的指针数组,本质上是在内存堆空间中定义了个具有m个元素的long型数组,将该数组的首地址存于变量ppTest中,该变量位于内存栈空间。

	for(int i=0;i<m;++i)
	{
		*(ppTest+i)=new int[n];
	}

然后逐轮在内存堆空间中定义具有n个元素的整形数组,new关键字返回该数组的首地址,我们所要做的就是用一个变量去接受这个地址的值。ppTest+i为刚才在内存堆空间中申请的具有m个元素的long型数组的第i个变量的地址,把n元素整形数组的首地址填进那个地址的内存空间中,接着就可以用变量ppTest操作整个数组了。如:

			*(*(ppTest+i)+j)=i+j;

ppTest+i为存放内存堆空间中第i行的一维整形数组的首地址的指针变量在内存堆空间中的地址,把它的值取出来就可得到第i行一维数组所有元素在内存堆空间中的地址,再通过解引用操作符"*"操作该地址的那片内存空间,这样则实现了通过在栈空间中的指向指针的指针**pb来访问和操作动态数组的所有元素。




原文地址:https://www.cnblogs.com/silyvin/p/9106919.html