以下是在不使用sizeof运算符的情况下查找结构大小的程序:
struct MyStruct
{
int i;
int j;
};
int main()
{
struct MyStruct *p=0;
int size = ((char*)(p+1))-((char*)p);
printf("\nSIZE : [%d]\nSIZE : [%d]\n", size);
return 0;
}
为什么需要对char *进行类型转换?
如果我不使用char *指针,输出为1 - 为什么?
答案 0 :(得分:2)
因为指针算法以指向的类型为单位工作。例如:
int* p_num = malloc(10 * sizeof(int));
int* p_num2 = p_num + 5;
此处,p_num2
未将五个字节指向p_num
以外,它将五个整数指向p_num
以外。如果在您的机器上,整数宽度为4个字节,则p_num2
中存储的地址将比p_num
中存储的地址多20个字节。其原因主要是指针可以像数组一样索引。 p_num[5]
完全等同于*(p_num + 5)
,因此指针算法始终以字节为单位是没有意义的,否则p_num[5]
会给你一些在第二个中间开始的数据整数,而不是像你期望的那样给你第六个整数。
为了在指针之外移动特定数量的字节,您需要将指针强制转换为指向保证正好1字节宽的类型(char
)。
此外,您在此处有错误:
printf("\nSIZE : [%d]\nSIZE : [%d]\n", size);
您有两个格式说明符,但格式字符串后只有一个参数。
答案 1 :(得分:2)
如果我不使用char *指针,则输出为1 - 为什么?
因为operator-
遵循operator+
所做的相同指针算术规则。当你向指针添加一个时,你增加了sizeof(MyStruct)
,但没有强制转换,你将sizeof(MyStruct)
中的字节差除以operator-
作为指针。
为什么不使用内置的sizeof()
运算符?
答案 2 :(得分:2)
因为你想要结构的大小以字节为单位。指针算术隐式使用类型大小。
int* p;
p + 5; // this is implicitly p + 5 * sizeof(int)
通过强制转换为char *来规避这种行为。
答案 3 :(得分:1)
指针算法是根据指针类型的大小定义的。这允许(例如)指针算法和数组下标之间的等价 - *(ptr+n)
等同于ptr[n]
。当你减去两个指针时,你得到的差异就是他们指向的项目数量。转换为pointer to char
意味着它会告诉您这些地址之间的字符数。由于C使char
和byte
基本等效(即一个字节是一个字符所需的存储空间),这也是第一个项目占用的字节数。