C语言中指针引用二维数组元素的问题

假设a是一个3行4列的二维数组,请问为什么a[0]与*(a+0)是等价的,
我的理解是二维数组名a既然是该数组首元素的地址,那么(a+0)也是一个地址,“*(a+0)”就是指向“(a+0)”这个地址的内容(即首个元素值)。
a[0]与*(a+0),一个元素地址和一个元素内容又如何能等价~~
请懂C语言的人帮忙解答,指出我的思维误区。我都为这问题冥思苦想好几天了,每次拿起书本就把该节内容看一边,就是不理解这了。
回答完了,加50分,我总共就100分。

第1个回答  2019-07-19
对于a[i][j](二维数组的大小为n×m)而言,
首先要搞清楚行指针和列指针
行指针:&a[i]或者a+i指向行,&a[i]=&*(a+i)=a+i
列指针:a[i]或*(a+i)指向列,a[i]等价于*(a+i)
元素的引用方式有如下三种方式
1.通过地址引用二维元素
*(&a[i][j]),
*(a[i]+j),
*(*(a+i)+j),
*(a[0]+m*i+j)
*(&a[0][0]+m*i+j)
(*(a+i))[j]
2.建立一个指针数组引用二维元素
int *p[3],a[3][2],i,j;
for(i=0;i<3;i++)
p[i]=a[i];//p[i]用来存放地址,a[i]为列地址
等价如下
(1) *(p[i]+j) 与*(a[i]+j)对应
(2)*(*(p+i)+j) 与*(*(a+i)+j)对应
(3)(*(p+i))[j] *(p[i]+j) 与*(a[i]+j)对应
(4)p[i][j] 与a[i][j]对应
3.建立一个行指针引用二维数组元素
int a[3][2],(*p)[2];
p=a;
(1) *(p[i]+j) 与*(a[i]+j)对应
(2)*(*(p+i)+j) 与*(*(a+i)+j)对应
(3)(*(p+i))[j] 与(*(a+i))[j]对应
(4)p[i][j] 与a[i][j]对应
例题如下
1.
#include<stdio.h>
main()
{
int score[][4]={{60,70,80,90},{56,89,67,88},{34,78,90,66}};
int i,j;
printf("输入学生号:0-2");
scanf("%d",&i);
printf("the score of No.%d are:\n",i);
for(j=0;j<4;j++)
printf("%d\t",*(*(score+i)+j));//score+i为列指针,*(score+i)为行指针
printf("\n");
}
2.
#include<stdio.h>
main()
{
int a[3][4]={1,3,5,7,9,11,13,15,17,19,21,23};
int *p;
for(p=a[0];p<a[0]+12;p++)//使p依次指向下一个元素,a[i]和*(a+i)是指向列的指针;&a[i]或a+i是指向行的指针
{
if((p-a[0])%4==0)printf("\n");
printf("%4d",*p);//输出p指向的数组元素的值
}
printf("\n");
}
3
#include<stdio.h>
main()
{
int score[][4]={{60,70,80,90},{56,89,67,88},{34,78,90,66}};
int i,j;
printf("输入学生号:0-2");
scanf("%d",&i);
printf("the score of No.%d are:\n",i);
for(j=0;j<4;j++)
printf("%d\t",*(score[i]+j));
printf("\n");
}
4
#include<stdio.h>
main()
{
int score[][4]={{60,70,80,90},{56,89,67,88},{34,78,90,66}};
int i,j,*p;
printf("输入学生号:");
scanf("%d",&i);
printf("the score of No.%d are:\n",i);
for(p=score[i];p<score[i]+4;p++)
printf("%d\t",*p);//p+i指向第i行,*(p+i)指向第i行0列元素*(p+i)+j指向第i行j列元素,是列地址
printf("\n");
}
5.
#include<stdio.h>
main()
{
int score[][4]={{60,70,80,90},{56,89,67,88},{34,78,90,66}};
int i,j,*p;
printf("输入学生号:");
scanf("%d",&i);
printf("the score of No.%d are:\n",i);
for(p=score[i],j=0;j<4;j++)
printf("%d\t",*(p+j));
printf("\n");
}
6
#include<stdio.h>
main()
{
int score[][4]={{60,70,80,90},{56,89,67,88},{34,78,90,66}};
int i,j,(*p)[4];//指针变量p指向包括4个整型元素的一维数组;
p=score;//p指向二维数组0行元素,p+1所指向的元素是p所指向元素的下一行元素;
printf("输入学生号:0-2");
scanf("%d",&i);
printf("the score of No.%d are:\n",i);
for(j=0;j<4;j++)
printf("%d\t",*(*(p+i)+j));//p+i指向第i行,p是行指针,*(p+i)指向第i行0列元素,是列指针。*(p+i)+j指向第i行j列元素,是一个元素的地址
printf("\n");
}
第2个回答  2020-04-09
(a+0)是地址没错
“*(a+0)”就是指向“(a+0)”这个地址的内容(即首个元素值)这句话也没错
因为a这个地址中放的也还是一个地址
======举个例子======
例如:
a[3][3]
=
{
1
,
2
,
3
4
,
5
,
6
7
,
8
,
9
};
1的地址就是a[0],
(a[0]是a[0][0],a[0][1],a[0][2]中第一个数据a[0][0]的地址,下同理)
4的地址就是a[1],
7的地址就是a[2]。
然后你再把这个1、4、7组成的a[0],a[1],a[2]看做一个一维数组
那么a(也可以说是a+0)表示的就是第一个数a[0]的地址。
所以*(a+0)就是地址a中所存放的数值(即a[0]),只不过这个数值是个地址的编号罢了~
因为地址也是一串数字啊~
你可以就用这个a[3][3]写段代码试试~
输出
*(
*(a+1)
+
2
)
看看是不是等于6~
第3个回答  2010-03-25
占座听课
第4个回答  2010-03-25
在C语言中,定义数组后,编译器在编译的时候会为其分配一个连续的存储单元。二维数组同样如此,在C的编译器中,二维数组的单元是按行存放,即先存第一行,接着存第二行,依次类推。二维数组的整个存储区域和一维数组是一样的,二维数组也是按照一维数组的存储方式进行存储。

C语言规定,对于二维数组a[m][n],a是其首地址,a=a+0;a[0]是第一个元素的首地址,也是第一行的首地址,a[0]=a+0=a。

如果数组a是一维数组,那么*a可以代表数组的第一个元素,但是如果数组a是二维数组,由于a可以表示为二维数组的首地址,或者第0行的首地址,或者第0行第0个元素的地址,因此*a=*(a+0),表示的是第0行的地址。
而a[0]它在二维数组中表示的不是一个元素,而是一个行地址,即第0行元素的首地址,因此a[0]和*(a+0)是等价的。

如果要用*号表示二维数组的元素,那么可以这样表示:*(*(a+i)+j)
其中,*a表示第0行的首地址,因此*(a+i)可以表示第i行的首地址,j是偏移量,表示第几列,因此*(a+i)+j就可以表示第i行第j列的地址,在这个地址前面加个*,就可以表示这个地址的内容了,如:*(*(a+i)+j)表示第i行第j列的内容。

求c语言指针方式引用二维数组问题
a[0]代表第一组首元素地址,当然,a[0]也指向数组首元素的地址,a[0]=&a[0][0];a是对a取值,它取出的是a[0],当然=&a[0][0];&a[0]指a[0]的地址,还是它自己,所以&a[0]=&a[0][0]。所以,第一行个打印语句输出的5个内容都是一样的,所以,输出5个19ff0c。是a[0][0...

C语言中二维数组的指针问题
假如:p=a 这是使指针p指向数组a的首行,当你输出*p这个值的时候,它输出的值是a[0][0]这个元素的值,但是当你执行p+1的时候,那么p就会指向数组a的序号为1的行,即指向了a[1][0]这个元素所在的行了。p始终指向数组a的行,而不指向列。虽然p=a[0] p=&a[0][0] p=a 这三个语...

C语言指针问题
由于二维数组的逻辑结构是一维空间,存储结构是二维空间,因此可以分别按照存储结构和逻辑结构定义指向二维数组的指针.二维数组是按行优先的规律转换为一维线性存放在内存中的,因此,可以通过指针访问二维数组中的元素。如果有:int a[M][N];则将二维数组中的元素a[i][j]转换为一维线性地址的一般公式是:...

C语言函数调用二维数组,指针问题
并且使用p时不能用下标,p[2][3]是错误的,因为不知道p指向的int*型的长度,无法编译成*(p+2*10+3)必须自己写成*(p+2*10+3)来调用 假如定义成 deal(int (*p)[10])就不一样了,编译器就能知道p是一个指向长度为10的数组的指针 那么p[2][3]就能编译成*(p+2*10+3)了 总之,C语言...

C语言程序设计中"二维数组中元素指针的表示"的例题,求详解
二维数组和指针 ⑴ 用指针表示二维数组元素。要用指针处理二维数组,首先要解决从存储的角度对二维数组的认识问题。一个二维数组在计算机中存储时,是按行存储的,即先存储第一行的元素,再存储第二行的元素。当把每一行看作一个整体,即作为一个大的数组元素时,原来的二维数组也就变成一个一维数组了...

关于C语言中数组元素的引用问题
A:int pp;表示pp所指的是一个二维数组,所以它的引用可以这样用pp[][]的形式;D:因为p[i]=&a[i*4];有p[0]=&a[0],所以*(p+2),即p[2],指的是a[8];(*(p+2)+2)指的就是a[10];p[0]-> a[0]a[1]a[2]a[3]p[1]-> a[4]a[5]a[6]a[7]p[2]-> a[8]a[9]a...

使用列指针输出二维数组元素
在C语言中,数组是不同于普通变量的,实际上C定义的数组是指向该数组第一个元素的指针。这是第一个概念,即数组名就是指针,所以可以直接当做指针来用,例如:对于一个数组a[],要取其第三个元素的值,既可以用a[2],也可以用a+2来访问。对于一个二维数组,如果用下标变量来表示的话,则可以...

c语言里面怎么用指针表示二维字符数组
二维数组就是数组的数组,二维数组即数组的元素是一维数组的数组。那么我们要用指针指向二维数组,就是要定义一个指向数组的指针了。例如:char str[3][10]; \/\/定义了一个char型的二维数组 char (*pstr)[10]; \/\/定义了一个指向char型的数组指针 pstr=str; \/\/指针指向二维数组str 下面用pstr...

c语言中,关于指针int(*p)[4]和int*p指向二维数组a[3][4]初始化的问题...
p指向一个N列二维数组的首地址 p自增1,p指向下一“行”一维数组的首地址 因为p是一个二级指针。所以索引其指向的数据内容需要取二次内容,格式及解释如下:格式:*(*(p+行)+列)解释:其实很好理解,因为p作为二级指针,p++代表的仅仅是行号+1所以格式中*(p+行)就取到了所在行首地址指针(...

C语言中二维数组行指针是什么
对于二维数组array[4][3],与int* p 。二维数组名array 不能直接赋值给p。原因前面已讲过,两只的对象性质不同。 在C语言中,可以通过定义一个行数组指针,使得这个指针与二维数组名具有同样的性质,实现它们之间可以直接赋值。行数组指针定义如下:int (*p)[3]; 它表示,数组 *p 具有三个int类型...

相似回答