我只是想知道sizeof
16 位和 32 位系统的指针会返回什么
printf("%d", sizeof(int16 *));
printf("%d", sizeof(int32 *));
谢谢你。
简短回答:在 32 位 Intel 386 上,您可能会看到这些返回 4,而针对 16 位 8086,您很可能会看到 2 或 4,具体取决于您选择的内存模型。
细节
第一个标准 C 对指针没有任何特殊要求,只是它们需要能够“指向”给定变量,并且指针运算需要在给定变量的数据区域内工作。即使是具有某种奇异指针表示的 C 解释器也是可能的,并且鉴于这种灵活性,指针确实可能是任何大小,具体取决于您的目标。
然而,通常编译器确实通过内存地址表示指针,这使得 C 标准未定义的几个操作“通常工作”。编译器如何选择表示指针的方式取决于目标架构:编译器编写者显然选择了既有用又高效的表示。
有用表示的一个例子是 Harward 架构微上的通用指针。它们允许您同时处理代码和数据 ram。在 8 位微控制器上,它们可能被编码为一个类型字节加上 2 个地址字节,这显然意味着每当您取消引用一个这样的指针时,都必须发出更复杂的代码才能从适当的位置加载内容。
这为有效表示提供了一个很好的例子:那么为什么不使用特定的指针呢?一个指向代码存储器,另一个指向数据存储器?只需 2 个字节(假设 8051 等 8 位微控制器通常使用 16 位地址空间),无需按类型选择。
但是你有多种类型的指针,嗯(同样是 8051:你可能还会有至少一种额外类型的指针指向它的内部 RAM...)。然后程序员需要考虑他需要使用哪种特定的指针类型。
当然,尺寸也不同。在这个以 8051 为目标的假设编译器上,您将有一个 3 字节的通用指针类型、一个 2 字节的外部数据存储器指针类型、一个 2 字节的代码存储器指针和一个 1 字节的内部 RAM 指针类型。
另请注意,这些是指针的类型,而不是它们指向的数据类型(函数指针在这里有点偏离,因为指针是函数指针这一事实意味着它与数据指针的类型不同,但没有任何指针具体语法区别只是它指向的数据类型是函数类型)。
回到你的 16 位机器,假设它是 8086:
如果您使用某种内存模型,而编译器假定您只有一个数据段,那么如果您没有明确声明一个near
或far
. 否则,默认情况下您将获得 4 字节指针。2 字节指针的表示通常只是 16 位偏移量,而对于 4 字节指针,它是一个段:偏移量对。您始终可以应用near
orfar
说明符来显式地使您的指针成为一种或另一种类型。
(near
指针如何在也使用far
指针的程序中工作?只需编译器生成一个默认数据段,并且所有near
s 都位于其中。编译器可能只是永久地或至少大部分时间拥有ds
段寄存器填充了默认数据段,因此访问near
s指向的数据可以更快)
a 指针的大小取决于架构。准确地说,它取决于该架构中使用的地址的大小,它反映了访问内存的总线系统的大小。
例如,在 32 位架构上,地址的大小为 4 个字节:
sizeof (void *) == 4 Bytes.
在 64 位上,地址大小为 8 个字节:
sizeof (void *) == 8 bytes.
请注意,所有指针的大小都与类型相互依赖。因此,如果您执行代码,int16
指针的大小和指针的大小int32
将相同。
但是,16 位系统上的指针大小应该是 2 个字节。通常,16 位系统的内存非常少(几兆字节),而 2 个字节足以寻址其所有位置。更准确地说,使用 16 位指针,您可以拥有的最大内存约为 65 KB。(与当今计算机的内存量相比,确实很少)。