文章详情

  • 游戏榜单
  • 软件榜单
关闭导航
热搜榜
热门下载
热门标签
php爱好者> php文档>二级指针和二维数组

二级指针和二维数组

时间:2010-03-16  来源:riverok

二级指针和二维数组

author: fengxz

先看下面一个简单例子:

int main()

{

char *onedp = NULL;  //one dimension array

char **twodp = NULL;  //two dimension array

        char a[3][16] = {"China_and_me", "c++", "It is a desk"};

        int i = 0;

 

        twodp = (char **)a;

        for(i = 0; i < 3; i++)

{

                printf("%s\n",a[i]);      

                printf("%s\n", *(twodp + i));          

        }

        return 0;      

}

在以上程序中,twodp 是一个二级指针,a[3][16]是一个二维数组。

for本要循环输出a[3][16]中的每一个字符串,但是遗憾的是,在执行printf("%s\n", *(twodp + i))时程序就down了。

下面看一下其中用到了那些知识:

     1) 以一维数组角度看待二维数组。

         对于a[3][16],这样来认识:首先把a作为一维数组看待,不过这个数组的元素仍是数组,即有4个数组为a的元素:a[0],a[1],a[2],a[3]。因此,a+1就是跨越一个行,所以a也称为行地址。关于行指针后面叙述。

         而a[i](i=0,1,2,3)又是一个一维数组,他的元素为a[i][j](j=0,1,2,...16),所以a[i]+1跨越a[3][16]的一个元素大小。

2) 应该要知道一点,指针变量中存放的是某个地址的值。

所以一维指针和二维指针变量的值,即onedp和twodp值都是某个地址,一维指针和二维指针变量不同的是,对二维指针变量操作:*twodp仍然是一个地址,而*onedp就是代表one所指的变量了。

这样看来,对上面的程序,twodp = (char **)a;这样twodp就指向二维数组的首地址,而这个首地址指向了字符c,当i为0时,twodp + i存放的是指向字符c的地址,那么*(twodp + i)的值就是字符c了,而字符c的ASCII码的16进制值是0x63,所以*(twodp + i)是0x63。注意,不要忘了twodp是一个二维指针,所以*(twodp + i)仍是一个地址,不幸,该值0x63却是内存中我们所无法访问的空间。这样我们就不难理解上面程序down的原因了。知道了原因,就离解决方法不远了,不过在说解决方法之前,我们先看另一个问题

3)对指针的运算,均是以指针所代表的类型为单位进行。

如果i=2,twodp = 0x0012fe90那么twodp + i是多少?

如果你答0x0012fe92,那就错了。

因为对指针的运算,均是以指针所代表的类型为单位进行。对于二级指针twodp,它的一级指针*twodp仍是指针类型,无论是char指针,还是其他指针,只要是指针类型,就占有4个字节(32位机)。所以twodp + i就是0x0012fe90 + i*4,当i=0时为0x0012fe94!

4)“行指针”概念

看一个例子:

int (*p)[16];

它定义了这样一个指针:这个指针指向一个一维数组,这个一维数组共有16个元素。

如果这样使用:

int a1[16];

p = a1;

那么p+1将发生越界,因为对p而言,它以行为单位进行。它每次走一行,一行是它的最小单位。对于a1[16],一行就是16个元素。每个元素4个字节,所以每一次p+1将跨越64个字节。行指针用在二维数组表现的很充分。因为二维数组可以看成一维数组的数组。对于二维数组a[3][16],共有3行。每一行又是含有16个元素的一维数组。从刚才上面对二位数组分析,二位数组名就是该数组第0行首地址,就是行地址。但是一定要注意a不是行指针,只是一个常量。

注意定义行指针时保持和二维数组的第二维一致!因为行指针移动按照这个“维”进行的。

 

有了以上知识,我们就可以方便操作二维数组了。

对于开始的例子,为了输出二维数组a[3][16]的每个字符串,以下几种方法:

1)设一个行指针。

char (*linep)[16];  // line type pointer

 

linep = a[0];

        for(i = 0; i < 3; i++)

        {

                printf("%s\n",linep + i);      

                               

    }

 

2)直接使用二级指针,不过一定注意二级指针的计算

twodp = (char **)a;

 

       

 

        for(i = 0; i < 3; i++)

        {

                printf("%s\n", twodp + i*4);           

    }      

这里一定要知道为什么是i与4相乘!

如果定义二维数组a为a[3][17],内容和a[3][16]相同。那么将很难找到直接使用二级指针来访问a[3][17]的每一个字符串的方法了。

相关阅读 更多 +
排行榜 更多 +
辰域智控app

辰域智控app

系统工具 下载
网医联盟app

网医联盟app

运动健身 下载
汇丰汇选App

汇丰汇选App

金融理财 下载