聊聊C語言中sizeof運(yùn)算符的一個陷阱
sizeof運(yùn)算符通常用于獲取變量或類型所占內(nèi)存的大?。▎挝皇亲止?jié))
#include <stdio.h> struct D{ char a; int b; }; int main() { int a = 0; struct D d; printf("sizeof(a)=%ld\n", sizeof(a)); printf("sizeof(int)=%ld\n", sizeof(int)); printf("sizeof(d)=%ld\n", sizeof(d)); printf("sizeof(struct D)=%ld\n", sizeof(struct D)); return 0; }
運(yùn)行程序輸出:
sizeof(a)=4
sizeof(int)=4
sizeof(d)=8
sizeof(struct D)=8
使用此特性可以結(jié)合memset,對數(shù)據(jù)結(jié)構(gòu)進(jìn)行初始化:
#include <stdio.h> #include <string.h> struct D{ char a; int b; }; int main() { D d; printf("before init:a=%d, b=%d\n", d.a, d.b); memset(&d, 0, sizeof(d)); printf("after init:a=%d, b=%d\n", d.a, d.b); return 0; }
運(yùn)行程序輸出:
before init:a=16, b=0
after init:a=0, b=0
不過在使用sizeof時需要注意,對于指針類型的變量,只會求值指針的大小,不會求值其指向內(nèi)容的大?。?/p>
#include <stdio.h> int main() { char str[10] = {0}; char* pStr = str; printf("sizeof(str)=%ld\n", sizeof(str)); printf("sizeof(pStr)=%ld\n", sizeof(pStr)); return 0; }
運(yùn)行程序輸出:
sizeof(str)=10
sizeof(pStr)=8
這對于通過函數(shù)參數(shù)進(jìn)行sizeof求值是一個陷阱:
#include <stdio.h> #include <string.h> void f(char *pStr) { memset(pStr, 'a', sizeof(pStr)); printf("pStr:%s sizeof(pStr)=%ld\n", pStr, sizeof(pStr)); } int main() { char str[10] = "123456789"; printf("str:%s sizeof(str)=%ld\n", str, sizeof(str)); f(str); return 0; }
運(yùn)行程序輸出:
str:123456789 sizeof(str)=10
pStr:aaaaaaaa9 sizeof(pStr)=8可見,在函數(shù)f內(nèi),通過指針pStr求值sizeof,獲得的是指針的大小(64位系統(tǒng)上位8個字節(jié)),如果依據(jù)此指來初始化str,那么只能操作8個字節(jié),也就導(dǎo)致了調(diào)用函數(shù)f后,str進(jìn)入了一種混亂的狀態(tài),其內(nèi)容為:aaaaaaaa9
Sizeof的作用非常簡單:求對象或者類型的大小。然而sizeof又非常復(fù)雜,它涉及到很多特殊情況,本篇把這些情況分門別類,總結(jié)出了sizeof的10個特性:
(0)sizeof是運(yùn)算符,不是函數(shù);
(1)sizeof不能求得void類型的長度;
(2)sizeof能求得void類型的指針的長度;
(3)sizeof能求得靜態(tài)分配內(nèi)存的數(shù)組的長度!
(4)sizeof不能求得動態(tài)分配的內(nèi)存的大小!
(5)sizeof不能對不完整的數(shù)組求長度;
(6)當(dāng)表達(dá)式作為sizeof的操作數(shù)時,它返回表達(dá)式的計算結(jié)果的類型大小,但是它不對表達(dá)式求值!
(7)sizeof可以對函數(shù)調(diào)用求大小,并且求得的大小等于返回類型的大小,但是不執(zhí)行函數(shù)體!
(8)sizeof求得的結(jié)構(gòu)體(及其對象)的大小并不等于各個數(shù)據(jù)成員對象的大小之和!
(9)sizeof不能用于求結(jié)構(gòu)體的位域成員的大小,但是可以求得包含位域成員的結(jié)構(gòu)體的大??!
概述:
Sizeof是C/C++中的關(guān)鍵字,它是一個運(yùn)算符,其作用是取得一個對象(數(shù)據(jù)類型或者數(shù)據(jù)對象)的長度(即占用內(nèi)存的大小,以byte為單位)。其中類型包含基本數(shù)據(jù)類型(不包括void)、用戶自定義類型(結(jié)構(gòu)體、類)、函數(shù)類型。數(shù)據(jù)對象是指用前面提到的類型定義的普通變量和指針變量(包含void指針)。不同類型的數(shù)據(jù)的大小在不同的平臺下有所區(qū)別,但是c標(biāo)準(zhǔn)規(guī)定所有編譯平臺都應(yīng)該保證sizeof(char)等于1。關(guān)于sizeof的更多概述你可以在msdn總輸入sizeof進(jìn)行查詢。
總結(jié)
到此這篇關(guān)于C語言中sizeof運(yùn)算符的一個陷阱的文章就介紹到這了,更多相關(guān)C語言sizeof運(yùn)算符陷阱內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
C++中sprintf使用的方法與printf的區(qū)別分析
這篇文章主要介紹了C++中sprintf使用的方法與printf的區(qū)別,實(shí)例分析了sprintf與printf的具體用法及相關(guān)注意事項,具有一定參考借鑒價值,需要的朋友可以參考下2015-01-01詳解C語言如何實(shí)現(xiàn)雙向帶頭循環(huán)鏈表
雙向帶頭循環(huán)鏈表應(yīng)該是鏈表中非常方便的一種,可以很容易的在任意位置上進(jìn)行插入和刪除,可以很容易的對鏈表進(jìn)行管理。本文將利用C語言實(shí)現(xiàn)雙向帶頭循環(huán)鏈表,需要的可以參考一下2022-08-08C++實(shí)現(xiàn)list增刪查改模擬的示例代碼
本文主要介紹了C++實(shí)現(xiàn)list增刪查改模擬,文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧2023-12-12c++ Protobuf解決數(shù)據(jù)傳輸瓶頸面試精講
這篇文章主要介紹了c++ Protobuf解決數(shù)據(jù)傳輸瓶頸利器面試精講,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪2023-10-10圖解C++的STL之stack和queue,輕松理解數(shù)據(jù)結(jié)構(gòu)
聚焦?C++?的?STL?中的?stack?和?queue,讓數(shù)據(jù)結(jié)構(gòu)變得簡單有趣!?通過圖解的方式,我們將輕松理解這兩個重要的數(shù)據(jù)結(jié)構(gòu),準(zhǔn)備好開啟?STL?學(xué)習(xí)之旅了嗎?讓我們一起探索?stack?和?queue?的奧秘吧!2024-03-03C++實(shí)現(xiàn)線程同步的四種方式總結(jié)
這篇文章主要為大家詳細(xì)介紹了C++實(shí)現(xiàn)線程同步的四種方式,文中的示例代碼講解詳細(xì),對我們學(xué)習(xí)C++有一定的幫助,需要的可以參考一下2022-11-11Cocos2d-x UI開發(fā)之CCControlSwitch控件類使用實(shí)例
這篇文章主要介紹了Cocos2d-x UI開發(fā)之CCControlSwitch控件類使用實(shí)例,本文代碼中含大量注釋講解了CCControlSwitch控件類的使用,需要的朋友可以參考下2014-09-09C++學(xué)習(xí)之cstdbool和cstddef頭文件封裝源碼分析
這篇文章主要為大家介紹了C++學(xué)習(xí)之cstdbool和cstddef頭文件封裝源碼分析,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪2022-09-09