C编程(结构声明)

时间:2015-11-17 20:33:17

标签: c

当我们宣布说:

int array[2];

array =“保存前32位的地址”,即它保持&array[0]。 所以“数组”是一个指针。 但是当我们声明一个结构例如:

typedef struct x 
{
    int y;
    int array[2];
}

为什么这个结构的大小是16个字节?不应该是8个字节,因为“数组”是一个指针?我很困惑?

4 个答案:

答案 0 :(得分:3)

首先,array这里是一个数组,在结构中分配了空间以包含该数组的所有元素。它不是指向结构外部空间的指针。关于一切占用多少空间,最简单的方法是查看这里发生的事情只是在这里运行一些sizeof检查:

#include <stdio.h>
typedef struct x 
{
    int y;
    int array[2];
};

int main(void) {
    struct x test1;
    printf("sizeof(int) %zu \n", sizeof(int));
    printf("sizeof(test1) %zu \n", sizeof(test1));
    printf("sizeof(test1.array) %zu", sizeof(test1.array));
    return 0;
}

在ideone上运行时,你会得到4,12和8。 http://ideone.com/pKBe1X 在我运行的其他系统上,我得到了类似的结果,这使我相信在您的机器上使用您的特定编译器选项时,您的结构中添加了一些填充。

如果sizeof(test1.y) + sizeof(test1.array) != sizeof(test1)那么你添加了一些填充。添加诸如#pragma pack(ms编译器)或__attribute__((__packed__))(gcc)之类的内容可能会改变这一点。

编译器添加填充的原因是因为在您的特定系统上,在内存中具有此特定对齐(16字节的倍数)的数据结构访问数据速度方面可能会有一些好处。有关详情,我建议您查看Wikipedia page on data structure alignment

答案 1 :(得分:2)

  

当我们宣布说:

     

int array[2];

     

array =“保存前32位的地址”,即它保持&amp; array [0]。

不。一点也不。声明一个2元素数组时,得到的结果如下:

     +---+
arr: |   | arr[0]
     +---+ 
     |   | arr[1]
     +---+

与标识符arr关联的对象int的2元素数组,而不是指针。在大多数情况下,表达式 arr将被转换(“衰减”)为“指向int的指针”类型的表达式。

struct类型的实例如下所示:

       +---+
    y: |   | 
       +---+
array: |   | array[0]
       +---+
       |   | array[1]
       +---+

成员的大小总和只有12个字节,因此在array之后必须有一些填充以满足8或16字节的对齐限制。

答案 2 :(得分:1)

数组具有指针的某些特征,但它本身不是指针。也就是说,你不能把它指向其他地方。它总是指向它分配的元素。

因此包含数组的struct不包含指针。在您的情况下,它包含两个int s加上非数组int。显然你的CPU是32位的,所以它包含12个字节的数据(三个4字节的int)。但是添加了一些结构填充以使每个项目落在8字节边界上(用于CPU访问效率)。这使它长16个字节。有一些编译器选项可以“打包”结构,这样就不会发生填充。通常#pragma pack(0)在文件中的一行上,或编译器命令行选项。

答案 3 :(得分:1)

这给出了关于int和char的打包效果的想法

#include <stdio.h>

#pragma  pack (push, 1)
typedef struct {
    int a;
    int b[2];
}TEST1;

typedef struct {
    int a;
    int b[2];
    char c;
}TEST2;
#pragma pack(pop)

typedef struct {
    int a;
    int b[2];
}TEST3;

typedef struct {
    int a;
    int b[2];
    char c;
}TEST4;

int main(){
    printf(" ==== PAKED =====\t==== DEFAULT =====\n");
    printf("sizeof(TEST1)=%d \tsizeof(TEST3)=%d\n",sizeof(TEST1),sizeof(TEST3));
    printf("sizeof(TEST2)=%d \tsizeof(TEST4)=%d\n\n",sizeof(TEST2),sizeof(TEST4));

   return 0;
}

我系统上的输出(AMD 64对于最好奇的人;))

 ==== PAKED =====       ==== DEFAULT =====
sizeof(TEST1)=12        sizeof(TEST3)=12
sizeof(TEST2)=13        sizeof(TEST4)=16

Press any key to continue...