问题描述
在研究C语言的指针时,我遇到了某些代码。
#include <stdio.h>
int main(void){
double d=5.3;
double *dp;
dp=&d;
printf("%d\n",sizeof(*dp));
printf("%d\n",sizeof(dp));
return 0;
}
使用64位系统的结果为8 8
。
我之所以认为是因为
-
printf("%d\n",sizeof(*dp));
:*dp
指向值,这是一种双重类型,使其打印8
(字节) -
printf("%d\n",sizeof(dp));
:dp
是一个指针变量,在64位系统中为8
字节,在32位系统中为4
byte
我想知道我所理解的是正确的还是我得到了切换1和2的原因。
解决方法
您已经知道了:
sizeof dp == sizeof (double *) == 8 (on your system)
sizeof *dp == sizeof (double) == 8 (on your system)
在您的特定系统上,double
和double *
占用相同的空间。但是,这不一定是正确的。
浮点类型必须能够以最小精度表示最小范围的值-对于double
,浮点类型必须能够表示值至少在 范围内1 x 10-37
至1 x 1037
,并提供至少 10个十进制数字精度。大多数现代系统使用IEEE-754双精度格式,该格式可以满足这些要求,并且恰好占用64位。
指针类型与表示特定类型的对象或函数的地址所需的大小一样大。这可能会受到CPU上地址线数量的影响,无论您使用的是平面内存还是分段内存模型,平台是字节寻址还是字寻址,等等。唯一的要求如下:
-
char *
和void *
具有相同的大小和对齐方式; - 指向合格类型的指针的大小和对齐方式与其指向不合格对等类型的指针(例如,
sizeof (const int *) == sizeof (int *)
)相同。 - 所有指向
struct
类型的指针都具有相同的大小和对齐方式; - 所有指向
union
类型的指针都具有相同的大小和对齐方式;
除此之外,它是敞开的。可能有sizeof (char *) != sizeof (int *)
,sizeof (int *) != sizeof (int (*)[N])
等系统。
在哈佛体系结构中,代码和数据也以不同的地址总线大小保存在物理上分开的内存中,因此对象指针和函数指针的大小可能不同。
说了这么多,您很可能不是从事任何奇特的工作。在大多数现代桌面系统上,所有指针类型都具有相同的大小和表示形式。请注意,并非到处都可以保证。
注意
sizeof
运算符的结果类型为size_t
,它可能(通常是)比int
大,因此您应该使用%zu
转换说明符打印它而不是%d
:
printf( "sizeof *dp == %zu,sizeof (double) == %zu\n",sizeof *dp,sizeof (double) );
请记住,sizeof
是 operator ,而不是函数-如果操作数的类型名称为int
或{{1 }}。