从内存角度理解指针和数组(二)

1,有一种指针叫行指针

所谓行指针,说明指针类型是行,指针变量存的是某一行的首地址,该行也是一片连续的内存区。
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   
0x000010000x0000B000 0x0000B0001
   0x0000B0082
   0x0000B0103
   0x0000B0184
 p 0x0000B0205
0x000020000x0000B000 0x0000B0286
     
由前面得出的结论,那么:
*p == 1
事与愿违,通过打印:
printf("%d, %d \n", p, *p);
273bf270, 273bf270
*p和p居然一样(是首地址)并且还不等于1,跟前面得出的结论相左啊!! 

整理一下:
从内存角度理解指针和数组(一)中,将数组名赋值给指针进行了类型强制转换,否则编译器会产生警告,但不会影响结果。如下所示:
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 **)类型强制转换,会产生类型不兼容的警告,但不会影响结果。

而:
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,多级指针和行指针的共性

我们还是可以这样理解:
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)。
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");
}
1 5 9 
所以要正确地操作指针还得看指针的类型。

3,页指针和三维数组

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");
}
1 21

4,像使用数组变量一样使用指针变量来遍历数组

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");
}
1 2 3 4 
5 6 7 8 
9 10 11 12 


21 22 23 24 
25 26 27 28 
29 30 31 32 






  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值