c语言 手动实现sizeof,sizeof究竟是怎样实现的?
sizeof,是在編譯的時(shí)候,查找符號(hào)表,判斷類型,然后根據(jù)基礎(chǔ)類型來(lái)取值的,如果是struct則是看類型聲明符號(hào)表來(lái)判定,如果字符串則是通過(guò)常
量表來(lái)判斷,具體可以參考編譯原理的符號(hào)表管理章節(jié),一般都有講,如果沒(méi)講,不要讀這本書,呵呵
關(guān)于sizeof的一般性的問(wèn)題,相信大家已經(jīng)見(jiàn)過(guò)很多了。
本文討論的是一些不常見(jiàn)的細(xì)節(jié)。
關(guān)于sizeof的更多細(xì)節(jié):
1、sizeof(i++)之后,i的值會(huì)怎樣?答案是不變。記得大一初學(xué)C語(yǔ)言時(shí)想研究一下sizeof與函數(shù)有什么區(qū)別,得到的結(jié)果只
是一些語(yǔ)法上的差別;學(xué)了匯編之后看看編譯器生成的代碼,才發(fā)現(xiàn)sizeof在編譯時(shí)直接給定了一個(gè)常值,而非在運(yùn)行時(shí)求值。進(jìn)而又分析過(guò)
sizeof(表達(dá)式)的結(jié)果,清楚了類型提升原理。但我之前沒(méi)有注意過(guò)表達(dá)式中出現(xiàn)副作用的問(wèn)題,于是在sizeof(i++)的問(wèn)題上猶豫了。現(xiàn)在經(jīng)
過(guò)查閱資料和實(shí)驗(yàn),結(jié)論是:sizeof在大多數(shù)情況下是編譯時(shí)定值的,表達(dá)式中的任何副作用(包括有副作用的運(yùn)算符、函數(shù)調(diào)用等)都不會(huì)發(fā)生。這里說(shuō)
“大多數(shù)情況”,排除了針對(duì)C99的新特性——不定長(zhǎng)數(shù)組(variable length
array)的特例。參考這篇文章(http://rednaxelafx.javaeye.com/blog/225909),如果sizeof運(yùn)算符
的參數(shù)是一個(gè)不定長(zhǎng)數(shù)組,則該需要在運(yùn)行時(shí)計(jì)算數(shù)組長(zhǎng)度。
2、sizeof('a')的結(jié)果是多少?這個(gè)要看是在C中還是C++中了。根據(jù)標(biāo)準(zhǔn)的規(guī)定,在C的算術(shù)類型提升時(shí),字符常量'a'自動(dòng)提
升為整型,故結(jié)果是4(對(duì)于32位機(jī)器);而在C++中則有字符常量的規(guī)定,'a'就是一個(gè)單字節(jié)的字符常量,故結(jié)果是1。我這樣理解:C強(qiáng)調(diào)了char
的“數(shù)”屬性,而C++強(qiáng)調(diào)了char的“字符”屬性。
3、sizeof('ab')的結(jié)果又是多少?'ab'這種語(yǔ)法我以前沒(méi)有注意到。經(jīng)查,這叫做“多字節(jié)字符常量”(multi-
character character
constant),它限制在單引號(hào)中包含2至4個(gè)字節(jié)。根據(jù)標(biāo)準(zhǔn),多字節(jié)字符常量的語(yǔ)義由編譯器的實(shí)現(xiàn)決定。在我測(cè)試的gcc
4.0和VS2008中,如果int a = 'abcd',則a == 0x61626364。sizeof('ab') ==
sizeof('abc') == sizeof('abcd') == 4。
4、那么sizeof(L'a')呢?雖然wchar_t是在源代碼級(jí)可移植的寬字符,但其大小依賴于操作系統(tǒng)或編譯器的定義。獨(dú)立出現(xiàn)的
wchar_t常量并不會(huì)像char常量那樣做算術(shù)提升,所以sizeof(L'a')就等于sizeof(wchar_t)。在我在32位
Windows和Linux平臺(tái)下分別為2和4。
5、至于sizeof(L'ab')、sizeof(L'中')、sizeof(L'中國(guó)')又會(huì)如何?寬字符常量的單引號(hào)中出現(xiàn)多個(gè)字節(jié)
構(gòu)成的單個(gè)字符(如L'中')是合法的,對(duì)它取sizeof,結(jié)果等于具體實(shí)現(xiàn)下的sizeof(wchar_t)。但出現(xiàn)多個(gè)字節(jié)構(gòu)成的多個(gè)字符(如
L'ab'、L'中國(guó)')則是沒(méi)有定義的,編譯器可能報(bào)錯(cuò),也可能給出不同的實(shí)現(xiàn)。在我測(cè)試的gcc4.0和VS2008中,L'abcd'分別返回了
0x64和0x61。對(duì)它們?nèi)izeof,結(jié)果等于具體實(shí)現(xiàn)下的sizeof(wchar_t),但注意這是標(biāo)準(zhǔn)未定義的,不應(yīng)該確信。
另外,看到的關(guān)于sizeof的兩個(gè)精巧的宏實(shí)現(xiàn)。
非數(shù)組的sizeof:
#defne _sizeof(T) ( (size_t)((T*)0 + 1))
數(shù)組的sizeof:
#define array_sizeof(T) ? ( (size_t)(&T+1) ?- (size_t)(&T)
)
原理就是c/c++中的指針運(yùn)算。
總結(jié)
以上是生活随笔為你收集整理的c语言 手动实现sizeof,sizeof究竟是怎样实现的?的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。
- 上一篇: Linux服务器版本鼠标,安装GPM给L
- 下一篇: 去除标题_你真的会写标题吗?企优托教您打