为什么我的homespun sizeof运算符需要char * cast?

时间:2010-04-09 14:43:48

标签: c

以下是在不使用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 - 为什么?

4 个答案:

答案 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使charbyte基本等效(即一个字节是一个字符所需的存储空间),这也是第一个项目占用的字节数。