簡體   English   中英

C編程(結構聲明)

[英]C programming ( Declaration of structs )

當我們宣布說:

int array[2];

array =“保存前32位的地址”,即它保持&array[0] 所以“數組”是一個指針。 但是當我們聲明一個結構例如:

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

為什么這個結構的大小是16個字節? 不應該是8個字節,因為“數組”是一個指針? 我感到很困惑 ?

首先登場的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 compiler)或__attribute__((__packed__)) (gcc)之類的東西將可能會改變這一點

編譯器添加填充的原因是因為在您的特定系統上,在內存中具有此特定對齊(16字節的倍數)的數據結構訪問數據速度方面可能會有一些好處。 有關更多信息,我建議您查看有關數據結構對齊Wikipedia頁面

當我們宣布說:

int array[2];

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

不。 一點也不。 聲明一個2元素數組時,得到的結果如下:

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

與標識符arr關聯的對象int的2元素數組,而不是指針。 在大多數情況下, 表達式 arr將被轉換(“衰減”)為“指向int ”的類型的表達式。

struct類型的實例如下所示:

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

成員大小的總和只有12個字節,因此在array之后必須有一些填充以滿足8或16字節的對齊限制。

數組具有指針的某些特性,但它本身不是指針。 也就是說,你不能把它指向其他地方。 它總是指向其分配的元素。

所以包含數組的struct不包含指針。 在您的情況下,它包含兩個int和非數組int。 顯然你的CPU是32位的,所以它包含12個字節的數據(三個4字節的int)。 但是添加了一些結構填充以使每個項目落在8字節邊界上(用於CPU訪問效率)。 這使它長16個字節。 有一些編譯器選項可以“打包”結構,這樣就不會發生填充。 通常#pragma pack(0)在文件中單獨一行,或者是編譯器命令行選項。

這給出了關於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...

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM