日本黄色一级经典视频|伊人久久精品视频|亚洲黄色色周成人视频九九九|av免费网址黄色小短片|黄色Av无码亚洲成年人|亚洲1区2区3区无码|真人黄片免费观看|无码一级小说欧美日免费三级|日韩中文字幕91在线看|精品久久久无码中文字幕边打电话

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

1、聊一聊

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


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



2、正確認識sizeof

? ??

01
非函數(shù)


? ? 首先大家需要明確,sizeof不是一個函數(shù)而是一個操作符,一些小伙伴經(jīng)??陬^上掛著"sizeof函數(shù)",這種說法是不正確的。


? ? 應該也好理解,比如sizeof(int),里面并沒有傳遞實參,如果其為函數(shù)便不成立,所以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在編譯階段就完成了轉化,所以經(jīng)常有小伙伴考慮到sizeof會不會很耗時間等等,從這里看它僅僅只是一個常量,對程序的運行影響與常量是一致的。


?

02
便于移植


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


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


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

參考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é)個數(shù)可要學會!),使用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語言進行了自動類型轉化,不理解的可參考<【重磅】“整形數(shù)”還真沒那么簡單(C語言版)>;


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


  • 這里提到strlen與sizeof,也是經(jīng)常使用過程中容易混淆的,這兩者有些相似也有不同,不過大家只要從定義出發(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ā)現(xiàn)sizeof后的表達式均沒有執(zhí)行,編譯器把sizeof修飾部分通過計算其類型占用空間大小直接替換。


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



05
其他


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

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


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


前提條件



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


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


5、結束語

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


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

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

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

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

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

【硬核C進階】如何實現(xiàn) 萬能 "兩數(shù)交換" 宏 ?

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

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

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

LED驅動電源的輸入包括高壓工頻交流(即市電)、低壓直流、高壓直流、低壓高頻交流(如電子變壓器的輸出)等。

關鍵字: 驅動電源

在工業(yè)自動化蓬勃發(fā)展的當下,工業(yè)電機作為核心動力設備,其驅動電源的性能直接關系到整個系統(tǒng)的穩(wěn)定性和可靠性。其中,反電動勢抑制與過流保護是驅動電源設計中至關重要的兩個環(huán)節(jié),集成化方案的設計成為提升電機驅動性能的關鍵。

關鍵字: 工業(yè)電機 驅動電源

LED 驅動電源作為 LED 照明系統(tǒng)的 “心臟”,其穩(wěn)定性直接決定了整個照明設備的使用壽命。然而,在實際應用中,LED 驅動電源易損壞的問題卻十分常見,不僅增加了維護成本,還影響了用戶體驗。要解決這一問題,需從設計、生...

關鍵字: 驅動電源 照明系統(tǒng) 散熱

根據(jù)LED驅動電源的公式,電感內電流波動大小和電感值成反比,輸出紋波和輸出電容值成反比。所以加大電感值和輸出電容值可以減小紋波。

關鍵字: LED 設計 驅動電源

電動汽車(EV)作為新能源汽車的重要代表,正逐漸成為全球汽車產(chǎn)業(yè)的重要發(fā)展方向。電動汽車的核心技術之一是電機驅動控制系統(tǒng),而絕緣柵雙極型晶體管(IGBT)作為電機驅動系統(tǒng)中的關鍵元件,其性能直接影響到電動汽車的動力性能和...

關鍵字: 電動汽車 新能源 驅動電源

在現(xiàn)代城市建設中,街道及停車場照明作為基礎設施的重要組成部分,其質量和效率直接關系到城市的公共安全、居民生活質量和能源利用效率。隨著科技的進步,高亮度白光發(fā)光二極管(LED)因其獨特的優(yōu)勢逐漸取代傳統(tǒng)光源,成為大功率區(qū)域...

關鍵字: 發(fā)光二極管 驅動電源 LED

LED通用照明設計工程師會遇到許多挑戰(zhàn),如功率密度、功率因數(shù)校正(PFC)、空間受限和可靠性等。

關鍵字: LED 驅動電源 功率因數(shù)校正

在LED照明技術日益普及的今天,LED驅動電源的電磁干擾(EMI)問題成為了一個不可忽視的挑戰(zhàn)。電磁干擾不僅會影響LED燈具的正常工作,還可能對周圍電子設備造成不利影響,甚至引發(fā)系統(tǒng)故障。因此,采取有效的硬件措施來解決L...

關鍵字: LED照明技術 電磁干擾 驅動電源

開關電源具有效率高的特性,而且開關電源的變壓器體積比串聯(lián)穩(wěn)壓型電源的要小得多,電源電路比較整潔,整機重量也有所下降,所以,現(xiàn)在的LED驅動電源

關鍵字: LED 驅動電源 開關電源

LED驅動電源是把電源供應轉換為特定的電壓電流以驅動LED發(fā)光的電壓轉換器,通常情況下:LED驅動電源的輸入包括高壓工頻交流(即市電)、低壓直流、高壓直流、低壓高頻交流(如電子變壓器的輸出)等。

關鍵字: LED 隧道燈 驅動電源
關閉