我理解指针和引用的整体含义(或者至少我认为我这样做),我也理解当我使用 new 时我会动态分配内存。
我的问题如下:
如果我使用cout << &p
,它将显示p
的“虚拟内存位置”。
有没有办法可以操作这个“虚拟内存位置?”
例如,以下代码显示了int
s。
如果我想显示p[1]
的值并且我知道p
的“虚拟内存位置”,我可以以某种方式执行“&p + 1
”并获取{p[1]
的值1}} cout << *p
,现在指向数组中的第二个元素?
int *p;
p = new int[3];
p[0] = 13;
p[1] = 54;
p[2] = 42;
答案 0 :(得分: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.注意您要更改的值在取消引用它以访问它指向的内容之前包含的内容。
答案 1 :(得分:3)
不完全。 &p
是指针p
的地址。 &p+1
将引用一个int*
的地址。你想要做的是
p=p+1; /* or ++p or p++ */
现在你做的时候
cout << *p;
你会得到54.区别在于,p
包含整数数组开头的地址,而&p
是p的地址。要移动一个项目,您需要进一步指向 int数组,而不是进一步指向堆栈,这是p
所在的位置。
如果您只有&p
,那么您需要执行以下操作:
int **q = &p; /* q now points to p */
*q = *q+1;
cout << *p;
如果我没有记错的话,那也会输出54.
答案 2 :(得分:2)
自从我使用指针以来已经有一段时间了(很多年)但是我知道如果p指向数组的开头(即p [0])并且你递增它(即p ++)那么p现在将是指着p [1]。
我认为您必须取消引用p才能获得该值。您可以通过在其前面放置*来取消引用指针。
所以* p = 33,将p [0]改为33。
我猜你要使用第二个元素*(p + 1)所以你需要的语法是:
cout << *(p+1)
或
cout << *(++p)
答案 3 :(得分:2)
我喜欢这样做:
&p[1]
对我而言看起来更整洁。
答案 4 :(得分:1)
将C和C ++中的“指针类型”想象为在CPU的内存空间中的字节上叠加一个非常长的逻辑单元格行,从字节0开始。每个单元格的字节数取决于指针的“类型”。每个指针类型放置一行,具有不同的单元格宽度。 "int *"
指针放下一行4字节的单元格,因为int的存储宽度是4个字节。 "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字节。)