关于sizeof用法的问题

Nav*_*K N 5 c c++ sizeof

问题1

我有一个像这样的结构,

struct foo
{
    int a;
    char c;
};
Run Code Online (Sandbox Code Playgroud)

当我说sizeof(foo),我正在8上机.根据我的理解,int为4个字节,char为1个字节,填充为3个字节.那是对的吗?给定如上所述的结构,我将如何找出将添加多少字节作为填充?

问题2

我知道sizeof可以用来计算数组的大小.大多数情况下,我已经看到使用像(foos是一个数组foo)

sizeof(foos)/sizeof(*foos)
Run Code Online (Sandbox Code Playgroud)

但我发现以下内容也会给出相同的结果.

sizeof(foos) / sizeof(foo)
Run Code Online (Sandbox Code Playgroud)

这两个有什么不同吗?哪一个更受欢迎?

问题3

请考虑以下声明.

foo foos[] = {10,20,30};
Run Code Online (Sandbox Code Playgroud)

当我这样做时sizeof(foos) / sizeof(*foos),它给出了2.但是数组有3个元素.如果我将语句更改为

foo foos[] = {{10},{20},{30}};
Run Code Online (Sandbox Code Playgroud)

它给出了正确的结果3.为什么会发生这种情况?

有什么想法吗..

Jon*_*ler 21

答案1

是的 - 您的计算是正确的.在你的机器,sizeof(int) == 4int必须是4字节对齐.

您可以通过手动添加基本元素的大小并从sizeof()报告的大小中减去该大小来找到有关填充的信息.如果您知道机器上的对齐要求,则可以预测填充.请注意,某些计算机非常繁琐,并且在访问未对齐的数据时会出现SIGBUS错误; 当你访问未对齐的数据时,其他人会更宽松,但会让你失望(他们可能支持' #pragma packed'或类似的东西).通常,基本类型的大小为2(1,2,4,8,16)的幂,并且n字节类型必须是n字节对齐的.此外,请记住,必须填充结构,以便结构数组将所有元素正确对齐.这意味着该结构通常将填充到结构中最严格对齐的构件的尺寸的倍数.

答案2

通常,第一个变体更好; 将数组的基本类型从'foo'更改为'foobar'时,它仍然是正确的.我通常使用的宏是:

#define DIM(x) (sizeof(x)/sizeof(*(x)))
Run Code Online (Sandbox Code Playgroud)

其他人有相同的基本操作其他的名字 - 你可以把我用下来的污染从朦胧而遥远的过去和一些使用基本的名称.

像往常一样,有一些警告.最值得注意的是,您无法将此有意义地应用于函数的数组参数或动态分配的数组(使用malloc()et al或new[]); 你已经适用于数组的实际定义.通常,该值是编译时常量.在C99下,如果数组是VLA - 可变长度数组,则可以在运行时进行评估.

答案3

因为当你没有足够的大括号时初始化的方式.你的'foo'结构必须有两个元素.10和20被分配到第一行; 30和隐含的0被提供给第二行.因此,大小是两个.当您提供子括号时,数组中有3个元素,其中第一个组件的值为10,20,30,第二个组件都为零.