當前位置:首頁 > 公眾號精選 > 嵌入式云IOT技術圈
[導讀]本文跟大家分享的是C語言中sizeof一些需要注意的知識點,一方面可以避免大家再次掉坑,另一方面可以拿去吹吹牛!

1、聊一聊

? ? 今天分享一首bug技術交流群里小伙伴推薦的歌曲,bug菌聽了以后心情久久難以平復,一首非常傷感的歌曲,當然更特別的是其背后的故事。(記得做好心理準備再聽!)


? ??本文跟大家分享的是C語言中sizeof一些需要注意的知識點,一方面可以避免大家再次掉坑,另一方面可以拿去吹吹牛!



2、正確認識sizeof

? ??

01
非函數


? ? 首先大家需要明確,sizeof不是一個函數而是一個操作符,一些小伙伴經常口頭上掛著"sizeof函數",這種說法是不正確的。


? ? 應該也好理解,比如sizeof(int),里面并沒有傳遞實參,如果其為函數便不成立,所以sizeof僅僅只是一個操作符,繼續(xù)實驗一下:

參考demo:
 1#include?
2#include?
3
4/***************************************
5?*?Fuction:?sizeof簡單測試?
6?*?Author:???(公眾號:最后一個bug)?
7?**************************************/

8int?main(int?argc,?char?*argv[])?{
9????int?a?=?5;?
10????printf("sizeof(char)=?%d\n",sizeof(char));
11????printf("sizeof(int)=?%d\n",sizeof(int));
12????printf("sizeof(float)=?%d\n",sizeof(float));
13????printf("sizeof(double)=?%d\n",sizeof(double));
14????printf("sizeof(a)=?%d\n",sizeof(a));
15????return?0;
16}
匯編與結果:



分析一下:
  • 匯編中5個紅線標記處對應著C語言中5個sizeof使用點,在最終的匯編代碼中并沒有看到sizeof的痕跡。


  • 同時還可以確認一點的是sizeof在編譯階段就完成了轉化,所以經常有小伙伴考慮到sizeof會不會很耗時間等等,從這里看它僅僅只是一個常量,對程序的運行影響與常量是一致的。


?

02
便于移植


? ? 因為在不同的平臺或者是編譯器,這些基礎的數據類型所占用的內存字節(jié)空間不一定是相同的。


? ? sizeof功能就是計算出數據類型在內存空間所占的字節(jié)數,這樣就增強了程序的可移植性,特別是當我們進行內存拷貝的時候顯得尤為有用。


? ? 比如一個大型結構體數據的內存拷貝,當由于內存數據類型發(fā)生變化,或者是數據對齊等等原因導致該結構體所占內存發(fā)生變化,如果你采用的memcpy函數指定的大小沒有跟隨發(fā)生改變,則會出現問題,如下面示例:

參考demo:
 1#include?
2#include?
3#include?
4
5//采用默認對齊?
6typedef?struct?_tag_Test1
7{
8????char?Val1;
9????int??Val2;
10????char?Val3;??
11}sTest1;
12
13sTest1?stTest1={1,2,3};
14
15//采用一個字節(jié)對齊?
16#pragma?pack(1)
17typedef?struct?_tag_Test2
18{
19????char?Val1;
20????int??Val2;
21????char?Val3;??
22}sTest2;
23
24#pragma?pack(0)
25sTest2?stTest2={4,5,6};
26/***************************************
27?*?Fuction:?sizeof可移植性?
28?*?Author:???(公眾號:最后一個bug)?
29?**************************************/

30int?main(int?argc,?char?*argv[])?{
31
32????sTest1?stTest1_ds;
33????sTest2?stTest2_ds;?
34
35????printf("sizeof(sTest1)?=?%d\n",sizeof(sTest1));
36????printf("sizeof(sTest2)?=?%d\n",sizeof(sTest2));
37
38??//?memcpy(&stTest1_ds,&stTest1,12);??//12和6硬編程,可移植性不好?
39??//?memcpy(&stTest2_ds,&stTest2,6);
40
41????memcpy(&stTest1_ds,&stTest1,sizeof(sTest1));
42????memcpy(&stTest2_ds,&stTest2,sizeof(sTest2));
43
44????printf("%d??%d??%d\n",stTest1_ds.Val1,stTest1_ds.Val2,stTest1_ds.Val3);
45????printf("%d??%d??%d\n",stTest2_ds.Val1,stTest2_ds.Val2,stTest2_ds.Val3);
46
47????return?0;
48}
輸出結果:

分析一下:
  • 上面bug菌為了解釋結構體在不同平臺占用空間有所不同,通過設置結構體對齊來進行了模擬(如何設置結構體對其字節(jié)個數可要學會!),使用sizeof明顯要比硬編程的移植性更好。


  • 結構體對齊不太不理解的可以參考<聽說因為代碼沒"對齊"程序就奔了?(深度剖析)>。



03
無符號類型


? ? 在之前的文中bug菌講到了strlen返回的是size_t類型,其為無符號類型,參考<【C進階】一不小心就被"strlen"給坑了!>,那么sizeof編譯器會處理成什么類型呢? 不防做個實驗:


參考demo:
 1#include?
2#include?
3
4/***************************************
5?*?Fuction:?sizeof類型測試?
6?*?Author:???(公眾號:最后一個bug)?
7?**************************************/

8int?main(int?argc,?char?*argv[])?{
9
10????int?i=?-1;
11
12????if(i?>?sizeof(int))
13????{
14????????printf("sizeof?采用無符號類型\n");???
15????}
16????else
17????{
18????????printf("sizeof?采用有符號類型\n");???
19????}?
20
21????return?0;
22}

輸出結果:

分析一下:
  • -1 > 4的結果是C語言進行了自動類型轉化,不理解的可參考<【重磅】“整形數”還真沒那么簡單(C語言版)>;


  • sizeof和strlen函數的返回類型一樣,都是size_t類型(可能有些平臺指定為unsigned int),而該類型一般定義無符號整形,這樣也就會出現如上的實驗現象,以后多加小心。其實也很好理解,它們都是計算數據長度的方法也就沒有必要使用有符號類型。


  • 這里提到strlen與sizeof,也是經常使用過程中容易混淆的,這兩者有些相似也有不同,不過大家只要從定義出發(fā)就沒有問題了,如下Demo:


 1#include?
2#include?
3
4/***************************************
5?*?Fuction:?sizeof與strlen?
6?*?Author:???(公眾號:最后一個bug)?
7?**************************************/

8int?main(int?argc,?char?*argv[])?{
9
10????char?*?cbug?=?"bug";?
11
12????printf("sizeof(cbug)?=?%d\n",sizeof(cbug));?//?b?u?g?\n?
13
14????printf("strlen(cbug)?=?%d\n",strlen(cbug));?//?b?u?g?
15
16????return?0;
17}




04
作用單一


? ? 這一點大家可能會疑惑,這里所說的單一不是說功能單一,而是sizeof只在編譯階段檢測并計算其后的類型,其他表達式均不處理,見代碼見真相 :

參考demo:
 1#include?
2#include?
3
4/***************************************
5?*?Fuction:??Cal?
6?*?Author:???(公眾號:最后一個bug)?
7?**************************************/

8int?Cal(int?*param1,int?*param2,int?*result)
9{
10????*result?=?*param1?+?*param2;
11?????return?1;
12}?
13
14/***************************************
15?*?Fuction:?sizeof重點實例?
16?*?Author:???(公眾號:最后一個bug)?
17?**************************************/

18int?main(int?argc,?char?*argv[])?{
19
20????int?i?=?1;?
21????char?j?=?1;?
22????int?a?=?2;
23????int?b?=?2;
24????int?ret?=?0;
25
26????printf("sizeof(i++)??=?%d\n",sizeof(i++));??
27????printf("sizeof(++i)??=?%d\n",sizeof(++i));??
28????printf("sizeof?++i???=?%d\n",sizeof?++j);???
29
30????printf("sizeof(Cal)??=?%d\n",sizeof(Cal(&a,&b,&ret)));
31????printf("sizeof?Cal???=?%d\n",sizeof?Cal(&a,&b,&ret));?
32
33????printf("i????????????=?%d\n",i);
34????printf("j????????????=?%d\n",j);????
35????printf("ret??????????=?%d\n",ret);??
36????return?0;
37}
輸出結果:

分析一下:
  • 通過上面的實驗大家可以發(fā)現sizeof后的表達式均沒有執(zhí)行,編譯器把sizeof修飾部分通過計算其類型占用空間大小直接替換。


  • 所以很多小伙伴編碼比較隨意容易出現這種類型的bug,當然sizeof后面接具體的數據類型一定需要小括號,而是其他非void表達式均可以省略該小括號,上面的實例中為大家展示了。



05
其他


? ? 最后兩個小細節(jié):

  • 1 )?sizeof(數組名)和sizeof(指針)的差別。前者為總的數組字節(jié)個數,而后者僅為平臺指針所占字節(jié)個數。


  • 2 )?sizeof不能用來計算位域大小。其實也很好理解,sizeof僅僅只計算字節(jié)個數,位域bit個數編譯器不識別。


前提條件



現以上內容暫不考慮C99標準下的sizeof的使用情況。


由于在C99標準下存在不定長數組的使用,從而使得sizeof會在程序運行階段確定對應的類型字節(jié)個數


5、結束語

? ? 本文到這里就結束了,sizeof理解好了其實并不難,就怕你閱讀一些反人類的代碼,從而造成理解上的困難!當然面試官也可能考你一波!


????好了,這里是公眾號:“最后一個bug”,一個為大家打造的技術知識提升基地。

推薦好文??點擊藍色字體即可跳轉

【開源】bug菌把"動態(tài)數字顯示"開源了!

【嵌入式】bug粉碎機之volatile的那些坑

【MCU】用stm32的UID給固件加密(重點在加密)

【硬核C進階】如何實現 萬能 "兩數交換" 宏 ?

?【進階】同事用#include"xxx.c"把我給驚呆了??!

免責聲明:本文內容由21ic獲得授權后發(fā)布,版權歸原作者所有,本平臺僅提供信息存儲服務。文章僅代表作者個人觀點,不代表本平臺立場,如有問題,請聯系我們,謝謝!

本站聲明: 本文章由作者或相關機構授權發(fā)布,目的在于傳遞更多信息,并不代表本站贊同其觀點,本站亦不保證或承諾內容真實性等。需要轉載請聯系該專欄作者,如若文章內容侵犯您的權益,請及時聯系本站刪除。
換一批
延伸閱讀

9月2日消息,不造車的華為或將催生出更大的獨角獸公司,隨著阿維塔和賽力斯的入局,華為引望愈發(fā)顯得引人矚目。

關鍵字: 阿維塔 塞力斯 華為

加利福尼亞州圣克拉拉縣2024年8月30日 /美通社/ -- 數字化轉型技術解決方案公司Trianz今天宣布,該公司與Amazon Web Services (AWS)簽訂了...

關鍵字: AWS AN BSP 數字化

倫敦2024年8月29日 /美通社/ -- 英國汽車技術公司SODA.Auto推出其旗艦產品SODA V,這是全球首款涵蓋汽車工程師從創(chuàng)意到認證的所有需求的工具,可用于創(chuàng)建軟件定義汽車。 SODA V工具的開發(fā)耗時1.5...

關鍵字: 汽車 人工智能 智能驅動 BSP

北京2024年8月28日 /美通社/ -- 越來越多用戶希望企業(yè)業(yè)務能7×24不間斷運行,同時企業(yè)卻面臨越來越多業(yè)務中斷的風險,如企業(yè)系統(tǒng)復雜性的增加,頻繁的功能更新和發(fā)布等。如何確保業(yè)務連續(xù)性,提升韌性,成...

關鍵字: 亞馬遜 解密 控制平面 BSP

8月30日消息,據媒體報道,騰訊和網易近期正在縮減他們對日本游戲市場的投資。

關鍵字: 騰訊 編碼器 CPU

8月28日消息,今天上午,2024中國國際大數據產業(yè)博覽會開幕式在貴陽舉行,華為董事、質量流程IT總裁陶景文發(fā)表了演講。

關鍵字: 華為 12nm EDA 半導體

8月28日消息,在2024中國國際大數據產業(yè)博覽會上,華為常務董事、華為云CEO張平安發(fā)表演講稱,數字世界的話語權最終是由生態(tài)的繁榮決定的。

關鍵字: 華為 12nm 手機 衛(wèi)星通信

要點: 有效應對環(huán)境變化,經營業(yè)績穩(wěn)中有升 落實提質增效舉措,毛利潤率延續(xù)升勢 戰(zhàn)略布局成效顯著,戰(zhàn)新業(yè)務引領增長 以科技創(chuàng)新為引領,提升企業(yè)核心競爭力 堅持高質量發(fā)展策略,塑強核心競爭優(yōu)勢...

關鍵字: 通信 BSP 電信運營商 數字經濟

北京2024年8月27日 /美通社/ -- 8月21日,由中央廣播電視總臺與中國電影電視技術學會聯合牽頭組建的NVI技術創(chuàng)新聯盟在BIRTV2024超高清全產業(yè)鏈發(fā)展研討會上宣布正式成立。 活動現場 NVI技術創(chuàng)新聯...

關鍵字: VI 傳輸協議 音頻 BSP

北京2024年8月27日 /美通社/ -- 在8月23日舉辦的2024年長三角生態(tài)綠色一體化發(fā)展示范區(qū)聯合招商會上,軟通動力信息技術(集團)股份有限公司(以下簡稱"軟通動力")與長三角投資(上海)有限...

關鍵字: BSP 信息技術
關閉
關閉