2010-04-09 82 views
3

下面是找到一个结构的大小,而无需使用sizeof操作符的程序:为什么我的homeopen sizeof运算符需要char *转换?

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

提醒:结构的大小可能不等于其成员(字段)大小的总和。编译器允许在结构中的成员之间插入填充字节。一个例子是在地址上对齐处理器有效的变量来获取。 – 2010-04-09 17:22:06

回答

2

由于指针运算以指向的类型为单位进行工作。例如:

int* p_num = malloc(10 * sizeof(int)); 
int* p_num2 = p_num + 5; 

这里,p_num2没有一点五个字节超越p_num,它分5个整数超越p_num。如果在您的机器上整数是四个字节宽,则存储在p_num2中的地址将比p_num中存储的地址长20个字节。其原因主要是指针可以像数组一样索引。 p_num[5]*(p_num + 5)完全等价,所以指针算术总是以字节为单位是没有意义的,否则p_num[5]会给你一些在第二个整数中间开始的数据,而不是像你那样给你第六个整数期望。

为了移动的字节特定数目超出一个指针,就需要转换指针以指向被保证是完全1个字节宽类型(一个char)。

而且,你这里有一个错误:

printf("\nSIZE : [%d]\nSIZE : [%d]\n", size); 

你有两种格式说明,但在格式字符串后只有一个参数。

2

如果我不使用char *指针,则输出为1 - 为什么?
因为operator-服从与operator+相同的指针算术规则。当您向指针中添加一个指针时,您增加了sizeof(MyStruct),但是如果没有该指针,您将在指针的operator-中将sizeof(MyStruct)的字节差值除以sizeof(MyStruct)

为什么不使用sizeof()内置运算符?

+1

如果确实使用'sizeof',请务必在指向的对象上使用它,而不是指针本身。 'sizeof(p)'会给你一个指针的大小,其中'sizeof(* p)'会给你一个'MyStruct'的大小。 – 2010-04-09 14:52:46

2

因为你想要你的结构的大小以字节为单位。而指针算术隐式使用字体大小。

int* p; 
p + 5; // this is implicitly p + 5 * sizeof(int) 

通过铸造到char *你规避了这种行为。

+1

好吧,'sizeof'返回大小,以'char'存储的大小为单位(即sizeof(char)总是1)。这是典型实现中的字节数,但并不是必需的...... – dmckee 2010-04-09 14:53:08

+0

这是真的,但每当你要求字节类型时,你都会得到无符号字符的答案:) – 2010-04-09 14:56:19

1

指针运算是根据指针类型的大小定义的。这允许(例如)指针算术和数组下标之间的等价性 - *(ptr+n)相当于ptr[n]。当你减去两个指针时,你会看到他们指向的项目数量的差异。投到pointer to char意味着它告诉你这些地址之间的字符数。由于C使得charbyte基本上等同(即一个字节是一个字符所需的存储空间),这也是第一项所占用的字节数。

相关问题