学习 C 语言的问题,有个问题怎么想都想不通

2015-11-03 21:45:57 +08:00
 ru20150601
一个 2 维的指针, int array [4] [2],教材中说, array 的值和 array[0]的值是一样的,是同一个地址值。这个我不能理解。* array 得到的是一个内存地址值 long int ,而* array[0]则是一个 int 。怎么可能会相同呢?

我本来以为这个是教材的错误,但是这个教材言之凿凿,甚至还特别举例,输出了这两个值的地址证明是相同的。有人能解答下吗?
3936 次点击
所在节点    程序员
35 条回复
ProjectAmber
2015-11-03 21:51:15 +08:00
虽然内容一样,但是类型不同啊。就和 int 和 float 二进制一样,表示的数可不一样。
zackkson1991
2015-11-03 21:52:47 +08:00
一楼说的正确。这时候已经类型是不一样了。也就是每次你访问的时候,抓取内存的方式不一样了。
colatin
2015-11-03 22:01:10 +08:00
f(x)=x^2
f(x)=x^3
即使 x 的值相同, f(x)的值也会不同。不知道这个类比是否恰当。
aholic
2015-11-03 22:11:36 +08:00
int i = 1;
int *p = (int*)(i);
i 和 p 的“值”也是一样的。
但是作为 int 来解读,它就是 1
作为 int*来解读,他就是一个指向 0x1 的指针
feiyuanqiu
2015-11-03 22:14:18 +08:00
*array 得到的是 array[0][0] 的地址
*array[0] 得到的是 array[0][0] 的值
ru20150601
2015-11-03 22:15:16 +08:00
@ProjectAmber
@zackkson1991
@colatin
不是,三位,可能我表达的不清楚。,是这样的,这个例子当中呢, 他们输出的是指针的值。我看的英文版的也不知道中文术语是不是这样说的,我直接说代码吧:
printf("array =%p array[0]= %p",array,array[0] );

书中的例子,这两个输出出来是一样的。这完全讲不通啊

如果 array==array[0]

那么 *array == *array [0]

array[0][0]=13 //而 *array [0] ==array [0][0]

那么 array==13 ?
=====================================分割线============================

我的意思是, array[0][0]是一个变量, array[0]是指向变量的指针, array 是指针的指针,这两个怎么可能相等?
ru20150601
2015-11-03 22:17:33 +08:00
@feiyuanqiu

对呀,这就是我所理解的啊。这两个值不可能相等啊。书中却是一样的。
c742435
2015-11-03 22:21:43 +08:00
指针的值是其指向的内存地址,都是指向同一个内存地址,为啥不等?
谁跟你说 array 是指针的指针。
patrickstar
2015-11-03 22:28:45 +08:00
你还是找本靠谱的书看看,看看 C 指针这本书,好像是这个名字
array 是一个 int**,而 array[0]是一个 int*
patrickstar
2015-11-03 22:36:36 +08:00
你看看 "Pointers on C" 这本书,中文名叫啥子忘了!
array 和 array[0]的指针值确实一样,都等于 &array[0][0],即第一个元素的地址,但是*array 和 *array[0]是两个概念了,*array 任然是一个指针,这时候任然=&array[0][0], 而*array[0]= array[0][0]
patrickstar
2015-11-03 22:44:18 +08:00
运行一下子程序就明白了:
#include <stdio.h>
#include <stdlib.h>

int main(int argc,char* argv[])
{
int a[4][2];
for(int *p = a[0],i = 0; i < 8; i++)
*(p+i) = (i+1)*(i+1);

printf("array = %p\n",a); // = &a[0][0]
printf("array[0] = %p\n",a[0]); // = &a[0][0]

printf("*array = %p\n",*a); //*a is a pointer=&a[0][0]
printf("*array[0] = %d\n",*a[0]); //*a[0] is int

return EXIT_SUCCESS;
}
harry890829
2015-11-03 22:45:54 +08:00
这是一个二维指针,所以 array[0]其实也是指针啊……
如果 char sz[8]写成 sz ,你知道是指 sz 数组的第一个元素的地址
那么 int array[4][2]写成, array[0]你也应该知道这是一个指针啊,
array 和 array[0]这两个都是指向了这个二维数组的第一个元素的地址
ru20150601
2015-11-03 22:46:52 +08:00
@patrickstar
好吧,我刚刚也实际运行代码测试过了,确认不是教材错了我就放心了。正在看的是 c primer plus ,这个例子也是这本书里的,这本书写的很细,猛的出来一个这么反直觉的东西,竟然没有解释,一句话就带过了,把我害苦了。
htfy96
2015-11-03 22:53:11 +08:00
@patrickstar
@harry890829
@ru20150601
array[0]并不是一个指针,而就是一个叫做 int[2]的类型
printf("%lu", sizeof(a[0]));
之所以常常能把 a[0]看作一个指针用,是因为这里发生了隐性的 decay
canautumn
2015-11-03 23:00:53 +08:00
C 语言就是这么规定的,记住就行了。可以看看『征服 C 指针』,记得里边讲 C 语言指针的设计只是尽量合理(尽量符合直觉),但有些和直觉矛盾之处是很难解决的,只好记住。
halfcoder
2015-11-03 23:06:20 +08:00
楼主从 C 数组的内存模型上来思考就容易理解了。 int array[4][2]作为一个总共拥有 8 个 int 元素的数组,不管是 array 也好还是 array[0]也罢,都是指向的第一个元素,其地址当然是一致的。至于类型不一样,那只是外部表示而已,即使 array 变成更高维的数组,其类型发生巨大变化,结论也是一致的。
Zhang
2015-11-03 23:19:03 +08:00
c 语言规定的,数组的名称就是第 0 个元素的地址!
CRVV
2015-11-03 23:23:35 +08:00
array 是一个 2 维数组, array[0] 是一个 1 维数组,类型都不一样,值怎么个一样法?

但是 C/C++里面的数组比较特殊,数组类型的变量会被编译器转成指向首元素的指针
(注一下,这个问题上,有些人认为数组名就是一个指针(而不是被转成指针),比如楼上的回帖,也包括楼主的教材)

所以下面是我认为的正确的理解方式(也就是 "C++ Primer" 的内容),要搞懂这个问题需要了解两件事:
1 、在你使用数组名这个变量时,它通常被转换成了首元素的指针,所以 array 被转成了 &array[0]
2 、数组只是一个连续的内存区域,用来存数组里的元素。数组的内存地址就是数组首元素的内存地址(但是,作为两个指针,它们的类型不同)
用 printf 输出来的是内存地址,所以
array -> &array[0] -> &array[0][0], array[0] -> &array[0][0]
三个箭头分别是,数组被转成首元素地址,数组的地址和数组首元素的地址相等,数组被转成首元素地址
结论是, 如果你用 printf 输出 array 和 array[0],输出的东西是相等的,但这两个变量的类型不同,不应该拿来比较

以下和回答无关
“教材中说, array 的值和 array[0]的值是一样的”
“* array 得到的是一个内存地址值 long int ”
看到这两行内容,我觉得你这本教材应该扔掉了
ru20150601
2015-11-03 23:42:49 +08:00
@CRVV 谢谢长文答复。我看的是 c primer plus ,这两句话不是原文,是我根据自己的理解描述的。因为不知道有这个背景。
CRVV
2015-11-03 23:57:47 +08:00
@ru20150601
http://www.v2ex.com/t/233379
从这个帖子来看,这书的作者不会使用指针

这是一个专为移动设备优化的页面(即为了让你能够在 Google 搜索结果里秒开这个页面),如果你希望参与 V2EX 社区的讨论,你可以继续到 V2EX 上打开本讨论主题的完整版本。

https://www.v2ex.com/t/233381

V2EX 是创意工作者们的社区,是一个分享自己正在做的有趣事物、交流想法,可以遇见新朋友甚至新机会的地方。

V2EX is a community of developers, designers and creative people.

© 2021 V2EX