关于指针的问题,这段话怎么看不懂呢?

tolixiaohui 2005-01-19 10:40:51
C语言里,数组名是被看作指针来使用的,
一维数组是指针,二维数组是指向指针的指针,三
维是.........
真的是这样的吗??

看下面的例子:

void show (int * * info,int x,int y)//打印一个x*y的数组的内容
{
int i,j;
for (i=0;i<x;i++) {
for (j=0;j<y;j++) {
printf ("%d ",info[i][j]);
}
printf ("\n");
}
}

在进行如下调用之后,你的系统有崩溃的可能!

void Function (void)
{
int as [10][10];
:
:
show (as,10,10);
:
:
}
为什么?在c中,二维数组虽然是定义为指向指针的指针,但是
实际上被指向的指针是不存在的,只是在 执行as [n]时返回一个
指针罢了,as所指的不过是存放数组内容的地址!!

????????????
为什么系统有崩溃的可能?
...全文
258 14 打赏 收藏 转发到动态 举报
写回复
用AI写文章
14 条回复
切换为时间正序
请发表友善的回复…
发表回复
well2008202 2005-01-19
  • 打赏
  • 举报
回复
我想应该是吧
我们老师说过的
我也不是太理解的我是刚学C的
二维是把行数看成一个一维的数组的,
后面在加上一个篇移量就是二维了
Meteorlet 2005-01-19
  • 打赏
  • 举报
回复
上面准确的说不是 p + i + j,而是*(*(p+i) + j) 二维数组是 *(*(p+i *10) + j)
Meteorlet 2005-01-19
  • 打赏
  • 举报
回复
二维数组就是指针的指针,但是指针的指针不能作为二维数组的指针操作,
因为参数传过去以后就只有一个指针的指针值,它并不知道它这个指针的指针指向多大的
一块内存,二维数组是已知的:10*10,所以这么测试一下就知道了:
char szData[10][10] = {0};
char **p = (char **)szData; // 假设szData的地址是0x0012f6a4
p ++; // p++ 就是0x0012f6a8,移动4个字节(指针是4个字节的)
char* p1 = (char *)szData[1];//而szData++就是szData[1] 地址为0x0012f6ae,移动了10个字节

因此函数传递的时候
func(char** p) 通过二维数组转换过来的指针的指针,这时候p++是无法知道移动多大的数组长度的
只能是移动四个字节,所以p[i][j] 只能等价于(p + i + j),如果是二维数组就是(p + i * 10 + j)
所以函数参数传递申明要指定这个大小:
func(char p[][10])或者func(char (*p)[10])
寻开心 2005-01-19
  • 打赏
  • 举报
回复
int ** 和 int a[][]是不等价的
在c语言的实现当中int a[a][b] 实际上还是等价于 int * p的
把你的show函数里面的使用方式调整一下,改成
printf("**", as[i*x+y])
即可

因为二维数组实际上还是一维的存储的

int * * a如同前面几位的说明
kobefly 2005-01-19
  • 打赏
  • 举报
回复
不会把
我的网络这么慢
kobefly 2005-01-19
  • 打赏
  • 举报
回复
2级指针跟2维数组是不同的拉

相互转换是很危险的,而且在c++会是error的
c给出warning

指针是间接寻址
数组的数组名就是数组的首地址,属于直接寻址
指针是通指针的值,找到地址,然后再找到值的

lovefly_fanny 2005-01-19
  • 打赏
  • 举报
回复
二维数组实际上是按照一维的顺序排列的啊
a[10][10]和a[100]没什么差别的,
这里只是在函数调用的时候编译器
是这么理解与处理的。···指针数组根本不存在
同样我也觉得没什么问题,系统可能崩溃?
从何说起呢~~~

liweiswin 2005-01-19
  • 打赏
  • 举报
回复
2.2. 指向二维数组的指针
2.2.1. 二维数组元素的地址
为了说明问题, 我们定义以下二维数组:
int a[3][4]={{0,1,2,3}, {4,5,6,7}, {8,9,10,11}};
a为二维数组名, 此数组有3行4列, 共12个元素。但也可这样来理解, 数组a由三
个元素组成: a[0], a[1], a[2]。而它匀中每个元素又是一个一维数组, 且都含
有4个元素 (相当于4列), 例如, a[0]所代表的一维数组所包含的 4 个元素为
a[0][0], a[0][1], a[0][2], a[0][3]。如图5.所示:
┏━━━━┓ ┏━┳━┳━┳━┓
a─→ ┃ a[0] ┃─→┃0 ┃1 ┃2 ┃3 ┃
┣━━━━┫ ┣━╋━╋━╋━┫
┃ a[1] ┃─→┃4 ┃5 ┃6 ┃7 ┃
┣━━━━┫ ┣━╋━╋━╋━┫
┃ a[2] ┃─→┃8 ┃9 ┃10┃11┃
┗━━━━┛ ┗━┻━┻━┻━┛
图5.
但从二维数组的角度来看, a代表二维数组的首地址, 当然也可看成是二维
数组第0行的首地址。a+1就代表第1行的首地址, a+2就代表第2行的首地址。如
果此二维数组的首地址为1000, 由于第0行有4个整型元素, 所以a+1为1008, a+2
也就为1016。如图6.所示
a[3][4]
a ┏━┳━┳━┳━┓
(1000)─→┃0 ┃1 ┃2 ┃3 ┃
a+1 ┣━╋━╋━╋━┫
(1008)─→┃4 ┃5 ┃6 ┃7 ┃
a+2 ┣━╋━╋━╋━┫
(1016)─→┃8 ┃9 ┃10┃11┃
┗━┻━┻━┻━┛
图6.
既然我们把a[0], a[1], a[2]看成是一维数组名, 可以认为它们分别代表它
们所对应的数组的首地址, 也就是讲, a[0]代表第 0 行中第 0 列元素的地址,
即&a[0][0], a[1]是第1行中第0列元素的地址, 即&a[1][0], 根据地址运算规则,
a[0]+1即代表第0行第1列元素的地址, 即&a[0][1], 一般而言, a[i]+j即代表第
i行第j列元素的地址, 即&a[i][j]。
另外, 在二维数组中, 我们还可用指针的形式来表示各元素的地址。如前所
述, a[0]与*(a+0)等价, a[1]与*(a+1)等价, 因此a[i]+j就与*(a+i)+j等价, 它
表示数组元素a[i][j]的地址。
因此, 二维数组元素a[i][j]可表示成*(a[i]+j)或*(*(a+i)+j), 它们都与
a[i][j]等价, 或者还可写成(*(a+i))[j]。
另外, 要补充说明一下, 如果你编写一个程序输出打印a和*a, 你可发现它
们的值是相同的, 这是为什么呢? 我们可这样来理解: 首先, 为了说明问题, 我
们把二维数组人为地看成由三个数组元素a[0], a[1], a[2]组成, 将a[0], a[1],
a[2]看成是数组名它们又分别是由4个元素组成的一维数组。因此, a表示数组第
0行的地址, 而*a即为a[0], 它是数组名, 当然还是地址, 它就是数组第0 行第0
列元素的地址。

CMyMfc 2005-01-19
  • 打赏
  • 举报
回复
你的理解是对的, 不过不要混淆地址和指针这两个概念

系统崩溃不是指你的操作系统崩溃, 是指你的程序崩溃

因为函数里面取info[i][i]的值时, 先取得info[i],这样就访问了不可访问的内存


void show (int info[][10],int x) // 这样就对了
liweiswin 2005-01-19
  • 打赏
  • 举报
回复
事实上as是该二维数组存放内存空间的首地址
flamingors 2005-01-19
  • 打赏
  • 举报
回复
我曾经也为这个问题困惑过很久。楼主的二维数组是指向指针的指针只是入门级的理解。准确点说,二维数组名的类型是“指向数组的指针”,一般的一维指针指向的是具体数据类型的指针。类型不匹配问题是学C时很容易犯的错误。另外双重指针好象不是这么用的。它确实可以用来访问二维数组,但是方法有问题。C的语句是有一定规则的,不是理解了意义就可以直接应用的。让我记得很深的一句话就是:理论跟实践是有差别的。
kent5566 2005-01-19
  • 打赏
  • 举报
回复
mark
grayfoxdie 2005-01-19
  • 打赏
  • 举报
回复
楼上的:
因为函数里面取info[i][i]的值时, 先取得info[i],这样就访问了不可访问的内存
void show (int info[][10],int x) // 这样就对了
有人能解释一下吗,这是什么意思,我是菜鸟,无知者无畏,再傻的问题我都敢问,请高手说说看。
xuelong_zl 2005-01-19
  • 打赏
  • 举报
回复
对于一维数组int a[n]对应的类型为int *P
对于二维数组int a[n][m]对应的类型为int (*p)[m],而不是int **p

这是应该注意的地方

69,381

社区成员

发帖
与我相关
我的任务
社区描述
C语言相关问题讨论
社区管理员
  • C语言
  • 花神庙码农
  • 架构师李肯
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧