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

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

1、聊一聊

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


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



2、正確認(rèn)識(shí)sizeof

? ??

01
非函數(shù)


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


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

參考demo:
 1#include?
2#include?
3
4/***************************************
5?*?Fuction:?sizeof簡(jiǎn)單測(cè)試?
6?*?Author:???(公眾號(hào):最后一個(gè)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}
匯編與結(jié)果:



分析一下:
  • 匯編中5個(gè)紅線標(biāo)記處對(duì)應(yīng)著C語言中5個(gè)sizeof使用點(diǎn),在最終的匯編代碼中并沒有看到sizeof的痕跡。


  • 同時(shí)還可以確認(rèn)一點(diǎn)的是sizeof在編譯階段就完成了轉(zhuǎn)化,所以經(jīng)常有小伙伴考慮到sizeof會(huì)不會(huì)很耗時(shí)間等等,從這里看它僅僅只是一個(gè)常量,對(duì)程序的運(yùn)行影響與常量是一致的。


?

02
便于移植


? ? 因?yàn)樵诓煌钠脚_(tái)或者是編譯器,這些基礎(chǔ)的數(shù)據(jù)類型所占用的內(nèi)存字節(jié)空間不一定是相同的。


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


? ? 比如一個(gè)大型結(jié)構(gòu)體數(shù)據(jù)的內(nèi)存拷貝,當(dāng)由于內(nèi)存數(shù)據(jù)類型發(fā)生變化,或者是數(shù)據(jù)對(duì)齊等等原因?qū)е略摻Y(jié)構(gòu)體所占內(nèi)存發(fā)生變化,如果你采用的memcpy函數(shù)指定的大小沒有跟隨發(fā)生改變,則會(huì)出現(xiàn)問題,如下面示例:

參考demo:
 1#include?
2#include?
3#include?
4
5//采用默認(rèn)對(duì)齊?
6typedef?struct?_tag_Test1
7{
8????char?Val1;
9????int??Val2;
10????char?Val3;??
11}sTest1;
12
13sTest1?stTest1={1,2,3};
14
15//采用一個(gè)字節(jié)對(duì)齊?
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:???(公眾號(hào):最后一個(gè)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}
輸出結(jié)果:

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


  • 結(jié)構(gòu)體對(duì)齊不太不理解的可以參考<聽說因?yàn)榇a沒"對(duì)齊"程序就奔了?(深度剖析)>。



03
無符號(hào)類型


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


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

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

輸出結(jié)果:

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


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


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


 1#include?
2#include?
3
4/***************************************
5?*?Fuction:?sizeof與strlen?
6?*?Author:???(公眾號(hào):最后一個(gè)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
作用單一


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

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

8int?Cal(int?*param1,int?*param2,int?*result)
9{
10????*result?=?*param1?+?*param2;
11?????return?1;
12}?
13
14/***************************************
15?*?Fuction:?sizeof重點(diǎn)實(shí)例?
16?*?Author:???(公眾號(hào):最后一個(gè)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}
輸出結(jié)果:

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


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



05
其他


? ? 最后兩個(gè)小細(xì)節(jié):

  • 1 )?sizeof(數(shù)組名)和sizeof(指針)的差別。前者為總的數(shù)組字節(jié)個(gè)數(shù),而后者僅為平臺(tái)指針?biāo)甲止?jié)個(gè)數(shù)。


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


前提條件



現(xiàn)以上內(nèi)容暫不考慮C99標(biāo)準(zhǔn)下的sizeof的使用情況。


由于在C99標(biāo)準(zhǔn)下存在不定長(zhǎng)數(shù)組的使用,從而使得sizeof會(huì)在程序運(yùn)行階段確定對(duì)應(yīng)的類型字節(jié)個(gè)數(shù)


5、結(jié)束語

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


????好了,這里是公眾號(hào):“最后一個(gè)bug”,一個(gè)為大家打造的技術(shù)知識(shí)提升基地。

推薦好文??點(diǎn)擊藍(lán)色字體即可跳轉(zhuǎn)

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

【嵌入式】bug粉碎機(jī)之volatile的那些坑

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

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

?【進(jìn)階】同事用#include"xxx.c"把我給驚呆了?。?/span>

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

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

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

關(guān)鍵字: 驅(qū)動(dòng)電源

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

關(guān)鍵字: 工業(yè)電機(jī) 驅(qū)動(dòng)電源

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

關(guān)鍵字: 驅(qū)動(dòng)電源 照明系統(tǒng) 散熱

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

關(guān)鍵字: LED 設(shè)計(jì) 驅(qū)動(dòng)電源

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

關(guān)鍵字: 電動(dòng)汽車 新能源 驅(qū)動(dòng)電源

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

關(guān)鍵字: 發(fā)光二極管 驅(qū)動(dòng)電源 LED

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

關(guān)鍵字: LED 驅(qū)動(dòng)電源 功率因數(shù)校正

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

關(guān)鍵字: LED照明技術(shù) 電磁干擾 驅(qū)動(dòng)電源

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

關(guān)鍵字: LED 驅(qū)動(dòng)電源 開關(guān)電源

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

關(guān)鍵字: LED 隧道燈 驅(qū)動(dòng)電源
關(guān)閉