我知道我的问题可能非常基本,但我想知道在内存中有多个单元格的对象,比如数组和用户定义的对象(在内存中需要多个单元格,因此具有内存中的连续地址),指针对于这种对象真正意味着什么?它是C ++中的变量,它包含内存中这些对象的地址(逻辑上不正确,因为这些对象在内存中占用了多个单元,因此具有连续地址范围),或者说,指向这些对象的指针只是开始这些对象的地址(更合理)。
请帮助我理解;如果你不相信我对C ++指针定义的解释,请给我一个正确的。
在大多数C ++教程中,它说指针只包含内存中其他变量的地址。
答案 0 :(得分:3)
假设您有一个变量a
已声明并初始化为
int a = 5;
然后使用address-of运算符a
创建一个指针并使int 指向到&
:
int* pointer_to_a = &a;
pointer_to_a
的实际值是a
在内存中的地址。但编译器知道它是一个指针,因此您可以使用pointer_to_a
使用解除引用运算符a
访问*
的内容:
*pointer_to_a = 10;
std::cout << "a = " << a << '\n';
上面将打印10
,因为您设置了pointer_to_a
指向10
的位置的内容。
答案 1 :(得分:2)
如果我(作为编译器)知道int
是(在此特定系统上) 4个字节长,指向int
的指针只需要告诉我int
的“开始”是:我只需要阅读它和接下来的3个字节!
对于像数组这样的大型数据结构,情况也是如此:如果我知道我的数组在哪里开始,我知道我可以通过将一个项的大小添加到地址来访问每个后续元素。例如,如果我从地址100开始有int a[]
,而int
是4个字节,那么
a[32] = (address of a) + (32 * size of int) = 100 + 128 = 228
所以字节228到231是a [32]处的整数。
这使得稍微容易使用的是编译器为我们抽象出不同大小的数据类型。如果我将1添加到整数指针,地址实际上会增加4!这是因为我很少(几乎从不)想要读取半个整数:我更希望依次查看一系列整数。
答案 2 :(得分:1)
来自here
计算机的内存可以被想象成一连串的记忆 单元格,每个计算机管理的最小尺寸(一个字节)。 这些单字节存储单元以连续方式编号,因此 因为,在任何内存块中,每个单元格都具有相同的数字 前一加一。
这样,每个单元格都可以很容易地位于内存中,因为它具有 一个唯一的地址和所有的存储单元遵循连续的模式。 例如,如果我们正在寻找1776单元格,我们知道它正在发展 恰好在细胞1775和1777之间,正好是一千个细胞 在776之后,在细胞2776之前只有一千个细胞。] 1
答案 3 :(得分:0)
这可能有助于想象操作系统的内存布局 Here
指定指针时,还指定它将保持的类型指针,例如INT * 在这种情况下,编译器将保留4个字节(通常为int的大小)并以little-endian / big-endian格式存储该值。
我认为你是正确的,它只有一个指向起始单元格的指针,如果你说p ++,那么编译器将增加4个字节并指向其他地址。
如果你想引用p指向的下一个单元格,那么认为你可能需要读取地址(HEX地址)并增加和推导它。
答案 4 :(得分:-1)
对于数组,指针与其他所有指针完全相同。
指针指向一个对象的位置(回复unwind的指针到数组的异议:这个一个对象也可能是一个数组),不多也不少。如果有一个(并且不关心),它不知道对象数组的大小。 1
完全可以创建一个指向单个值的指针,并将其作为一个大小的数组访问,尽管这既不明确也不明智(它可能会崩溃)。完全可以使用指向大小为5的数组的指针并访问第10个元素。同样,这没有意义,可能会崩溃,但没有什么能阻止你这样做(除了编译时常量索引,至少有些编译器可能会发出警告)。指针不知道。
对于一个结构,指针知道结构在内存中的位置,不多也不少。最重要的是,编译器知道其他详细信息,例如成员到此基址的偏移量。但是,此信息绑定到用于取消引用指针的类型(而不是指针本身!)。
因此,如果让Car
指向汽车(通过演员,偶然或算术),通常可以通过Banana
指针访问Banana
对象。当然这没有任何意义,但它是可能的。指针不知道差异,编译器将“好像”。
<小时/> 1 是的,如果它是一个指向数组的指针,编译器就知道那个数组的大小。但这只对类型的正确性有影响。尝试将数组5指定给指向数组4的指针时会出现编译错误,因为它们是不同的东西。但这与指针无关。 指针仍然不知道数组的大小,它仍然不知道是否有一个数组或一个数组数组。您仍然可以以任何一种方式使用它(可能是灾难性的效果),并且没有任何逻辑可以阻止您造成伤害。