6

我理解指针和引用的整体含义(或者至少我认为我理解),我也理解当我使用new时,我正在动态分配内存。

我的问题如下:

如果我要使用cout << &p,它将显示p. 有没有办法可以操纵这个“虚拟内存位置”?

例如,以下代码显示了一个ints 数组。

如果我想显示 的值p[1]并且我知道 的“虚拟内存位置” p,我能否以某种方式执行“ &p + 1”并获得p[1]with的值cout << *p,它现在将指向数组中的第二个元素?

int *p;
p = new int[3];

p[0] = 13;
p[1] = 54;
p[2] = 42;
4

5 回答 5

8

当然,您可以操作指针来访问数组中的不同元素,但是您需要操作指针的内容(即 p 指向的地址),而不是指针本身的地址。

int *p = new int[3];
p[0] = 13;
p[1] = 54;
p[2] = 42;

cout << *p << ' ' << *(p+1) << ' ' << *(p+2);

每个加法(或减法)表示数组中的后续(先前)元素。如果 p 指向地址为 12345 的 4 字节变量(例如典型的 32 位 PC 上的int),则 p+1 将指向 12349,而不是 12346。请注意,您希望在取消引用之前更改 p 包含的值访问它指向的内容。

于 2008-09-20T05:49:02.930 回答
3

不完全的。是指针&p的地址。将指的是一个更远的地址。你想做的是p&p+1int*

p=p+1; /* or ++p or p++ */

现在当你做

cout << *p;

您将得到 54。不同之处在于,p包含ints 数组的起始地址,而p&p的地址。要移动一个项目,您需要指向int 数组的更远,而不是沿着堆栈的更远,这是存在的地方。p

如果您只有,&p那么您需要执行以下操作:

int **q = &p; /* q now points to p */
*q = *q+1;
cout << *p;

如果我没记错的话,那也会输出 54 。

于 2008-09-20T05:53:44.777 回答
2

自从我使用指针以来已经有一段时间(很多年)了,但我知道如果 p 指向数组的开头(即 p[0])并且你递增它(即 p++)那么 p 现在将指向 p [1]。

我认为您必须取消引用 p 才能获得该值。您可以通过将 * 放在指针前面来取消引用指针。

所以 *p = 33 将 p[0] 更改为 33。

我猜要获得第二个元素,你会使用 *(p+1) 所以你需要的语法是:

cout << *(p+1)

或者

cout << *(++p)
于 2008-09-20T05:54:25.587 回答
2

我喜欢这样做:

&p[1]

在我看来,它看起来更整洁。

于 2008-09-20T06:11:23.517 回答
1

将 C 和 C++ 中的“指针类型”视为在 CPU 内存空间中的字节上叠加一长串逻辑单元,从字节 0 开始。每个单元的宽度(以字节为单位)取决于指针的“类型”。每种指针类型都放置具有不同单元格宽度的行。"int *"指针放置一行 4 字节的单元,因为 int 的存储宽度是 4 字节。A"double *"为每个单元格设置一个 8 字节的行;一个"struct foo *"指针放置一行,每个单元格的宽度为单个"struct foo",无论是什么。任何“事物”的“地址”是保存“事物”的行中单元格的字节偏移量,从 0 开始。

指针算法基于行中的单元格,而不是字节。"*(p+10)" 是对“p”之后的第 10 个单元格的引用,其中单元格大小由 p 的类型决定。如果“p”的类型是“int”,则“p+10”的地址是 p 之后的 40 个字节; 如果 p 是指向 1000 字节长的结构的指针,“p+10”是 p 之后的 10,000 字节。(请注意,编译器可以为结构选择最佳大小,该大小可能比您想象的要大;这个是由于“填充”和“对齐”。例如,讨论的 1000 字节结构实际上可能每个单元占用 1024 个字节,因此“p+10”实际上是 p 之后的 10,240 个字节。)

于 2008-09-20T07:02:01.993 回答