如果指针指向数组或对象,那么它的值是多少

What is the value of a pointer if it is pointing to an array or an object?

本文关键字:多少 指针 数组 对象 如果      更新时间:2023-10-16

我知道我的问题可能很基本,但我想知道对于那些在内存中有多个单元格的对象,比如数组和用户定义的对象(它们在内存中需要多个单元格,因此在内存中具有连续地址的范围),指针对这类对象到底意味着什么?是C++中的变量包含了这些对象在内存中的地址(逻辑上不为真,因为这些对象占据了内存中的多个单元,因此具有连续地址范围),还是说指向这些对象的指针只是这些对象的起始地址(更合理)。

请帮我理解;如果你不相信我对C++指针定义的解释,给我一个正确的。

在大多数C++教程中,它说指针只包含内存中其他变量的地址。

假设您有一个像一样声明和初始化的变量a

int a = 5;

然后创建一个指针,并使用运算符&:的地址使int指向a

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的内容。

如果我(作为编译器)知道int(在这个特定系统上)长4个字节,指向int的指针只需要告诉我int的"开始"在哪里:我只需要读取它和接下来的3个字节!

对于像数组这样的较大数据结构,情况也是如此:如果我知道数组从哪里开始,我就知道我可以通过在地址中添加一个项目的大小来访问后续的每个元素。例如,如果我有一个从地址100开始的int a[],而int是4个字节,那么

CCD_ 17所以字节228到231是a[32]处的整数。

让它稍微容易使用的是,编译器为我们抽象了不同大小的数据类型。如果我在整数指针上加1,地址实际上会增加4!这是因为我很少(几乎从不)想读半个整数:我更可能希望依次看一系列整数。

从这里开始

你电脑的内存可以想象成一连串的内存单元格,每个单元格都是计算机管理的最小大小(一个字节)。这些单字节存储单元是以连续的方式编号的,因此因为,在任何内存块中,每个单元都与上一个加一。

这样,每个单元都可以很容易地定位在存储器中,因为它具有唯一地址,并且所有存储器单元遵循连续模式。例如,如果我们正在寻找1776号细胞,我们知道它正在移动正好在1775和1777单元格之间,正好有一千个单元格776之后和2776之前正好一千个细胞。]1

这可能有助于想象操作系统的内存布局此处

当您指定一个指针时,您还指定它将保持的类型指针,例如int*在这种情况下,编译器将保留4个字节(通常是int的大小),并以小端/大端格式存储值。

我认为您是正确的,它将有一个指向起始单元格的指针,如果您说p++,那么编译器将增加4个字节并指向其他地址。

如果你想引用p指向的下一个单元格,那么你可能需要读取地址(HEX地址)并对其进行增量和尊重。

对于数组,指针的含义与其他所有指针的含义完全相同。

一个指针正好指向一个对象的位置(作为对展开指向数组异议的指针的回应:这个一个对象也可能是一个数组)。它不知道对象数组的大小(如果有)(也不在乎)1
创建一个指向单个值的指针并将其作为某种大小的数组进行访问是完全可能的,尽管这既不明确也不明智(可能会崩溃)。使用指向大小为5的数组的指针并访问第10个元素也是完全可能的。同样,这没有意义,可能会崩溃,但没有什么可以阻止你这样做(除了compiletime常量索引,至少一些编译器可能会发出警告)。指针不知道。

对于一个结构,指针知道该结构在内存中的位置,不多也不少。除此之外,编译器还知道其他详细信息,例如成员到此基地址的偏移量。但是,此信息绑定到用于取消引用指针的类型(而不是指针本身!)
因此,如果您使Banana指向汽车(通过投射、意外或算术),通常可以通过Banana指针访问Car对象。当然,这没有任何意义,但这是可能的。指针不知道有什么区别,编译器会像"一样"行事。


1是的,如果它是指向数组的指针,编译器就会知道数组的大小。但这只对类型正确性重要。尝试将5的数组分配给4的指针对数组时会出现编译错误,因为它们是不同的。但这与指针无关。指针仍然不知道数组的大小,它仍然不知道是一个数组还是一个数组数组。你仍然可以以任何一种方式使用它(可能会产生破坏性效果),而且没有任何逻辑可以阻止你造成伤害。