指针数组和数组指针的区别

来源:互联网 发布:mysql事物隔离级别 编辑:程序博客网 时间:2024/06/01 22:29
数组指针(也称行指针)
定义 int (*p)[n];
()优先级高,首先说明p是一个指针,指向一个整型的一维数组,这个一维数组的长度是n,也可以说是p的步长。也就是说执行p+1时,p要跨过n个整型数据的长度。

如要将二维数组赋给一指针,应这样赋值:
int a[3][4];
int (*p)[4]; //该语句是定义一个数组指针,指向含4个元素的一维数组。
 p=a;        //将该二维数组的首地址赋给p,也就是a[0]或&a[0][0]
 p++;       //该语句执行过后,也就是p=p+1;p跨过行a[0][]指向了行a[1][]

所以数组指针也称指向一维数组的指针,亦称行指针。

指针数组
定义 int *p[n];
[]优先级高,先与p结合成为一个数组,再由int*说明这是一个整型指针数组,它有n个指针类型的数组元素。这里执行p+1时,则p指向下一个数组元素,这样赋值是错误的:p=a;因为p是个不可知的表示,只存在p[0]、p[1]、p[2]...p[n-1],而且它们分别是指针变量可以用来存放变量地址。但可以这样 *p=a; 这里*p表示指针数组第一个元素的值,a的首地址的值。
如要将二维数组赋给一指针数组:
int *p[3];
int a[3][4];
p++; //该语句表示p数组指向下一个数组元素。注:此数组每一个元素都是一个指针
for(i=0;i<3;i++)
p[i]=a[i]
这里int *p[3] 表示一个一维数组内存放着三个指针变量,分别是p[0]、p[1]、p[2]
所以要分别赋值。

这样两者的区别就豁然开朗了,数组指针只是一个指针变量,似乎是C语言里专门用来指向二维数组的,它占有内存中一个指针的存储空间。指针数组是多个指针变量,以数组形式存在内存当中,占有多个指针的存储空间。
还需要说明的一点就是,同时用来指向二维数组时,其引用和用数组名引用都是一样的。
比如要表示数组中i行j列一个元素:
*(p[i]+j)、*(*(p+i)+j)、(*(p+i))[j]、p[i][j]

优先级:()>[]>*

出处:http://www.cnblogs.com/hongcha717/archive/2010/10/24/1859780.html

=========================================================================

一、指针数组和数组指针的内存布局

初学者总是分不出指针数组与数组指针的区别。其实很好理解:
指针数组:首先它是一个数组,数组的元素都是指针,数组占多少个字节由数组本身的大小决定,每一个元素都是一个指针,在32 位系统下任何类型的指针永远是占4 个字节。它是“储存指针的数组”的简称。
数组指针:首先它是一个指针,它指向一个数组。在32 位系统下任何类型的指针永远是占4 个字节,至于它指向的数组占多少字节,不知道,具体要看数组大小。它是“指向数组的指针”的简称。


下面到底哪个是数组指针,哪个是指针数组呢:
A)
int *p1[10];
B)
int (*p2)[10];
每次上课问这个问题,总有弄不清楚的。这里需要明白一个符号之间的优先级问题。

“[]”的优先级比“*”要高。p1 先与“[]”结合,构成一个数组的定义,数组名为p1,int *修饰的是数组的内容,即数组的每个元素。那现在我们清楚,这是一个数组,其包含10 个指向int 类型数据的指针,即指针数组。至于p2 就更好理解了,在这里“()”的优先级比“[]”高,“*”号和p2 构成一个指针的定义,指针变量名为p2,int 修饰的是数组的内容,即数组的每个元素。数组在这里并没有名字,是个匿名数组。那现在我们清楚p2 是一个指针,它指向一个包含10 个int 类型数据的数组,即数组指针。我们可以借助下面的图加深理解:

二、关于行指针和列指针的区别补充如下:

表示形式

含义

指针类型

a或者a+0

指向第0

行指针

a+1

指向第1

行指针

a+2

指向第2

行指针



表示形式

含义

指针类型

a[0]

是一维数组的名称,也是它的首地址,而且是第1个元素的地址(a[0]+0

列指针

a[0]+1

0行,第2个元素的地址

列指针

a[0]+2

0行,第3个元素的地址

列指针


行指针

转换成:列指针

列指针等价表示

内容

内容等价表示

含义

aa+0

*a

a[0]

*a[0]

*(*a)

a[0][0]

a+1

*(a+1)

a[1]

*a[1]

*(*(a+1))

a[1][0]

a+2

*(a+2)

a[2]

*a[2]

*(*(a+2))

a[2][0]


总得来说,对行指针解引用就可以得到列指针,对列指针解引用就可以得到对应内容。

测试代码:

// PointerArray.cpp : 定义控制台应用程序的入口点。//#include "stdafx.h"int _tmain(int argc, _TCHAR* argv[]){int a[3][4] = { 0, 1, 2, 3,4, 5, 6, 7,8, 9, 10, 11 };printf("Row Adress: %d %d %d\n", a, a+1, a+2);//行的首地址printf("Row COl Adress: %d %d %d\n", a[0], a[1], a[2]);//x行0列元素的地址   a[0]+0 a[0]+1 a[0]+2 a[0]+3 分别是0行0列 0行1列元素的地址printf("Zero Row Adress: %d %d %d %d\n", a[0], a[0] + 1, a[0] + 2, a[0]+3);int (*p)[4];//数组指针 = 指向数组的指针p = a+1;for (int i = 0; i < 4; i++){printf("%d  ", *(*p + i));// *( *(a+i)+j ) = a[i][j]  )}printf("\n");p = a;for (int i = 0; i < 3; i++){printf("%5d%5d%5d%5d\n", **p, *(*p + 1), *(*p + 2), *(*p + 3));p++;//p 看成行指针  (a,a+1,a+2)}//用列指针输出整个数组printf("用列指针输出整个数组:\n");int *colP = a[0];for (; colP < a[0] + 12; colP++){printf("%5d", *colP);}puts("\n");int* q[3];//指针数组 = 存储指针的数组printf("指针数组输出元素.\n");for (int i = 0; i < 3; i++){q[i] = a[i];//q[i] 看成列指针}for (int i = 0; i < 3; i++){for (int j = 0; j < 4; j++){printf("%5d", *(q[i] + j));}printf("\n");}return 0;}



原创粉丝点击