?
Dieses Dokument verwendet PHP-Handbuch für chinesische Websites Freigeben
C程序創(chuàng)建,銷毀,訪問(wèn)和操作對(duì)象。
C中的對(duì)象是執(zhí)行環(huán)境中的數(shù)據(jù)存儲(chǔ)區(qū)域,其內(nèi)容可以表示值(當(dāng)解釋為具有特定類型時(shí),值是對(duì)象內(nèi)容的含義)。
每個(gè)對(duì)象都有。
大?。梢杂胹izeof來(lái)確定)
對(duì)齊要求(可以通過(guò)alignof來(lái)確定)(因?yàn)镃11)
存儲(chǔ)時(shí)間(自動(dòng),靜態(tài),分配,線程本地)
壽命(等于存儲(chǔ)時(shí)間或臨時(shí))
有效的類型(見(jiàn)下文)
價(jià)值(可能是不確定的)
可選地,表示該對(duì)象的標(biāo)識(shí)符
對(duì)象由聲明,分配函數(shù),字符串文字,復(fù)合文字以及通過(guò)返回具有數(shù)組成員的結(jié)構(gòu)或聯(lián)合的非左值表達(dá)式創(chuàng)建。
除了位字段,對(duì)象由一個(gè)或多個(gè)字節(jié)的連續(xù)序列組成,每個(gè)字節(jié)由CHAR_BIT
位組成,可以復(fù)制memcpy
到一個(gè)類型的對(duì)象中unsigned char[n]
,其中n
對(duì)象的大小就是這樣。結(jié)果數(shù)組的內(nèi)容被稱為對(duì)象表示。
如果兩個(gè)對(duì)象具有相同的對(duì)象表示形式,則它們會(huì)相等(除非它們是浮點(diǎn)型NaN)。相反的情況并非如此:比較相等的兩個(gè)對(duì)象可能具有不同的對(duì)象表示,因?yàn)閷?duì)象表示的每一位都不需要參與該值。這些位可用于填充以滿足對(duì)齊要求,用于奇偶校驗(yàn),指示陷印表示等。
如果對(duì)象表示不表示對(duì)象類型的任何值,則稱為陷阱表示。除了通過(guò)字符類型的左值表達(dá)式讀取陷阱表達(dá)以外的任何其他方式都是未定義的行為。即使任何特定的成員是一個(gè)結(jié)構(gòu)或聯(lián)合的價(jià)值,也不是陷阱表示。
對(duì)于類型為char,signed char和unsigned char的對(duì)象,要求對(duì)象表示的每一位參與值表示,并且每個(gè)可能的位模式表示不同的值(不允許填充,陷阱位或多個(gè)表示形式)。
每個(gè)對(duì)象都有一個(gè)有效的類型,它確定哪些左值訪問(wèn)是有效的,哪些違反了嚴(yán)格的別名規(guī)則。
如果對(duì)象是由聲明創(chuàng)建的,則該對(duì)象的聲明類型是對(duì)象的有效類型。
如果對(duì)象是由分配函數(shù)(包括realloc
)創(chuàng)建的,則它沒(méi)有聲明類型。這樣的對(duì)象獲得如下有效類型:
第一次通過(guò)一個(gè)左值寫(xiě)入該對(duì)象,該左值的類型不是字符類型,此時(shí)該左值的類型變?yōu)樵搶?duì)象的該寫(xiě)入的有效類型以及所有后續(xù)讀取。
memcpy
或者memmove
將另一個(gè)對(duì)象復(fù)制到該對(duì)象中,此時(shí)源對(duì)象的有效類型(如果有的話)成為該對(duì)象的有效類型以及所有后續(xù)讀取。
對(duì)沒(méi)有聲明類型的對(duì)象進(jìn)行任何其他訪問(wèn),有效類型是用于訪問(wèn)的左值的類型。
給定一個(gè)有效類型為 T1 的對(duì)象,使用不同類型T2的左值表達(dá)式(通常是解引用指針)是未定義的行為,除非:
T2和T1是兼容的類型。
T2是與T1兼容的類型的cvr限定版本。
T2是與T1兼容的類型的有符號(hào)或無(wú)符號(hào)版本。
T2是一種聚合類型或聯(lián)合類型類型,其成員之一包括上述類型之一(包括遞歸地,子聚合的成員或包含的聯(lián)合)。
T2是一種字符類型(char,signed char或unsigned char)。
int i = 7;char* pc = (char*)(&i);if(pc[0] == '\x7') // aliasing through char is ok puts("This system is little-endian");else puts("This system is big-endian"); float* pf = (float*)(&i);float d = *pf; // UB: float lvalue *p cannot be used to access int
請(qǐng)注意,也可以通過(guò)聯(lián)合的非活動(dòng)成員執(zhí)行類型雙關(guān)。
每個(gè)完整的對(duì)象類型都有一個(gè)稱為對(duì)齊需求的屬性,它是一個(gè)類型的整數(shù)值,size_t
表示可以分配此類對(duì)象的連續(xù)地址之間的字節(jié)數(shù)。有效的對(duì)齊值是兩個(gè)非負(fù)整數(shù)冪。
The alignment requirement of a type can be queried with alignof. | (since C11) |
---|
為了滿足結(jié)構(gòu)中所有成員的對(duì)齊要求,可以在其一些成員之后插入填充。
#include <stdio.h>#include <stdalign.h> // objects of struct S can be allocated at any address// because both S.a and S.b can be allocated at any addressstruct S { char a; // size: 1, alignment: 1 char b; // size: 1, alignment: 1}; // size: 2, alignment: 1 // objects of struct X must be allocated at 4-byte boundaries// because X.n must be allocated at 4-byte boundaries// because int's alignment requirement is (usually) 4struct X { int n; // size: 4, alignment: 4 char c; // size: 1, alignment: 1 // three bytes padding}; // size: 8, alignment: 4 int main(void){ printf("sizeof(struct S) = %zu\n", sizeof(struct S)); printf("alignof(struct S) = %zu\n", alignof(struct S)); printf("sizeof(struct X) = %zu\n", sizeof(struct X)); printf("alignof(struct X) = %zu\n", alignof(struct X));}
可能的輸出:
sizeof(struct S) = 2alignof(struct S) = 1sizeof(struct X) = 8alignof(struct X) = 4
每種對(duì)象類型都對(duì)該類型的每個(gè)對(duì)象強(qiáng)加對(duì)齊要求。任何類型最嚴(yán)格的(最大的)基本對(duì)齊方式都是對(duì)齊max_align_t
。最弱(最?。┑膶?duì)準(zhǔn)是種類的排列char
,signed char
以及unsigned char
,和等于1。
如果使用alignas將對(duì)象的對(duì)齊更嚴(yán)格(大于)max_align_t,則它具有擴(kuò)展的對(duì)齊要求。其成員具有擴(kuò)展對(duì)齊的結(jié)構(gòu)或聯(lián)合類型是超對(duì)齊類型。如果支持過(guò)度對(duì)齊類型,它是實(shí)現(xiàn)定義的,并且它們的支持在每種存儲(chǔ)持續(xù)時(shí)間中可能不同。 | (自C11以來(lái)) |
---|