行指针和列指针的理解

指针与二维数组

int a[3][4]={1,3,5,7,9,11,13,15,17,19,21,23};

我们以为,二维数组的存储形式是:

但是,二维数组实际上是以一维数组为单位连续存储的。

这样,上述的二维数组就可以看成是“特殊的”一维数组了。

而数组名a是这个“特殊的”一维数组的名称,也就是首地址(常量地址),也就是第一个元素的地址。

也就是第一行的首地址,是指首行一整行,并不是指某个具体元素。

对于这种,我们称之为“行指针”。同理:a+0,a+1,a+2,都是行指针。


接下来,我们来放大观看首行,首行的元素分别是:a[0][0],a[0][1],a[0][2],a[0][3]。

将其看作一个独立的一维数组,那么 a[0]就是这个数组的名称,也就是这个数组的首地址。

也就是第一个元素的地址,也就是a[0]+0。a[0]和a[0]+0都是指具体的元素。

对于这种,我们称之为“列指针”


由上面的比较可以得出:

行指针:指向某一行,不指向具体的元素。

列指针:指向行中具体的元素。

也就是说,列指针只要在同一行,不管它们指向行中的哪个元素,它们的行地址都是在同一行的地址,所以它们的行地址都是一样的。

所以,&列指针--->行指针


相反地可以推出:

          *行指针---->列指针


对于元素a[1][2],其地址用列指针表示为a[1]+2,等价表示为*(a+1)+2,那么内容是*(*(a+1)+2)

那么如何声明行指针呢?

对于数组a[3][4],可以这样声明(并初始化)行指针: 

int (*ptr)[4]=a;
//注意行指针是一行中所有元素所共有的,所以应该等于列数

由上面可知:

行指针-->列指针:

a+i --> *(a+i) --> a[i] -->*a[i] ([]优先级大于*)

这里还要注意:

声明和初始化列指针时,要注意“*”如:

int *ptr=*a;//true
int *ptr=a; //error

下面是应用:

#include<stdio.h>
/**
三个学生修四门功课,求总平均分,输出第n个学生成绩
*/ 
void average(float *p, int n);
void search(float (*p)[4], int n);
int main()
{
	float score[3][4] = {{20,30,40,50},{25,35,45,55},{60,70,80,90}};
	average(*score,12);  //*score为列指针 
	search(score,2);	//score为行指针 
	return 0;
} 
void average(float *p, int n)
{
	float *p_end,sum=0,aver;
	p_end = p+n-1;
	for(;p<p_end;p++)
		sum=sum+(*p);
	aver=sum/n;
	printf("average=%5.2f\n",aver);
}
void search(float (*p)[4], int n)
{
	int i;
	printf("No.%d :\n",n);
	for(i=0;i<4;i++)
		printf("%5.2f ",*(*(p+n)+i));
}

本文稍有借鉴:https://blog.csdn.net/haussuden/article/details/5965304

以及:https://wenku.baidu.com/view/acf838ef856a561252d36fe3.html

有不足之处,欢迎指出。


猜你喜欢

转载自blog.csdn.net/DYD850804/article/details/80582519