在关于C的一个有信誉的来源中,在讨论&操作符后给出了以下信息:

... 有点不幸的是,术语[地址的]仍然存在,因为它混淆了那些不知道地址是关于什么的人,并误导了那些知道地址的人:将指针视为地址通常会导致悲伤……

我读过的其他材料(来自同样有名望的来源,我想说)总是毫不掩饰地将指针和&操作符作为内存地址。我很愿意继续寻找事情的真相,但当有信誉的消息来源不同意时,这有点困难。

现在我有点困惑了——如果指针不是内存地址,那么它到底是什么?

P.S.

作者后来说:……不过,我将继续使用“地址”这个术语,因为发明一个不同的(术语)会更糟糕。


当前回答

C标准没有在内部定义指针是什么以及它在内部是如何工作的。这样做的目的是为了不限制平台的数量,在这些平台上,C可以作为编译或解释语言实现。

指针值可以是某种ID或句柄,也可以是几个ID的组合(对x86段和偏移量说你好),不一定是真正的内存地址。这个ID可以是任何东西,甚至是固定大小的文本字符串。非地址表示可能对C解释器特别有用。

其他回答

指针只是另一个变量,它通常包含另一个变量的内存地址。指针是一个变量,它也有一个内存地址。

Come to think about it, I think it's a matter of semantics. I don't think the author is right, since the C standard refers to a pointer as holding an address to the referenced object as others have already mentioned here. However, address!=memory address. An address can be really anything as per C standard although it will eventually lead to a memory address, the pointer itself can be an id, an offset + selector (x86), really anything as long as it can describe (after mapping) any memory address in the addressable space.

你是对的,是理智的。通常,指针只是一个地址,因此您可以将其强制转换为整数并进行任何算术运算。

但有时指针只是地址的一部分。在一些体系结构上,指针被转换为一个增加了基数的地址或使用另一个CPU寄存器。

但是现在,在PC和ARM架构上,使用平面内存模型和原生编译的C语言,可以认为指针是指向一维可寻址RAM中某个位置的整数地址。

C标准没有在内部定义指针是什么以及它在内部是如何工作的。这样做的目的是为了不限制平台的数量,在这些平台上,C可以作为编译或解释语言实现。

指针值可以是某种ID或句柄,也可以是几个ID的组合(对x86段和偏移量说你好),不一定是真正的内存地址。这个ID可以是任何东西,甚至是固定大小的文本字符串。非地址表示可能对C解释器特别有用。

A pointer value is an address. A pointer variable is an object that can store an address. This is true because that's what the standard defines a pointer to be. It's important to tell it to C novices because C novices are often unclear on the difference between a pointer and the thing it points to (that is to say, they don't know the difference between an envelope and a building). The notion of an address (every object has an address and that's what a pointer stores) is important because it sorts that out.

然而,标准在特定的抽象层次上进行讨论。作者所说的那些“知道地址是关于什么的”,但对C不熟悉的人,必须在不同的抽象级别上学习地址——也许是通过编写汇编语言。不能保证C实现使用与cpu操作码相同的地址表示(在本文中称为“存储地址”),这些人已经知道。

He goes on to talk about "perfectly reasonable address manipulation". As far as the C standard is concerned there's basically no such thing as "perfectly reasonable address manipulation". Addition is defined on pointers and that is basically it. Sure, you can convert a pointer to integer, do some bitwise or arithmetic ops, and then convert it back. This is not guaranteed to work by the standard, so before writing that code you'd better know how your particular C implementation represents pointers and performs that conversion. It probably uses the address representation you expect, but it it doesn't that's your fault because you didn't read the manual. That's not confusion, it's incorrect programming procedure ;-)

简而言之,C使用了比作者更抽象的地址概念。

The author's concept of an address of course is also not the lowest-level word on the matter. What with virtual memory maps and physical RAM addressing across multiple chips, the number that you tell the CPU is "the store address" you want to access has basically nothing to do with where the data you want is actually located in hardware. It's all layers of indirection and representation, but the author has chosen one to privilege. If you're going to do that when talking about C, choose the C level to privilege!

Personally I don't think the author's remarks are all that helpful, except in the context of introducing C to assembly programmers. It's certainly not helpful to those coming from higher level languages to say that pointer values aren't addresses. It would be far better to acknowledge the complexity than it is to say that the CPU has the monopoly on saying what an address is and thus that C pointer values "are not" addresses. They are addresses, but they may be written in a different language from the addresses he means. Distinguishing the two things in the context of C as "address" and "store address" would be adequate, I think.