从内存角度理解指针和数组(二)
1,有一种指针叫行指针
所谓行指针,说明指针类型是行,指针变量存的是某一行的首地址,该行也是一片连续的内存区。
[cpp]
long int (*p)[4] = NULL; //定义一个行指针,一行有4个long int类型的元素。
long int b[3][4]= {1,2,3,4,5,6,7,8,9,10,11,12};
p = b;
变量p和b的内存局跟从内存角度理解指针和数组(一)中是一样的,再次列出:
b
0x00001000 0x0000B000 0x0000B000 1
0x0000B008 2
0x0000B010 3
0x0000B018 4
p 0x0000B020 5
0x00002000 0x0000B000 0x0000B028 6
由前面得出的结论,那么:
[cpp]
*p == 1
事与愿违,通过打印:
[cpp]
printf("%d, %d \n", p, *p);
[cpp]
273bf270, 273bf270
*p和p居然一样(是首地址)并且还不等于1,跟前面得出的结论相左啊!!
整理一下:
在从内存角度理解指针和数组(一)中,将数组名赋值给指针进行了类型强制转换,否则编译器会产生警告,但不会影响结果。如下所示:
[cpp]
long int b[3][4] = {1,2,3,4,5,6,7,8,9,10,11,12};
long int **p;
p = (long int **)b; //去掉(long int **)类型强制转换,会产生类型不兼容的警告,但不会影响结果。
而:
[cpp]
long int (*p)[4] = NULL; //定义一个行指针,一行有4个long int类型的元素。
long int b[3][4]= {1,2,3,4,5,6,7,8,9,10,11,12};
p = b;
却能顺利地通过编译。由此可知这两个肯定不一样。
2,多级指针和行指针的共性
我们还是可以这样理解:
[cpp]
long int **p;
//*p 是一个long int *类型的值,是单值;
long int (*p)[4];
//*p是一个long int [4]类型,它是一个元素个数为4的一维数组,不是单值;
*p的类型就是将类型申明去掉*p后剩下的部分。如:long int **p,*p的类型就为long int *型的单值,而long int (*p)[4]中,*p类型就为long int [4]的数组。
既然是一个一维数组,打印一个一维数组就只能打印它的首地址了,而且p++后地址的偏移量为4*sizeof(long int)。
[cpp]
void func3(void){
int i;
long int (*p)[4] = NULL;
long int a[3][4] = {1,2,3,4,\
5,6,7,8,\
9,10,11,12};
p = a;
for(i=0;i<3;i++,p++){
printf("%d ",**p);
}
printf("\n");
}
[cpp]
1 5 9
所以要正确地操作指针还得看指针的类型。
3,页指针和三维数组
[cpp]
void func4(void){
int i;
long int (*p)[3][4] = NULL;
long int a[2][3][4] = {{1,2,3,4, \
5,6,7,8, \
9,10,11,12},{21,22,23,24, \
25,26,27,28, \
29,30,31,32
} \
};
p = a;
for(i=0;i<3;i++,p++){
printf("%d ",***p);
}
printf("\n");
}
[cpp]
1 21
4,像使用数组变量一样使用指针变量来遍历数组
[cpp]
void func5(void){
int i,j,z;
long int (*p)[3][4] = NULL;
long int a[2][3][4] = {\
{1,2,3,4, \
5,6,7,8, \
9,10,11,12}, \
{21,22,23,24, \
25,26,27,28, \
29,30,31,32} \
};
p = a;
for(i=0;i<2;i++){
for(j=0;j<3;j++){
for(z=0;z<4;z++)
printf("%d ",p[i][j][z]);
printf("\n");
}
printf("\n\n");
}
printf("\n");
}
[cpp]
1 2 3 4
5 6 7 8
9 10 11 12
21 22 23 24
25 26 27 28
29 30 31 32
补充:软件开发 , C++ ,