问答1 问答5 问答50 问答500 问答1000
网友互助专业问答平台

c语言中二维数组的指针如何表示27

提问网友 发布时间:2024-03-07 10:16
声明:本网页内容为用户发布,旨在传播知识,若有侵权等问题请及时与本网联系,我们将在第一时间删除处理。
E-MAIL:1656858193@qq.com
4个回答
热心网友 回答时间:2024-03-29 11:12
比如定义一个int型的二维数组,如下:
int **p;
或者
int p[MAX_ROW][MAX_LINE];
不同的是前者定义了一个int型二维数组的指针,编写器知道该指针的移动方式以int为单位,但此时该指针为NULL,即没有与内存中的物理单元进行对应。使用指针前需要用malloc()为该指针分配一段内存空间,内存空间的大小在malloc()的参数中指定,系统会为该指针分配一段空闲内存供该指针使用。或者将你的程序中其他int类型的指针赋值给该指针使其映射到内存物理单元。在程序结束或不在需要使用该指针时需要使用free()将该指针所映射内存释放。
后者在定义时为该指针分配了MAX_ROW*MAX_LINE个int大小的空间映射到内存,之后就可以直接使用了。
热心网友 回答时间:2024-03-29 11:10
小的示例程序:
#include <cstdio>
#include <cstring>
using namespace std;

int a[3][4];

int main(){
memset(a, -1, sizeof(a));
int i;
for( i = 0; i < 3; i++){
printf("&a[i][0] = %d\n", &a[i][0]);
printf("a + i = %d; *(a + i) = %d;\n", a + i, *( a + i));
printf("a[i] = %d; &a[i] = %d;\n", a[i], &a[i]);
printf("\n");
}
}

这段示例程序在我本地上运行的结果为:
&a[i][0] = 4214816
a + i = 4214816; *(a + i) = 4214816;
a[i] = 4214816; &a[i] = 4214816;

&a[i][0] = 4214832
a + i = 4214832; *(a + i) = 4214832;
a[i] = 4214832; &a[i] = 4214832;

&a[i][0] = 4214848
a + i = 4214848; *(a + i) = 4214848;
a[i] = 4214848; &a[i] = 4214848;

我想看到这个运行结果,你已经有所了解了,下面我再详细说一下:
指针量a作为一个二维数组的指针量,其本质是一个“指向指针的指针”(为了方便,下面称其为双重指针),或者你可以理解为a为int**类型的指针量。当a做加减运算时,得到的结果仍然是一个“双重指针”,即a + i是一个双重指针,它是一个指向了原数组第i行的起始位置的双重指针。
而*(a + i)原来的双重指针解引用后得到的一个指针变量,他是一个指向了原数组第i行的起始位置的“单重指针”。
可以看出,a + i和*(a + i)尽管数据类型不同(前者为双重指针,后者为单重指针),但是他们指向同一块内存地址,因此作为指针量,他们的值是相等的。注意,仅仅是说,他们的值在数学上是相等的,并非说“他们是等价的”。
你的第二个问题亦是同理:
首先,[]作为C语言的操作符,本身即具有“解引用”的语义。明白的说,就是a[i]与*(a + i)是完全等价的,而&a[i]即等价于a + i。由于易知a + i和*(a + i)在数值上相当,那么进行等价带花可以知道,&a[i]和a[i]在数值上相等。当然,此处仍非等价关系。
至于指向行的指针,所指的就是指向行首位置的指针量。
至于你的最后一个问题,正如我刚才一直强调的那样,等号两端仅仅是数值上的相等,而非等价关系,因此无法按照你所设想的方式进行归纳推导。
另外,虚机团上产品团购,超级便宜
热心网友 回答时间:2024-03-29 11:14
给你一个例子吧
#include <stdlib.h>
int ** array = malloc( N * sizeof(int *) ); //二维数组指针
array[0] = malloc( M * sizeof(int) );
for (int k=1;k<N;k++)
array[k] = array[0]+M*k; //可以当数组用
热心网友 回答时间:2024-03-29 11:14
二维数组和指针

⑴ 用指针表示二维数组元素。

要用指针处理二维数组,首先要解决从存储的角度对二维数组的认识问题。
一个二维数组在计算机中存储时,是按行存储的,即先存储第一行的元素,再存储第二行的元素。
当把每一行看作一个整体,即作为一个大的数组元素时,原来的二维数组也就变成一个一维数组了。而每个大数组元素对应原来二维数组中的一行,称为行数组元素,显然每个行数组元素都是一个一维数组。
下面讨论二维数组元素和指针之间的对应关系,清楚了二者之间的关系,就能用指针处理二维数组了。
设p是指向二维数组a[M][N]的指针变量,若有:p=a[0]; 则p+j将指向a[0]数组中的元素a[0][j]。
由于a[0]、a[1]┅a[M-1]等各个行数组依次连续存储,则对于a数组中的任一元素a[i][j],指针的一般形式如下:p+i*N+j用"*"运算符表示为:*( p+i*N+j)同样,a[i][j]也可使用指针下标法表示,如下:p[i*N+j]

例如,有如下定义:
int a[3][4]={{10,20,30,40,},{50,60,70,80},{90,91,92,93}};
则数组a有3个元素,分别为a[0]、a[1]、a[2]。而每个元素都是一个一维数组,各包含4个元素,如a[1]的4个元素是a[1][0]、a[1][1]、a[1]2]、a[1][3]。
若有:
int *p=a[0];
则数组a的元素a[1][2]对应的指针为:p+1*4+2
元素a[1][2]也就可以表示为:*( p+1*4+2)
用下标表示法,a[1][2]表示为:p[1*4+2]
特别说明:
对上述二维数组a,虽然a[0]、a都是数组首地址,但二者指向的对象不同。

a[0]是一维数组的名字,它指向的是一维数组a[0]的首元素a[0][0],对其进行“*”运算,得到的是一维数组元素a[0][0]的值,即*a[0]与a[0][0]是同一个值。
而a是一个二维数组的名字,它指向的是二维数组a的首元素a[0],对a进行“*”运算,得到的是一维数组a[0]的首地址,即*a与a[0]是同一个值。它的指针移动单位是“行”,所以a+i指向的是第i个行数组,即指向a[i]。
当用int *p;定义指针p时,p的指向是一个int型数据,而不是一个地址,因此,用a[0]对p赋值是正确的,而用a对p赋值是错误的。这一点请务必注意。

示例:

#include <stdio.h>

int main()
{

int a[3][4]={{3,17,8,11},{66,7,8,19},{12,88,7,16}};
int *p=a[0],max,i,j,row,col;
max=a[0][0];

row=col=0;

for(i=0;i<3;i++)
for(j=0;j<4;j++)
if(*(p+i*4+j)>max)
{
max=*(p+i*4+j);
row=i;
col=j;
}
printf("a[%d][%d]=%d\n",row,col,max);
printf("address of a is:%x\n", (unsigned int)a);
printf("address of a[0] is:%x\n", (unsigned int)a[0]);
printf("address of a[0][0] is:%x\n\n", (unsigned int)&a[0][0]);
printf("address of (a+1) is:%x\n", (unsigned int)(a+1));
printf("address of (a[0]+1) is:%x\n", (unsigned int)(a[0]+1));
printf("address of (a[0][0]+1) is:%x\n", (unsigned int)(&a[0][0]+1));

return 0;
}

运行结果:

a[2][1]=88
address of a is:bfdc0368
address of a[0] is:bfdc0368
address of a[0][0] is:bfdc0368

address of (a+1) is:bfdc0378
address of (a[0]+1) is:bfdc036c
address of (a[0][0]+1) is:bfdc036c
从结果看出,a,a[0],a[0][0]是同一个地址,

⑵ 用二维数组名作地址表示数组元素。

另外,由上述说明,还可以得到二维数组元素的一种表示方法:
对于二维数组a,其a[0]数组由a指向,a[1]数组则由a+1指向,a[2]数组由a+2指向,以此类推。因此,*a与a[0]等价、*(a+1)与a[1]等价、*(a+2)与a[2]等价,┅,即对于a[i]数组,由*(a+i)指向。由此,对于数组元素a[i][j],用数组名a的表示形式为:*(*(a+i)+j)指向该元素的指针为:*(a+i)+j数组名虽然是数组的地址,但它和指向数组的指针变量不完全相同。指针变量的值可以改变,即它可以随时指向不同的数组或同类型变量,而数组名自它定义时起就确定下来,不能通过赋值的方式使该数组名指向另外一个数组。
示例:

求二维数组元素的最大值。

该问题只需对数组元素遍历,即可求解。因此,可以通过顺序移动数组指针的方法实现。
main()
{

int a[3][4]={{3,17,8,11},{66,7,8,19},{12,88,7,16}};
int *p,max;
for(p=a[0],max=*p;p<a[0]+12;p++)
if(*p>max)
max=*p;
printf("MAX=%d/n",max);

}
执行结果:
MAX=88
这个程序的主要算法都是在for语句中实现的:p是一个int型指针变量;p=a[0]是置数组的首元素地址为指针初值;max=*p将数组的首元素值a[0][0]作为最大值初值;p<a[0]+12是将指针的变化范围限制在12个元素的位置内;p++使得每比较一个元素后,指针后移一个元素位置。
示例:

求二维数组元素的最大值,并确定最大值元素所在的行和列。
本例较之上例有更进一步的要求,需要在比较的过程中,把较大值元素的位置记录下来,显然仅用上述指针移动方法是不行的,需要使用能提供行列数据的指针表示方法。
main()
{

int a[3][4]={{3,17,8,11},{66,7,8,19},{12,88,7,16}};
int *p=a[0],max,i,j,row,col;
max=a[0][0];

row=col=0;

for(i=0;i<3;i++)
for(j=0;j<4;j++)
if(*(p+i*4+j)>max)
{
max=*(p+i*4+j);
row=i;
col=j;
}
printf("a[%d][%d]=%d/n",row,col,max);

}
程序运行结果:
a[2][1]=88

⑶ 行数组指针

对于指针,不管有多复杂,按照以下原则进行分析:
从变量名处起,根据运算符优先级结合,一步一步分析。

在上面的说明中已经知道,二维数组名是指向行的,它不能对如下说明的指针变量p直接赋值:
int a[3][4]={{10,11,12,13},{20,21,22,23},{30,31,32,33}},*p;其原因就是p与a的对象性质不同,或者说二者不是同一级指针。C语言可以通过定义行数组指针的方法,使得一个指针变量与二维数组名具有相同的性质。

行数组指针的定义方法如下:
数据类型 (*指针变量名)[二维数组列数];

例如,对上述a数组,行数组指针定义如下:
int (*p)[4];它表示,数组*p有4个int型元素,分别为(*p)[0]、(*p)[1]、(*p)[2]、(*p)[3] ,亦即p指向的是有4个int型元素的一维数组,即p为行指针。
(按照指针的分析原则进行分析:p先与*结合,说明p是一个指针,然后与[]结合,说明指针指向的内容是含4个元素的数组,然后与int结合,说明数组中的元素为int类型。所以p是一个指向含4个int类型元素的数组的指针。)此时,可用如下方式对指针p赋值:p=a;为做对比,比较一下如下指针:int *p[4];
(按照指针的分析原则进行分析:p先与[]结合,说明p是一个数组,然后与*结合,说明数组的元素为指针,然后与int结合,说明指针指向的是int类型的变量。所以p是一个含4个元素的指向int类型变量的指针组成的数组。)

此外二维数组不可以用int**类型直接赋值访问

本文如未解决您的问题请添加抖音号:51dongshi(抖音搜索懂视),直接咨询即可。

异地能不能在福建省福清市农村申请建房,怎么申请,需什么手续 C语言如何利用指针接受二维数组实参1 c语言里面怎么用指针表示二维字符数组8 C语言怎么用指针代替二维数组66 C语言的指针表示动态二维数组怎么弄?2 C语言如何定义指针指向字符型二维数组22 C语言 怎么用指针输出一个二维数组的全部值33 ...以后在考职称的问题,是考中医师呢还是考主治医师? c语言中怎样实现对二维数组元素进行赋值并输出。179 儿媳不孝顺婆婆会影响到婆婆财产吗? 儿媳能继承公婆遗产吗比例是多少 丧偶儿媳没有赡养公婆有继承权吗 国家规定电信塔要离居民房多少米才安全129 国家规定移动基站铁塔安全距离是多少59 用护照去了一次香港,可以再去别的国家吗?4 请问持护照可以去香港吗?212 我有港澳通行证,但是没有香港的签注,持护照假飞第三国而在香港...2 砖砌体的质量要求包括什么? 草铵膦稀释倍数7 增强草甘膦的溶解度1 c语言里面怎么用指针表示二维字符数组5 C语言 怎么用指针输出一个二维数组的全部值52 c语言问题,用指针为一个二维数组赋值20 管理学作业啊,急! 案例二 东原公司的组织问题 东原公司是一家新兴企业... 交强险过期电子眼会报警吗?13 车险脱保后电子眼会不会拍?还有12123上车辆会不会显示异常...8 车辆脱审高速电子警察能否报警4 白云观能让师傅开光吗 车辆脱审了摄像头能拍到吗4 脱审车摄像头还能拍到吗 ...需要买公交票了,两个人的话在北京怎么买公交票比较方便 车保脱险几天开车出了一趟门,电子眼会拍吗?5 现在的电子眼能通过车牌判断车辆是否脱保?5 强制险脱保定陶电子眼能拍到吗? 脱保车辆摄像头每次都会被拍吗2 被电子眼拍了,可不可以过一段时间再去处理?38 ...报警之后,第二天派出所有警官给我打电话,让我不要把我的事和家里人... 电子眼能识别外市的脱审车辆吗8 电子狗 摄像头能辨别外省车辆脱审脱保 如果上路会不会引来交警...4 机动车辆被查封是否脱保?
Top