C语言 如果不是内存地址,C 指针究竟是什么?

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/15151377/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-09-02 05:31:06  来源:igfitidea点击:

What exactly is a C pointer if not a memory address?

cpointersmemory-address

提问by d0rmLife

In a reputable source about C, the following information is given after discussing the &operator:

在有关 C 的信誉良好的来源中,在讨论&运算符后给出了以下信息:

... It's a bit unfortunate that the terminology [address of]remains, because it confuses those who don't know what addresses are about, and misleads those who do: thinking about pointers as if they were addresses usually leads to grief...

...保留[address of]这个术语有点遗憾,因为它混淆了那些不知道地址是什么的人,并误导了那些知道地址的人:将指针视为地址通常会导致悲伤.. .

Other materials I have read (from equally reputable sources, I would say) have always unabashedly referred to pointers and the &operator as giving memory addresses. I would love to keep searching for the actuality of the matter, but it is kind of difficult when reputable sources KIND OF disagree.

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

Now I am slightly confused--what exactlyis a pointer, then, if not a memory address?

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

P.S.

聚苯乙烯

The author later says: ...I will continue to use the term 'address of' though, because to invent a different one[term] would be even worse.

作者后来说:……不过我会继续使用“address of”这个词,因为发明一个不同的[term]会更糟。

回答by Alexey Frunze

The C standard does not define what a pointer is internally and how it works internally. This is intentional so as not to limit the number of platforms, where C can be implemented as a compiled or interpreted language.

C 标准没有定义指针在内部是什么以及它在内部如何工作。这是有意的,以免限制平台的数量,其中 C 可以作为编译或解释语言来实现。

A pointer value can be some kind of ID or handle or a combination of several IDs (say hello to x86 segments and offsets) and not necessarily a real memory address. This ID could be anything, even a fixed-size text string. Non-address representations may be especially useful for a C interpreter.

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

回答by Cornstalks

I'm not sure about your source, but the type of language you're describing comes from the C standard:

我不确定您的来源,但您所描述的语言类型来自 C 标准:

6.5.3.2 Address and indirection operators
[...]
3. The unary & operator yields the address of its operand.[...]

6.5.3.2 地址和间接运算符
[...]
3.一元 & 运算符产生其操作数的地址。[...]

So... yeah, pointers point to memory addresses. At least that's how the C standard suggests it to mean.

所以......是的,指针指向内存地址。至少这就是 C 标准所暗示的意思。

To say it a bit more clearly, a pointer is a variable holding the valueof some address. The address of an object (which may be stored in a pointer) is returned with the unary &operator.

说得更清楚一点,指针是一个保存某个地址的变量。对象的地址(可以存储在指针中)通过一元运算符返回。&

I can store the address "42 Wallaby Way, Sydney" in a variable (and that variable would be a "pointer" of sorts, but since that's not a memory address it's not something we'd properly call a "pointer"). Your computer has addresses for its buckets of memory. Pointers store the value of an address (i.e. a pointer stores the value "42 Wallaby Way, Sydney", which is an address).

我可以将地址“42 Wallaby Way, Sydney”存储在一个变量中(该变量将是某种“指针”,但由于这不是内存地址,因此我们不能正确地将其称为“指针”)。您的计算机具有存储桶的地址。指针存储地址的值(即指针存储值“42 Wallaby Way, Sydney”,这是一个地址)。

Edit:I want to expand on Alexey Frunze's comment.

编辑:我想扩展 Alexey Frunze 的评论。

What exactly is a pointer?Let's look at the C standard:

究竟什么是指针?让我们看看 C 标准:

6.2.5 Types
[...]
20. [...]
A pointer typemay be derived from a function type or an object type, called the referenced type. A pointer type describes an object whose value provides a reference to an entity of the referenced type. A pointer type derived from the referenced type T is sometimes called ‘‘pointer to T''. The construction of a pointer type from a referenced type is called ‘‘pointer type derivation''. A pointer type is a complete object type.

6.2.5类型
[...]
20 [...]
指针类型可以由函数类型或对象类型,称为派生引用的类型。指针类型描述了一个对象,其值提供对被引用类型的实体的引用。从引用类型 T 派生的指针类型有时称为“指向 T 的指针”。从引用类型构造指针类型称为“指针类型派生”。指针类型是一个完整的对象类型。

Essentially, pointers store a value that provides a reference to some object or function. Kind of. Pointers are intended to store a value that provides a reference to some object or function, but that's not alwaysthe case:

本质上,指针存储一个值,该值提供对某个对象或函数的引用。的种类。指针旨在存储提供对某些对象或函数的引用的值,但情况并非总是如此:

6.3.2.3 Pointers
[...]
5. An integer may be converted to any pointer type. Except as previously specified, the result is implementation-defined, might not be correctly aligned, might not point to an entity of the referenced type, and might be a trap representation.

6.3.2.3 指针
[...]
5. 整数可以转换为任何指针类型。除了前面指定的,结果是实现定义的,可能没有正确对齐,可能不指向引用类型的实体,并且可能是陷阱表示。

The above quote says that we can turn an integer into a pointer. If we do that (that is, if we stuff an integer value into a pointer instead of a specific reference to an object or function), then the pointer "might not point to an entity of reference type" (i.e. it may not provide a reference to an object or function). It might provide us with something else. And this is one place where you might stick some kind of handle or ID in a pointer (i.e. the pointer isn't pointing to an object; it's storing a value that represents something, but that value may not be an address).

上面的引用说我们可以将整数转换为指针。如果我们这样做(也就是说,如果我们将一个整数值填充到一个指针中而不是一个对象或函数的特定引用中),那么该指针“可能不会指向一个引用类型的实体”(即它可能不会提供一个对对象或函数的引用)。它可能会为我们提供其他东西。这是一个您可能会在指针中粘贴某种句柄或 ID 的地方(即指针不指向一个对象;它存储了一个代表某物的值,但该值可能不是地址)。

So yes, as Alexey Frunze says, it's possible a pointer isn't storing an address to an object or function. It's possible a pointer is instead storing some kind of "handle" or ID, and you can do this by assigning some arbitrary integer value to a pointer. What this handle or ID represents depends on the system/environment/context. So long as your system/implementation can make sense of the value, you're in good shape (but that depends on the specific value and the specific system/implemenation).

所以是的,正如 Alexey Frunze 所说,指针可能没有存储指向对象或函数的地址。指针可能会存储某种“句柄”或 ID,您可以通过为指针分配一些任意整数值来实现这一点。这个句柄或 ID 代表什么取决于系统/环境/上下文。只要您的系统/实现能够理解价值,您就处于良好状态(但这取决于具体的价值和具体的系统/实现)。

Normally, a pointer stores an address to an object or function. If it isn't storing an actual address (to an object or function), the result is implementation defined (meaning that exactly what happens and what the pointer now represents depends on your system and implementation, so it might be a handle or ID on a particular system, but using the same code/value on another system might crash your program).

通常,指针存储指向对象或函数的地址。如果它不存储实际地址(到对象或函数),则结果是实现定义的(意味着究竟发生了什么以及指针现在代表什么取决于您的系统和实现,因此它可能是一个句柄或 ID一个特定的系统,但在另一个系统上使用相同的代码/值可能会使您的程序崩溃)。

That ended up being longer than I thought it would be...

结果比我想象的要长......

回答by Harikrishnan

Pointer vs Variable

指针 vs 变量

In this picture,

在这幅图片中,

pointer_p is a pointer which is located at 0x12345, and is pointing to a variable variable_v at 0x34567.

pointer_p 是位于 0x12345 处的指针,指向 0x34567 处的变量 variable_v。

回答by Gilles 'SO- stop being evil'

To think of a pointer as an address is an approximation. Like all approximations, it's good enough to be useful sometimes, but it's also not exact which means that relying on it causes trouble.

将指针视为地址是一种近似。像所有近似值一样,它有时足够有用,但它也不精确,这意味着依赖它会导致麻烦。

A pointer is like an address in that it indicates where to find an object. One immediate limitation of this analogy is that not all pointers actually contain an address. NULLis a pointer which is not an address. The content of a pointer variable can in fact be of one of three kinds:

指针就像地址一样,指示在哪里可以找到对象。这种类比的一个直接限制是并非所有指针实际上都包含地址。NULL是一个不是地址的指针。指针变量的内容实际上可以是以下三种之一:

  • the addressof an object, which can be dereferenced (if pcontains the address of xthen the expression *phas the same value as x);
  • a null pointer, of which NULLis an example;
  • invalidcontent, which doesn't point to an object (if pdoesn't hold a valid value, then *pcould do anything (“undefined behavior”), with crashing the program a fairly common possibility).
  • 对象的地址,可以取消引用(如果p包含的地址x则表达式与*p具有相同的值x);
  • 一个空指针,这NULL是一个例子;
  • 不指向对象的无效内容(如果p不包含有效值,则*p可以做任何事情(“未定义行为”),使程序崩溃是一种相当常见的可能性)。

Furthermore, it would be more accurate to say that a pointer (if valid and non-null) containsan address: a pointer indicates where to find an object, but there is more information tied to it.

此外,更准确地说,一个指针(如果有效且非空)包含一个地址:一个指针指示在哪里可以找到一个对象,但有更多与之相关的信息。

In particular, a pointer has a type. On most platforms, the type of the pointer has no influence at runtime, but it has an influence that goes beyond the type at compile time. If pis a pointer to int(int *p;), then p + 1points to an integer which is sizeof(int)bytes after p(assuming p + 1is still a valid pointer). If qis a pointer to charthat points to the same address as p(char *q = p;), then q + 1is not the same address as p + 1. If you think of pointer as addresses, it is not very intuitive that the “next address” is different for different pointers to the same location.

特别是,指针具有类型。在大多数平台上,指针的类型在运行时没有影响,但它在编译时的影响超出了类型。如果p是指向int( int *p;)的指针,则p + 1指向一个整数,该整数在sizeof(int)字节之后p(假设p + 1仍然是一个有效的指针)。如果q是指向与( )char相同地址的指针,则与 不是相同的地址。如果将指针视为地址,那么指向同一位置的不同指针的“下一个地址”不同,这不是很直观。pchar *q = p;q + 1p + 1

It is possible in some environments to have multiple pointer values with different representations (different bit patterns in memory) that point to the same location in memory. You can think of these as different pointers holding the same address, or as different addresses for the same location — the metaphor isn't clear in this case. The ==operator always tells you whether the two operands are pointing to the same location, so on these environments you can have p == qeven though pand qhave different bit patterns.

在某些环境中,可能有多个具有不同表示(内存中的不同位模式)的指针值指向内存中的同一位置。您可以将它们视为保存相同地址的不同指针,或者相同位置的不同地址——在这种情况下,隐喻并不明确。该==运营商总是告诉你两个操作数是否都指向同一位置,所以在这些环境中,你可以有p == q,即使pq有不同的位模式。

There are even environments where pointers carry other information beyond the address, such as type or permission information. You can easily go through your life as a programmer without encountering these.

甚至在某些环境中,指针携带地址以外的其他信息,例如类型或权限信息。作为一名程序员,你可以轻松地度过你的生活,而不会遇到这些。

There are environments where different kinds of pointers have different representations. You can think of it as different kinds of addresses having different representations. For example, some architectures have byte pointers and word pointers, or object pointers and function pointers.

在某些环境中,不同类型的指针具有不同的表示形式。您可以将其视为具有不同表示形式的不同类型的地址。例如,某些体系结构具有字节指针和字指针,或对象指针和函数指针。

All in all, thinking of pointers as addresses isn't too bad as long as you keep in mind that

总而言之,只要记住,将指针视为地址并不算太糟糕

  • it's only valid, non-null pointers that are addresses;
  • you can have multiple addresses for the same location;
  • you can't do arithmetic on addresses, and there's no order on them;
  • the pointer also carries type information.
  • 只有有效的非空指针才是地址;
  • 同一位置可以有多个地址;
  • 你不能对地址进行算术运算,而且它们没有顺序;
  • 指针还携带类型信息。

Going the other way round is far more troublesome. Not everything that looks like an address can be a pointer. Somewhere deep down any pointer is represented as a bit pattern that can be read as an integer, and you can say that this integer is an address. But going the other way, not every integer is a pointer.

反过来就麻烦多了。并非所有看起来像地址的东西都可以是指针。在深处,任何指针都被表示为一个位模式,可以作为一个整数读取,你可以说这个整数是一个地址。但反过来说,并不是每个整数都是指针。

There are first some well-known limitations; for example, an integer that designates a location outside your program's address space can't be a valid pointer. A misaligned address doesn't make a valid pointer for a data type that requires alignment; for example, on a platform where intrequires 4-byte alignment, 0x7654321 cannot be a valid int*value.

首先是一些众所周知的限制;例如,指定程序地址空间之外的位置的整数不能是有效指针。对于需要对齐的数据类型,未对齐的地址不会成为有效的指针;例如,在int需要 4 字节对齐的平台上,0x7654321 不能是有效值int*

However, it goes well beyond that, because when you make a pointer into an integer, you're in for a world of trouble. A big part of this trouble is that optimizing compilers are far better at microoptimization than most programmers expect, so that their mental model of how a program works is deeply wrong. Just because you have pointers with the same address doesn't mean that they are equivalent. For example, consider the following snippet:

然而,它远不止于此,因为当您将指针转换为整数时,您将陷入困境。这个问题的很大一部分是优化编译器在微优化方面比大多数程序员预期的要好得多,因此他们对程序如何工作的心理模型是非常错误的。仅仅因为您具有相同地址的指针并不意味着它们是等效的。例如,请考虑以下代码段:

unsigned int x = 0;
unsigned short *p = (unsigned short*)&x;
p[0] = 1;
printf("%u = %u\n", x, *p);

You might expect that on a run-of-the-mill machine where sizeof(int)==4and sizeof(short)==2, this either prints 1 = 1?(little-endian) or 65536 = 1?(big-endian). But on my 64-bit Linux PC with GCC 4.4:

您可能希望在普通机器上使用sizeof(int)==4and sizeof(short)==2,这要么打印1 = 1?(little-endian) 要么65536 = 1?(big-endian)。但是在我的带有 GCC 4.4 的 64 位 Linux PC 上:

$ c99 -O2 -Wall a.c && ./a.out 
a.c: In function ‘main':
a.c:6: warning: dereferencing pointer ‘p' does break strict-aliasing rules
a.c:5: note: initialized from here
0 = 1?

GCC is kind enough to warn us what's going wrongin this simple example — in more complex examples, the compiler might not notice. Since phas a different type from &x, changing what ppoints to cannot affect what &xpoints to (outside some well-defined exceptions). Therefore the compiler is at liberty to keep the value of xin a register and not update this register as *pchanges. The program dereferences two pointers to the same address and obtains two different values!

GCC 非常友好地警告我们在这个简单的例子中出了什么问题——在更复杂的例子中,编译器可能不会注意到。由于与p具有不同的类型&x,因此更改p指向的内容不会影响&x指向的内容(某些明确定义的异常除外)。因此,编译器可以自由地将 的值保留x在寄存器中,并且不会随着*p更改而更新该寄存器。程序取消引用指向同一地址的两个指针并获得两个不同的值!

The moral of this example is that thinking of a (non-null valid) pointer as an address is fine, as long as you stay within the precise rules of the C language. The flip side of the coin is that the rules of the C language are intricate, and difficult to get an intuitive feeling for unless you know what happens under the hood. And what happens under the hood is that the tie between pointers and addresses is somewhat loose, both to support “exotic” processor architectures and to support optimizing compilers.

这个例子的寓意是将(非空有效)指针视为地址是可以的,只要您遵守 C 语言的精确规则。硬币的另一面是 C 语言的规则错综复杂,除非您知道幕后发生了什么,否则很难获得直观的感觉。在幕后发生的事情是指针和地址之间的联系有些松散,既支持“异国情调”处理器架构,也支持优化编译器。

So think of pointers being addresses as a first step in your understanding, but don't follow that intuition too far.

因此,将指针作为地址视为理解的第一步,但不要太遵循这种直觉。

回答by Aniket Inge

A pointer is a variable that HOLDS memory address, not the address itself. However, you can dereference a pointer - and get access to the memory location.

指针是一个保存内存地址的变量,而不是地址本身。但是,您可以取消引用指针 - 并访问内存位置。

For example:

例如:

int q = 10; /*say q is at address 0x10203040*/
int *p = &q; /*means let p contain the address of q, which is 0x10203040*/
*p = 20; /*set whatever is at the address pointed by "p" as 20*/

That's it. It's that simple.

就是这样。就这么简单。

enter image description here

在此处输入图片说明

A program to demonstrate what I am saying and its output is here:

一个演示我所说内容及其输出的程序在这里:

http://ideone.com/rcSUsb

http://ideone.com/rcSUsb

The program:

该程序:

#include <stdio.h>

int main(int argc, char *argv[])
{
  /* POINTER AS AN ADDRESS */
  int q = 10;
  int *p = &q;

  printf("address of q is %p\n", (void *)&q);
  printf("p contains %p\n", (void *)p);

  p = NULL;
  printf("NULL p now contains %p\n", (void *)p);
  return 0;
}

回答by thang

It's difficult to tell exactly what the authors of those books mean exactly. Whether a pointer contains an address or not depends on how you define an address and how you define a pointer.

很难确切地说出这些书的作者究竟是什么意思。指针是否包含地址取决于您如何定义地址以及如何定义指针。

Judging from all the answers that are written, some people assume that (1) an address must be an integer and (2) a pointer doesn't need to be by virtual of not being said so in the specification. With these assumptions, then clearly pointers do not necessarily contain addresses.

从所有写的答案来看,有些人认为(1)地址必须是整数,(2)指针不需要是虚拟的,因为在规范中没有这么说。有了这些假设,显然指针不一定包含地址。

However, we see that while (2) is probably true, (1) probably doesn't have to be true. And what to make of the fact that the & is called the address ofoperator as per @CornStalks's answer? Does this mean that the authors of the specification intend for a pointer to contain an address?

然而,我们看到虽然 (2) 可能是真的,但 (1) 可能不一定是真的。根据@CornStalks 的回答,& 被称为运营商的地址这一事实如何?这是否意味着规范的作者打算使用包含地址的指针?

So can we say, pointer contains an address, but an address doesn't have to be an integer? Maybe.

那么我们可以说,指针包含一个地址,但地址不一定是整数吗?也许。

I think all of this is jibberish pedantic semantic talk. It is totally worthless practically speaking. Can you think of a compiler that generates code in such a way that the value of a pointer is not an address? If so, what? That's what I thought...

我认为所有这些都是废话迂腐的语义谈话。实际上,这是完全没有价值的。你能想到一个编译器以指针的值不是地址的方式生成代码吗?如果是这样,是什么?我也这么想...

I think what the author of the book (the first excerpt that claims that pointers are not necessarily just addresses) probably is referring to is the fact that a pointer comes with it the inherent type information.

我认为这本书的作者(声称指针不一定只是地址的第一个摘录)可能指的是指针附带固有类型信息的事实。

For example,

例如,

 int x;
 int* y = &x;
 char* z = &x;

both y and z are pointers, but y+1 and z+1 are different. if they are memory addresses, wouldn't those expressions give you the same value?

y 和 z 都是指针,但 y+1 和 z+1 是不同的。如果它们是内存地址,这些表达式不会给你相同的值吗?

And here in lies the thinking about pointers as if they were addresses usually leads to grief. Bugs have been written because people think about pointers as if they were addresses, and this usually leads to grief.

在这里,将指针视为地址想法通常会导致悲伤。之所以编写错误,是因为人们将指针视为地址,而这通常会导致悲伤

55555 is probably not a pointer, although it may be an address, but (int*)55555 is a pointer. 55555+1 = 55556, but (int*)55555+1 is 55559 (+/- difference in terms of sizeof(int)).

55555 可能不是指针,虽然可能是地址,但是 (int*)55555 是指针。55555+1 = 55556,但 (int*)55555+1 是 55559(在 sizeof(int) 方面的 +/- 差异)。

回答by alexis

Well, a pointer is an abstractionrepresenting a memory location. Note that the quote doesn't say that thinking about pointers as if they were memory addresses is wrong, it just says that it "usually leads to grief". In other words, it leads you to have incorrect expectations.

好吧,指针是表示内存位置的抽象。请注意,引用并没有说将指针视为内存地址是错误的,它只是说它“通常会导致悲伤”。换句话说,它会导致您产生不正确的期望。

The most likely source of grief is certainly pointer arithmetic,which is actually one of C's strengths. If a pointer was an address, you'd expect pointer arithmetic to be address arithmetic; but it's not. For example, adding 10 to an address should give you an address that is larger by 10 addressing units; but adding 10 to a pointer increments it by 10 times the size of the kind of object it points to (and not even the actual size, but rounded up to an alignment boundary). With an int *on an ordinary architecture with 32-bit integers, adding 10 to it would increment it by 40 addressing units (bytes). Experienced C programmers are aware of this and live with it, but your author is evidently no fan of sloppy metaphors.

最可能的悲痛来源当然是指针运算,这实际上是 C 的强项之一。如果一个指针是一个地址,你会期望指针算术是地址算术;但事实并非如此。例如,在地址上加 10 会得到一个大于 10 个寻址单元的地址;但是将 10 添加到指针会使其指向的对象类型的大小增加 10 倍(甚至不是实际大小,而是四舍五入到对齐边界)。对于int *具有 32 位整数的普通体系结构,向其添加 10 会将其增加 40 个寻址单元(字节)。有经验的 C 程序员意识到这一点并接受它,但您的作者显然不喜欢草率的隐喻。

There's the additional question of how the contents of the pointer representthe memory location:As many of the answers have explained, an address is not always an int (or long). In some architectures an address is a "segment" plus an offset. A pointer might even contain just the offset into the current segment ("near" pointer), which by itself is not a unique memory address. And the pointer contents might have only an indirect relationship to a memory address as the hardware understands it. But the author of the quote cited doesn't even mention representation, so I think it was conceptual equivalence, rather than representation, that they had in mind.

还有一个问题是指针的内容如何表示内存位置:正如许多答案所解释的那样,地址并不总是 int(或 long)。在某些体系结构中,地址是一个“段”加上一个偏移量。指针甚至可能只包含到当前段(“近”指针)的偏移量,它本身并不是唯一的内存地址。并且指针内容可能与硬件理解的内存地址只有间接关系。但是引用的引文的作者甚至没有提到表示,所以我认为他们想到的是概念对等,而不是表示。

回答by Mark Bessey

Here's how I've explained it to some confused people in the past: A pointer has two attributes that affect its behavior. It has a value, which is (in typical environments) a memory address, and a type, which tells you the type and size of the object that it points at.

下面是我过去向一些困惑的人解释它的方式: 指针有两个影响其行为的属性。它有一个value,它是(在典型环境中)一个内存地址和一个type,它告诉你它指向的对象的类型和大小。

For example, given:

例如,给定:

union {
    int i;
    char c;
} u;

You can have three different pointers all pointing to this same object:

您可以让三个不同的指针都指向同一个对象:

void *v = &u;
int *i = &u.i;
char *c = &u.c;

If you compare the values of these pointers, they're all equal:

如果比较这些指针的值,它们都是相等的:

v==i && i==c

However, if you increment each pointer, you'll see that the typethat they point to becomes relevant.

但是,如果您增加每个指针,您将看到它们指向的类型变得相关。

i++;
c++;
// You can't perform arithmetic on a void pointer, so no v++
i != c

The variables iand cwill have different values at this point, because i++causes ito contain the address of the next-accessible integer, and c++causes cto point to the next-addressable character. Typically, integers take up more memory than characters, so iwill end up with a larger value than cafter they are both incremented.

此时变量ic将具有不同的值,因为i++导致i包含下一个可访问整数的地址,并c++导致c指向下一个可寻址字符。通常,整数比字符占用更多内存,因此i最终会比c它们都递增后得到更大的值。

回答by exebook

You are right and sane. Normally, a pointer is just an address, so you can cast it to integer and do any arithmetics.

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

But sometimes pointers are only a part of an address. On some architectures a pointer is converted to an address with addition of base or another CPUregister is used.

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

But these days, on PC and ARMarchitecture with a flat memory model and C language natively compiled, it's OK to think that a pointer is an integer address to some place in one-dimensional addressable RAM.

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

回答by Aki Suihkonen

Mark Bessey already said it, but this needs to be re-emphasised until understood.

Mark Bessey 已经说过了,但是在理解之前需要重新强调这一点。

Pointer has as much to do with a variable than a literal 3.

指针与变量的关系与文字 3 的关系一样多。

Pointer isa tuple of a value (of an address) and a type (with additional properties, such as read only). The type (and the additional parameters if any) can further define or restrict the context; eg. __far ptr, __near ptr: what is the context of the address: stack, heap, linear address, offset from somewhere, physical memory or what.

指针值(地址)和类型(具有附加属性,例如只读)的元组。类型(以及附加参数,如果有的话)可以进一步定义或限制上下文;例如。__far ptr, __near ptr:地址的上下文是什么:堆栈、堆、线性地址、从某处偏移、物理内存或什么。

It's the property of typethat makes pointer arithmetic a bit different to integer arithmetic.

正是类型的属性使指针算术与整数算术有点不同。

The counter examples of a pointer of not being a variable are too many to ignore

指针不是变量的反例太多了,不容忽视

  • fopen returning a FILE pointer. (where's the variable)
  • stack pointer or frame pointer being typically unaddressable registers

    *(int *)0x1231330 = 13;-- casting an arbitrary integer value to a pointer_of_integer type and writing/reading an integer without ever introducing a variable

  • fopen 返回一个 FILE 指针。(变量在哪里)
  • 堆栈指针或帧指针通常是不可寻址的寄存器

    *(int *)0x1231330 = 13;-- 将任意整数值转换为 pointer_of_integer 类型并在不引入变量的情况下写入/读取整数

In the lifetime of a C-program there will be many other instances of temporary pointers that do not have addresses -- and therefore they are not variables, but expressions/values with a compile time associated type.

在 C 程序的生命周期中,会有许多其他没有地址的临时指针实例——因此它们不是变量,而是具有编译时关联类型的表达式/值。