C 指针如何引用多字节变量?

C 指针如何引用多字节变量?,c,pointers,memory-address,C,Pointers,Memory Address,我对C指针如何实际引用变量的内存地址感到困惑。我可能在这里漏掉了一些东西,但是,例如,如果一个int是32位(就像在C中一样),那么它将被存储在4个字节中 如果我没有弄错的话,那么每个内存地址的大小往往是一个字节,因为它们通常是可寻址内存的最小单元。如果一个int占4个字节,那么它不是有4个内存地址吗?(因为它存储在4个8位内存地址上) 如果是这种情况,那么为什么指针只包含一个内存地址?(或者在打印时仅显示一个,如果它容纳更多?)。这仅仅是存储int的第一个地址吗?(假设它们是连续存储的) 我试

我对C指针如何实际引用变量的内存地址感到困惑。我可能在这里漏掉了一些东西,但是,例如,如果一个int是32位(就像在C中一样),那么它将被存储在4个字节中

如果我没有弄错的话,那么每个内存地址的大小往往是一个字节,因为它们通常是可寻址内存的最小单元。如果一个int占4个字节,那么它不是有4个内存地址吗?(因为它存储在4个8位内存地址上)

如果是这种情况,那么为什么指针只包含一个内存地址?(或者在打印时仅显示一个,如果它容纳更多?)。这仅仅是存储int的第一个地址吗?(假设它们是连续存储的)


我试图在网上找到答案,但这只会导致进一步的混乱。

是的,从技术上讲,您描述的
int
将有四个可寻址字节。但是指针指向第一个字节,从中读取
int
将读取该字节和随后的三个字节以构造
int

如果您试图从指向其他三个字节中的一个字节的指针读取数据,至少您会得到一个不同的值(因为它将读取一个
int
的剩余字节和它旁边的其他字节),并且在某些需要对齐读取的体系结构上(因此四个字节的值必须从可被四整除的地址开始),你的程序可能会崩溃


这种语言试图保护你不去读像那样的未对齐的指针;如果您有一个
int*
,并向其中添加
1
,它不会将原始地址增加1,而是将原始地址增加
sizeof(int)
(对于您的情况,
4
),因此,指向
int
数组的指针可以逐个值遍历数组值,而不会意外地读取逻辑上部分来自一个
int
,部分来自其邻居的值。

指针指向类型的起始地址,如果您搜索“指针大小”它将向您展示它通常依赖于您的cpu体系结构,而不是您的基本类型或对象


虽然问题是关于c++,但是一个字节是最小的可寻址单元,但这并不意味着一个地址只有一个字节。否则,您只能寻址256个字节!指针的大小通常为4或8字节


变量的地址是指它的第一个字节的地址。剩余字节被理解为紧随其后,字节数是数据类型的一部分。

具体取决于机器的实际架构(什么样的CPU、什么样的内存等),因此我假设您关心的是一个现代32位处理器,其中int和指针都占用四个字节的内存。请记住,当整数是两个字节,指针是8个字节时,同样的想法也适用,但我们必须只关注一组示例

话虽如此,您完全正确,一个int使用四个连续的内存字节,这意味着它有四个独立的内存地址,指针只保存一个地址——它是int的第一个字节的地址

因此,CPU有一条读取int的指令。该指令获取int的第一个字节的地址,并读取整个int-全部四个。这就是为什么你只需要一个地址就可以读取整个整数。所以
inti=42
把一个四字节的整数读入i,这个值被解释为42

但指针也是一个整数,其中的值是内存地址,因此可以完全以相同的方式读取。因此,
int*p=42
将一个四字节整数读入p,该值被解释为内存地址42的平均值


当您开始考虑字节的存储顺序时,所有这些都会变得复杂起来,因此我们不会讨论这个问题(但是,如果您想知道术语是endianness-请参见)

我明白了。这是否意味着变量总是连续存储?(至少在C中是这样)。@Jr795:我从未见过不连续存储它的体系结构,而且我非常确定C标准库的某些部分根据其API的性质暗示了连续存储(例如,
memcpy
不能在
int
的数组上工作,除非
int
s保证由
sizeof(int)组成)
连续字节)。字节的顺序不能保证(如果您感兴趣,请阅读),但它总是连续存储的。基本上,您缺少的是
int
是4个连续字节,而不仅仅是任何4个字节。(顺便说一句,您在这里提到的是许多语言的列表和数组类型之间差异的关键,例如Python的
list
np.ndarray
)是的,int占用4个内存地址,但它们是连续的。也就是说,如果一个int的地址是,比如说5000,那么组成该int的字节位于地址5000、5001、5002和5003。当您执行类似于
x=*ip
的操作时,它会将指针地址中的四个连续字节复制到变量的地址。关于您的第一段:我认为OP并不是说他们认为指针的大小只有一个字节,只是他们认为指针引用了特定的字节(这是正确的,但读取它读取的字节数足以满足所讨论的类型)。