【问题标题】:c structure problemc结构问题
【发布时间】:2010-10-07 06:59:21
【问题描述】:

感谢您对解决我以前的问题的支持。现在我正在研究自指结构。我写了以下代码:

#include <stdio.h>

int main()
{
system("clear");
struct node
{
 int x;
  struct node *next;
} p1;

printf(" \nthe address of node1 = %u",& p1);

printf(" \n\nthe size of node 1 = %d",sizeof( p1));
printf("\n\n the size of info part = %d",sizeof(p1.x));
printf("\n\n the size of pointer part = %ld",sizeof(p1.next));
printf("\nthe size of node is = %d\n",sizeof(struct node));
return;
}

编译后的程序很少出现警告,例如:

警告:格式“%u”需要类型 'unsigned int',但参数 2 有 输入‘结构节点*’

每次我用指针做某事时都会产生这样的警告。问题是什么?我不知道。谁能解释为什么它会发生在 Linux 上(特别是)?

我的第二个问题是,当我运行程序时,它显示结构 16 的大小,而 int 占用 4 个字节(Ubuntu 10)& 指针为 8 个字节。那为什么它显示结构大小为 16 字节?

【问题讨论】:

    标签: c struct


    【解决方案1】:

    在 C99 中,使用“%zd”打印size_t

    在其他地方,只需将sizeof() 的结果转换为int;你不会溢出任何东西。

    在 C99 中打印指针,如果您不喜欢 %p 的默认格式:

    #include <inttypes.h>
    
    printf("Pointer = 0x%" PRIXPTR "\n", (uintptr_t)&something);
    

    uintptr_t 类型保证足够大以容纳指针。

    您的尺寸问题是因为对齐要求; 8 字节指针必须与 8 字节对齐以获得最佳性能(在某些机器上,以避免崩溃)。因此,该结构的长度必须是 8 字节的倍数,而 16 是大于 12 字节的 8 的最小倍数。您还将在结构的两个部分之间进行一些填充 - 实际上是 4 个字节的填充。您可以使用 &lt;stddef.h&gt; 中的 offsetof() 宏来证明这一点。

    【讨论】:

    • sizeof()sizeof? ++(i) 还是 ++i?顺便说一句,用intptr_t 格式化指针值的好技巧。 +1
    • @schot:我只是在指出sizeof() 运算符——它显然需要一个参数,即返回大小的东西。我知道它并不总是需要在参数周围加上括号,但由于它总是在参数周围使用括号,所以我总是在参数周围使用括号。
    • 这只是个小玩笑。 return (0);
    • 当 sizeof “需要”括号时,类型本身需要它们(如演员表):sizeof object ... sizeof (int)object ... sizeof (int)
    【解决方案2】:

    %p 是指针的格式字符串,这是您传递给第一个 printf 的内容。

    【讨论】:

      【解决方案3】:

      许多 CPU 架构无法处理,或者在处理任意地址方面效率很低。

      你的架构,我猜是 x86_64,想要访问至少 8 字节块的内存。

      所以,12 个字节等于一个半 8 字节块 - 不好。 然后发生的是,编译器在最后用虚拟数据填充结构,直到它适合 8 字节块,在这种情况下额外 4 个字节,总共 16 个字节。

      同样适用于不同的处理器,但对齐方式不同。一些 CPU 甚至完全无需对齐也能正常工作,但大多数现代处理器在对齐的情况下效果最佳。

      正如其他人所指出的,例如使用 %p 进行指针打印。

      对于size_t printfs,如果不能使用 C99 和 %zd,请使用 %lu 并转换为 (unsigned long)

      【讨论】:

        【解决方案4】:

        这个程序在 LINUX 发行版 Fedora12 下运行良好。 它产生正确的输出。

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 2021-12-03
          • 2017-06-14
          • 2017-06-08
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多