我以为指针只是保存内存地址?
是的,但是您可以使用该内存地址进行操作。特别是 C++ 允许一种称为“指针算法”的东西,它允许您使用内存地址来获取相对于您已经拥有地址的内存的其他内存的地址。例如,如果您有一个内存地址,您可以获得紧随其后的内存地址。
(方块是内存位置)
☐
☐
☐ ← I have the address of this memory in variable A
☐ ← I would like to get the address of this memory location and to store it in X
☐
☐
☐
int *A = ...;
int *X = A + 1; // compute the address of the next memory location
所以数组是一系列内存位置。要访问数组的任何元素,您只需获取您拥有的地址,计算您要访问的元素的地址,然后使用该新地址。
int *A = new int[10];
int *X = A + 5; // get the address of the memory five locations past where A points to
*X = 999;
您不必将计算的地址存储在变量中:
int *A = new int[10];
*(A+5) = 999;
C++ 提供了语法的简写*(A+5)
,这是数组索引运算符:
int *A = new int[10];
A[5] = 999;
有趣的是,数组索引运算符实际上只是这个*(A+5)
表达式的简写。由于您可以翻转操作数并且*(5+A)
您可以对数组索引运算符执行相同的操作:
5[A] = 999;
你不应该这样做,因为它不是很可读。
关于指针的另一件事:Java 有指针。当你这样做
String s = new String();
在 Javas
中是一个指针。Java 只是试图隐藏这个事实,同时它需要比 C++ 更大程度地使用指针。Java 没有指针算法,您不必像在 C++ 中那样在 Java 中手动取消引用指针。但请考虑:
List<String> l = new List<String>();
List<String> m = l; // Do I have two lists, l and m, that can be modified independently? Or do I have two entities, l and m, that both refer to the same List object?
请记住您在 Java 中遇到的那些空指针异常。
如果您一直在使用 Java,那么您已经在使用指针。它们在 C++ 中并没有什么不同,但它们在 C++ 中是直接可见和显式的,而不是像 Java 那样隐藏得很差。