C语言 从指针中查找结构的正确大小,而无需创建对象



如果标题令人困惑,请抱歉。这是我的结构:

struct l_list{
   int number;
   char *name;
   double value;
   struct l_list *next;
};
typedef struct l_list *PhoneBook;

主要功能:

int main(void){
   printf("%un", sizeof(struct l_list));
   PhoneBook person1;
   printf("%un", sizeof(*person1));
   printf("%un", sizeof(PhoneBook));
   return 0;
}

输出为:

20
20

我知道PhoneBook显示 4 个字节,因为它只是指针的大小,但是您如何从typedef PhoneBook中找到实际结构的大小?

您可以使用

以下内容:

printf("%zun", sizeof( *(PhoneBook)NULL ) );

重要的问题是为什么上述有效,您不是在NULL指针上执行间接寻址,这将是未定义的行为吗?不,您不是,因为除了可变长度数组之外sizeof根本没有计算。如果我们看一下 C99 草案标准部分 6.5.3.4 运算符的大小2 段说(强调我的):

sizeof 运算符产生其操作数的大小(以字节为单位),这可能是一个 表达式或类型的括号名称。大小由类型确定 操作数。结果是一个整数。如果操作数的类型是可变长度数组类型,则计算操作数;否则,不计算操作数,结果为整数常量。

此外,我们在第5段中看到以下例子,它证实了这一解读:

double *dp = alloc(sizeof *dp);

在编译时,确定表达式的类型以计算结果。我们可以通过以下示例进一步证明这一点:

int x = 0 ;
printf("%zun", sizeof( x++ ));

这不会增加x.

注意%zusizeof 结果的独立于平台的格式说明符。

你可以做:

printf("%un", sizeof(*(PhoneBook) NULL) );

我会这样做:

typedef struct l_list{
    int number;
    char *name;
    double value;
   struct l_list *next;
} PhoneBook, *PPhoneBook;

然后,您的电话簿是结构l_list的typedef,而不是指针。这更有意义。PPhoneBook(或您选择的任何其他名称)是电话簿*的typedef。

然后你可以做:

sizeof(PhoneBook)

它将为您提供电话簿对象的正确大小。

或者你可以做:

sizeof(PPhoneBook)

它将返回 4 个字节,即指针大小。请注意,将指针隐藏在非指针式 typedef(如 PPhoneBook)后面并不总是可取的。它可能会使您的代码混乱。但是,如果这是您想要的,这就是如何做到的!

最新更新