zoukankan      html  css  js  c++  java
  • 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来访问和操作动态数组的所有元素。




  • 相关阅读:
    lua版本的一个状态机
    unity getcomponentsinchildren 翻船
    dotween tips
    ulua c#调用lua中模拟的类成员函数
    洗牌算法
    unity的一些tips
    用Unity写一个12306验证器的恶搞图生成软件
    好久没写Blog了
    蛋疼的时候写三消游戏(十三)
    用DropBox分享Unity3D的Web应用
  • 原文地址:https://www.cnblogs.com/silyvin/p/9106919.html
Copyright © 2011-2022 走看看