一个关于C++数组的小问题

lumieresceau 2007-10-02 04:37:24
这是一个测试指向数组的指针数组的例子。是一本C++教程里的现成例题。pf是一个指针数组,每个元素分别存放不同数组的地址。代码如下:
#include<iostream.h>
void main()
{
double aa[2]={1.1,2.2},bb[2]={3.3,4.4},cc[2]={5.5,6.6};
double (*pf[3])[2];
pf[0]=&aa;pf[1]=&bb;pf[2]=&cc;
for(int i=0;i<3;i++)
{
for(int j=0;j<2;j++)
cout<<*(*pf[i]+j)<<" ";
cout<<endl;
}
}
输出如下:
1.1 2.2
3.3 4.4
5.5 6.6

我把代码试验过了,没有问题,但是我有个地方一直不明白,很长时间了。既然数组名是该数组的首地址,是一个指向本身首地址的指针,为什么代码中还要用pf[0]=&aa 之类的语句,为什么需要用&这个运算符呢?aa本身不就是个指针吗?它不就是一个十六进制的地址值吗?一直不明白。但是我试着把&符去了然后编译运行,甚至都不能通过编译,提示有错误。想问下CSDN的达人这到底是怎么回事。拜托讲详细点!这一直是我最困惑的地方。如果满意结贴的话,定有额外加分送给真诚回复者。谢谢!
...全文
1110 41 打赏 收藏 转发到动态 举报
写回复
用AI写文章
41 条回复
切换为时间正序
请发表友善的回复…
发表回复
zxhhp1314 2012-01-15
  • 打赏
  • 举报
回复
楼主,这又要说到c++最基础的也是最容易理解错误的指针与数组了,在问题中你说到“aa本身不就是数组吗”请注意这是个很危险的说法。请看指针与数组的定义:
指针是指针,指针变量存储的是一个地址,用来间接访问数据,在32位系统下,一个指针变量(包括void指针)始终占4个字节的空间。指针可以指向任何内存空间,但不是任何内存空间都可以通过指针去访问。

数组是数组,定义一个数组之后,编译器便根据该数组元素的类型和个数在内存开辟一段连续的空间来存放数据,从而直接访问数据。
如果楼主不能和好理解,可以来我的博客看这篇《浅谈C/C++中的指针和数组》
http://blog.sina.com.cn/s/blog_9984cde101011rwt.html

lumieresceau 2007-10-09
  • 打赏
  • 举报
回复
哎,CSDN有的时候真让人上火。说是全国最大的IT技术社区居然还有这么多问题。网络上不少朋友抱怨有bug,记分系统有问题。我个人在这也没办法加分,甚至没办法和在线的人及时聊天,都发不出去信息,说该用户不存在。这个玩笑开得大了点吧,现在什么都用不了,眼争睁看别人发个信息给你还回不了,晕!
saul2006 2007-10-06
  • 打赏
  • 举报
回复
晕,我要学英语了.
lumieresceau 2007-10-06
  • 打赏
  • 举报
回复
拜托,这个上面都已经做了, 知道值是好事,但是最重要的是原理啊
独孤过儿 2007-10-06
  • 打赏
  • 举报
回复
恩,楼上的建议非常好!

与其这样迷惑,还不如把指针以及指针指向的内容全部输出出来,那样一目了然,自然也很容易懂了!

输出一个指针可以用 (void*)pf 来实现
liwei84516 2007-10-06
  • 打赏
  • 举报
回复
我是来学英语的了.
其实我觉得象楼主的问题,有个方法很简单哈.你直接把pf[0],pf[],aa,&aa的值给他输出来,一切都清楚的很了.
wuqiong_1986_1001 2007-10-06
  • 打赏
  • 举报
回复
高深阿。。。真牛。。
英语!!
oldmanzhao 2007-10-05
  • 打赏
  • 举报
回复
因为pf 是一个 double **
pluminsnow 2007-10-05
  • 打赏
  • 举报
回复
多的不知道,但我可以告诉搂主,行与行之间差的不是10,以为那是16进制的10,其实就是16,所以行与行之间差的是16啊
LuckyYong 2007-10-05
  • 打赏
  • 举报
回复
Symbol aa only exist in compiling time. If we go into assemble level (assume we are on x86 platform), aa is an immediate constant (a pointer to current call stack/or global data area). There is no an address to hold aa. So &aa only exist in compiling time also. This is why they are identical in value. But they are different in syntax and semantics (I have explained the details about their syntax and semantics before). IN C/C++, WE PRESENT A NATIVE ARRAY WITH ITS ADDRESS. aa presents a native array, so aa is the array address in value. &aa prensents address of array aa in syntax and semantics. BTW: function name has same situation, f and &f are identical in value(address of function f) but different in syntax and semantics. SOMETIMES, THEY CAN BE CONVERTED IMPLICITLY.
Peterry 2007-10-05
  • 打赏
  • 举报
回复
我觉得aa不是指针吧,我觉得指针应该都是一个左值,楼主可以试一下,aa不是一个左值
Iluly 2007-10-05
  • 打赏
  • 举报
回复
关于你的迷惑:

函数的数据(包括参数和局部变量)存在在函数的堆栈中。

而栈是按地址从高到低存放的。

aa,bb,cc按声明顺序 由高到低 分配内存空间。
另:8+8=16 (有点废话了)
所以aa,bb,cc相差10(你说的是10,其实是F , 16);

这下明白了吧。
Iluly 2007-10-05
  • 打赏
  • 举报
回复
行与行相差的是16
因为数组有两个元素,一个占8位
Iluly 2007-10-05
  • 打赏
  • 举报
回复
第一个矛盾:
“既然数组名是数组首地址也是第一个元素的地址,那么aa这个单元既要存一个自身的地址(同时也是第一个double元素的地址),又要存一个double型的数据,既数组的首元素aa[0],这不就矛盾了吗?”

这其实是数据的物理结构与逻辑结构的问题。编译器提供逻辑层的封装,从而隐藏了物理层的细节。

物理层上 aa这个单元,就是四个字节,没有任何意义。但这四个字节,从逻辑上来说可以是任何地址, 如一个类的地址,数组的地址,本身的地址,或者一个函数的地址。

就看你怎么用了。所有并不矛盾,由于 它本身的地址与 aa首元素的地址相同, 所以逻辑上它两种意义。


附:黑客提取ShellCode的方法。
void func()
{
//攻击代码
……
}

main()
{
char *shell=(char *)func;

……
}

shell的值等于func, 那么逻辑上 func 不仅是一个函数的入口,又是一个数组第一个元素的地址,但这矛盾吗?
King_Fee 2007-10-05
  • 打赏
  • 举报
回复
flizny == &flizny[0]; // name of array is the address of the first element.


Actually,this is also a matter about C.

Refer to <<C Primer Plus>>.--Fifth Edition,By Stephen Prata.

Chapter 10. Arrays and Pointers-Pointers and Multidimensional Arrays.
LuckyYong 2007-10-05
  • 打赏
  • 举报
回复
To lumieresceau,
I have added comments in asm code. I said 'immediate constant' is not strict in my latest post. Sorry for confusing you, just forget it :)
lumieresceau 2007-10-05
  • 打赏
  • 举报
回复
To LuckyYong:
i am so sorry to tell you that i can't understand your ASM code'cause i am a beginner on computer science. Will you please explain the codes in details for me?
and still i want to ask why the name of an array is a immdiate constant(pointer)? According to C++ books, immediate constants aren't supposed to have a name as a mark, are they?

find it's really convenient to type in english in which C++ codes are written,hehe
lumieresceau 2007-10-05
  • 打赏
  • 举报
回复
ely_5:
Also my heartfelt thanks for you too!And the same should goes for you---------
for your patience in keeping answering my questions. And finaly my compliment to your knowledge of computer science as well as English language.
hehe, hope i 'll have the honour to make a good friend out of you regarding learning of computer science-----
haha,CSDN's really got some tough guys here!
Iluly 2007-10-05
  • 打赏
  • 举报
回复
The programer who have learned ASM maybe very easy to understand why aa only exist in compiling time.
As asm programer use registers instead of identities as aa,or bb to control the memory .And this is just why programers didn't use it to build a big project.
You can read some books about ASM,then you will understand many questions on pointer or memory.
LuckyYong 2007-10-05
  • 打赏
  • 举报
回复
To lumieresceau,
[quote]
Then, like you said, aa and &aa only exist in compiling level, how can the program identify the correct data which are supposed to be labeled by aa during the runing process of the program?
[end of quoting]

considering the following example on 32 bits x86 platform

void f()
{
int a[10]; //10bytes
int* p = a; //4bytes
int (*q)[10] = &a; //4bytes
}

ASM code maybe like this.
...
...
push ebp
mov ebp, esp ;ebp hold address of array a. ebp is a register, it has NO ADDRESS in C/C++ perspective
sub esp, 48 ;48bytes total for local vars (one array, 2 pointers)
mov eax, ebp
mov [ebp+40], eax ; p = a
mov [ebp+44], eax ; q = &a
....
....

The program identify data via stack pointer. I think this explained what I said, which is that aa exists only in compling time. Regarding immidate constant, it is not strict because the address of aa is hold by ebp. But it has no address (memory address) exactly.
加载更多回复(21)

64,642

社区成员

发帖
与我相关
我的任务
社区描述
C++ 语言相关问题讨论,技术干货分享,前沿动态等
c++ 技术论坛(原bbs)
社区管理员
  • C++ 语言社区
  • encoderlee
  • paschen
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
  1. 请不要发布与C++技术无关的贴子
  2. 请不要发布与技术无关的招聘、广告的帖子
  3. 请尽可能的描述清楚你的问题,如果涉及到代码请尽可能的格式化一下

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