3.9 異質的數據結構
C
語言提供了兩種將不同類型的對象組合到一起創建數據類型的機制:
結構(structure
),用關鍵字struct
來聲明,將多個對象集合到一個單位中;
聯合(union
),用關鍵子union
來聲明,允許用幾種不同的類型來引用一個對象。
3.9.1 結構
C
語言的struct
聲明創建一個數據類型,將可能不同類型的對象聚合到一個對象中。用名字來引用結構的各個組成部分。
示例:
另外,我們可以在一條語句中既聲明變量又初始化它的手段:
struct rect r = {0, 0, 10, 20, 0xFF00FF};
返回長方形面積的示例:
long area(struct rect *rp)
{
return (*rp).width * (*rp).height;
}
rp -> width
等價於 (*rp).width
。
示例:
struct rec {
int i;
int j;
int a[2];
int *p;
};
示例:
Registers: r in %rdi
r->j = r->i
movl (%rdi), %eax Get r->i
movl %eax, 4(%rdi) Store in r->j
Registers: r in %rdi, i in %rsi
&(r->a[i])
leaq 8(%rdi, %rsi, 4), %rax Set %rax to &r->a[i]
Registers: r in %rdi
r->p = &r->a[r->i + r->j ];
movl 4(%rdi), %eax Get r->j
addl (%rdi), %eax Add r->i
cltq Extend to 8 bytes
leaq 8(%rdi, %rax, 4), %rax Compute &r->a[r->i + r->j]
movq %rax, 16(%rdi) Store in r->p
3.9.2 聯合
聯合允許以多種類型來引用一個對象。
考慮如下聲明:
struct S3
{
char c;
int i[2];
double v;
}
union U3
{
char c;
int i[2];
double v;
}
可以看出 類型 union U3 *
的指針 p
,p->c
、p->i[0]
和p->v
引用的都是數據結構的起始位置。一個聯合的總的大小等於它最大字段的大小。
3.9.3 數據對齊
許多計算機系統對基本數據類型的合法地址做出了一些限制,要求某種類型對象的地址必須是某個值K(通常是2
、4
或8
的倍數)。這種對齊限制簡化了形成處理器和內存系統之間接口的硬件設計。
K | 類型 |
---|---|
1 | char |
2 | short |
4 | int, float |
8 | long, double,chat* |
例如跳轉表的彙編聲明包含下列指令:
.align 8
這就保證了它後面的數據的起始地址是 8 的倍數。
示例:
藍色部分爲爲對齊而填充的地址空間。