0
  • 聊天消息
  • 系統(tǒng)消息
  • 評(píng)論與回復(fù)
登錄后你可以
  • 下載海量資料
  • 學(xué)習(xí)在線課程
  • 觀看技術(shù)視頻
  • 寫文章/發(fā)帖/加入社區(qū)
會(huì)員中心
創(chuàng)作中心

完善資料讓更多小伙伴認(rèn)識(shí)你,還能領(lǐng)取20積分哦,立即完善>

3天內(nèi)不再提示

字符型、指針型等變量等該如何初始化

玩轉(zhuǎn)嵌入式 ? 來(lái)源:玩轉(zhuǎn)嵌入式 ? 2024-03-18 11:02 ? 次閱讀

在敲代碼的時(shí)候,我們會(huì)給變量一個(gè)初始值,以防止因?yàn)榫幾g器的原因造成變量初始值的不確定性。

對(duì)于數(shù)值類型的變量往往初始化為0,但對(duì)于其他類型的變量,如字符型、指針型等變量等該如何初始化呢?

數(shù)值類變量初始化

整型、浮點(diǎn)型的變量可以在定義的同時(shí)進(jìn)行初始化,一般都初始化為0。

1int inum = 0;

2float fnum = 0.00f;

3double dnum = 0.00;

字符型變量初始化

字符型變量也可在定義的同時(shí)進(jìn)行初始化,一般初始化為‘?’。

1char ch = ‘?’;

字符串初始化

字符串初始化的方法比較多,我這里簡(jiǎn)單介紹三種,因?yàn)樽址举|(zhì)上是由一個(gè)個(gè)字符組成的字符數(shù)組,所以其初始化的最終目的,就是將字符數(shù)組里面的一個(gè)個(gè)字符都初始化為‘?’。

方法一:使用空的字符串“”。

char str[10] = “”;

方法二:使用memset。

char str[10]; memset(str, 0, sizeof(str));

方法三:寫一個(gè)循環(huán)。

char str[10]; for(int i = 0; i 《 10; i++) { str[i] = ‘?’; } 這里比較推薦的是第二種初始化方法。也即使用memset進(jìn)行初始化。

很多人對(duì)memset這個(gè)函數(shù)一知半解,只知道它可以初始化很多數(shù)據(jù)類型的變量,卻不知道其原理是什么樣的,這里做一下簡(jiǎn)要的說(shuō)明:memset是按照字節(jié)進(jìn)行填充的。 先看下面的一段代碼:

int num; memset(&num, 0, sizeof(int)); printf(“step1=%d ”, num); memset(&num, 1, sizeof(int)); printf(“step2=%d ”, num);

在討論之前,我們先看一下運(yùn)行結(jié)果

chenyc@DESKTOP-IU8FEL6:~/src$ gcc -o memset memset.c -g chenyc@DESKTOP-IU8FEL6:~/src$ 。/memset step1 = 0 step2 = 16843009 chenyc@DESKTOP-IU8FEL6:~/src$

看到這個(gè)運(yùn)行結(jié)果,是不是和你想象中的不一樣呢? step1 = 0 相信大家都好理解,可 step2 = 16843009 很多人就不能理解了。按照一般的慣性思維,不是應(yīng)該 = 1 才對(duì)么? 這就是我要說(shuō)的,memset是按照字節(jié)進(jìn)行填充的。 我們知道,int 型是4個(gè)字節(jié)(每個(gè)字節(jié)有8位),按二進(jìn)制表示出來(lái)就應(yīng)該是:

00000000 00000000 00000000 00000000

按照按字節(jié)填充的原則,step1 的結(jié)果就是將4個(gè)字節(jié)全部填充0,所以得到的結(jié)果仍然是0:

00000000 00000000 00000000 00000000

而 step2 則是將每個(gè)字節(jié)都填充為1 (注意是每個(gè)字節(jié),而不是每個(gè)byte位) ,所以相對(duì)應(yīng)的結(jié)果就應(yīng)該是:

00000001 00000001 00000001 00000001

大家可以自己將上面那個(gè)二進(jìn)制數(shù)轉(zhuǎn)換成十進(jìn)制看看,看看是不是16843009。 所以嚴(yán)格來(lái)說(shuō),memset函數(shù)本身并不具有初始化的功能,而是一個(gè)單純的按字節(jié)填充函數(shù),只是人們?cè)谑褂玫倪^(guò)程中,擴(kuò)展出了初始化的作用。

字符串初始化有一個(gè)小竅門,我們知道字符串本質(zhì)上是字符數(shù)組,因此它具有兩個(gè)特性,

字符串在內(nèi)存里是連續(xù)的,

字符串遇‘?’結(jié)束。 所以我們?cè)诔跏蓟臅r(shí)候,總是愿意給字符串本身長(zhǎng)度加1的長(zhǎng)度的內(nèi)存進(jìn)行初始化。

char year[4+1]; memset(year, 0, sizeof(year)); strcpy(year,“2018”);

指針初始化

一般來(lái)說(shuō),指針都是初始化為NULL。

int *pnum = NULL; int num = 0; pnum = # 指針是個(gè)讓人又愛又恨的東西,一般的整形、字符串等,初始化之后就可以直接拿來(lái)用了,可指針如果初始化為NULL后,沒(méi)有給該指針重新分配內(nèi)存,則會(huì)出現(xiàn)難以預(yù)料的錯(cuò)誤(最最常見的就是操作空指針引起的段錯(cuò)誤)。 在動(dòng)態(tài)內(nèi)存管理中,由于變量的內(nèi)存是分配在堆中的,所以一般用malloc、calloc等函數(shù)申請(qǐng)過(guò)動(dòng)態(tài)內(nèi)存,在使用完后需要及時(shí)釋放,一般釋放掉動(dòng)態(tài)內(nèi)存后要及時(shí)將指針置空,這也是很多人容易忽略的。

char *p = NULL; p=(char *)malloc(100); if(NULL == p) { printf(“Memory Allocated at: %x ”,p); } else { printf(“Not Enough Memory! ”); } free(p); p = NULL; //這一行給指針置空必不可少,否則很可能后面操作了這個(gè)野指針而不自知,從而導(dǎo)致出現(xiàn)嚴(yán)重的問(wèn)題 很多人經(jīng)常會(huì)犯的一個(gè)錯(cuò)誤,我們知道,在指針作為實(shí)參進(jìn)行參數(shù)傳遞時(shí),該指針就已經(jīng)退化成了數(shù)組,所以很多人就想到用memset來(lái)對(duì)該指針進(jìn)行初始化:

void fun(char *pstr) { memset(pstr, 0, sizeof(pstr)); 。.. } 這種寫法是不正確的。我們姑且不管指針能不能用memset來(lái)進(jìn)行初始化,指針首先保存的是一個(gè)4字節(jié)的地址,所以sizeof(pstr)永遠(yuǎn)只能 = 4,這樣的初始化就毫無(wú)意義。

結(jié)構(gòu)體初始化

結(jié)構(gòu)體的初始化就比較簡(jiǎn)單了,基本也都是采用memset的方式。

typedef struct student { int id; char name[20]; char sex; }STU; STU stu1; memset((char *)&stu1, 0, sizeof(stu1)); 關(guān)于初始化結(jié)構(gòu)體的長(zhǎng)度問(wèn)題,也即memset的第三個(gè)參數(shù),一般來(lái)說(shuō),傳入數(shù)據(jù)類型和變量名效果是一樣的,上例中,下面寫法是等價(jià)的效果:

memset((char *)&stu1, 0, sizeof(STU)); 但是對(duì)于結(jié)構(gòu)體數(shù)組的初始化,長(zhǎng)度就需要注意一下了,還是以上例來(lái)做說(shuō)明:

STU stus[10]; memset((char *)&stus, 0, sizeof(stus)); //正確,數(shù)組本身在內(nèi)存里就是連續(xù)的,sizeof取出的就是數(shù)組的字節(jié)長(zhǎng)度 memset((char *)&stus, 0, sizeof(STU)); //錯(cuò)誤,只會(huì)初始化第一個(gè)STU結(jié)構(gòu)體,后面還有9個(gè)STU元素并未初始化 memset((char *)&stus, 0, sizeof(STU)*10); //正確,效果與第一個(gè)是一樣的 有些人習(xí)慣將memset的第二個(gè)參數(shù)寫成以下形式:

memset((char *)&stu1, 0x00, sizeof(stu1)); 只要理解了memset是按字節(jié)進(jìn)行填充的,就知道這樣寫也是正確的,完全沒(méi)有問(wèn)題。

審核編輯:黃飛

聲明:本文內(nèi)容及配圖由入駐作者撰寫或者入駐合作網(wǎng)站授權(quán)轉(zhuǎn)載。文章觀點(diǎn)僅代表作者本人,不代表電子發(fā)燒友網(wǎng)立場(chǎng)。文章及其配圖僅供工程師學(xué)習(xí)之用,如有內(nèi)容侵權(quán)或者其他違規(guī)問(wèn)題,請(qǐng)聯(lián)系本站處理。 舉報(bào)投訴
  • 字符串
    +關(guān)注

    關(guān)注

    1

    文章

    587

    瀏覽量

    20699
  • 編譯器
    +關(guān)注

    關(guān)注

    1

    文章

    1645

    瀏覽量

    49473
  • 變量
    +關(guān)注

    關(guān)注

    0

    文章

    613

    瀏覽量

    28579

原文標(biāo)題:初始化,原來(lái)這么多講究,你搞懂了嗎?

文章出處:【微信號(hào):玩轉(zhuǎn)嵌入式,微信公眾號(hào):玩轉(zhuǎn)嵌入式】歡迎添加關(guān)注!文章轉(zhuǎn)載請(qǐng)注明出處。

收藏 人收藏

    評(píng)論

    相關(guān)推薦

    字符、指針變量如何初始化

    在敲代碼的時(shí)候,我們會(huì)給變量一個(gè)初始值,以防止因?yàn)榫幾g器的原因造成變量初始值的不確定性。對(duì)于數(shù)值類型的變量往往
    發(fā)表于 09-23 11:50 ?2279次閱讀

    C語(yǔ)言中未初始化的局部變量到底是多少

    C語(yǔ)言中,未初始化的局部變量到底是多少?
    發(fā)表于 10-21 14:42 ?2127次閱讀

    請(qǐng)問(wèn)這樣操作指針初始化不對(duì)?

    int?a=20b=5;??/*?定義兩個(gè)整型變量ab并初始化?*/ int?*pa=&a; /*?將變量a的地址賦給指針變量pa?*/不
    發(fā)表于 05-09 07:56

    請(qǐng)問(wèn)CC3200為什么從有些初始化過(guò)的的全局變量在watch Expressions中看到的全是點(diǎn)呢?

    ;.",我改成用a,b,c字符初始化就能在watch Expressions中顯示出來(lái),怎么回事,難道只能發(fā)送字符么?為何沒(méi)法定義byte類型的
    發(fā)表于 06-12 10:43

    【原創(chuàng)分享】變量初始化技巧

    由于在嵌入式系統(tǒng)中必須考慮程序規(guī)模的問(wèn)題,因此,對(duì)程序中的變量初始化也需要進(jìn)行慎重的考慮。在C語(yǔ)言中,基本數(shù)據(jù)結(jié)構(gòu)(字符、整型)的初始化
    發(fā)表于 09-08 15:28

    單片機(jī)指針變量的相關(guān)資料分享

    單片機(jī)C語(yǔ)言變量分別有char,int,long,float,它們分別占用內(nèi)存為1個(gè)單
    發(fā)表于 11-30 08:05

    C語(yǔ)言教程之字符變量的使用

    C語(yǔ)言教程之字符變量的使用,很好的C語(yǔ)言資料,快來(lái)學(xué)習(xí)吧。
    發(fā)表于 04-22 11:06 ?0次下載

    Linux內(nèi)核初始化過(guò)程中的調(diào)用順序

    所有的__init函數(shù)在區(qū)段.initcall.init中還保存了一份函數(shù)指針,在初始化時(shí)內(nèi)核會(huì)通過(guò)這些函數(shù)指針調(diào)用這些__init函數(shù)指針,并在整個(gè)
    發(fā)表于 05-12 08:40 ?1673次閱讀

    你知道C之變量初始化的重要性?

    C之變量初始化的重要性
    發(fā)表于 05-15 16:46 ?1080次閱讀
    你知道C之<b class='flag-5'>變量</b><b class='flag-5'>初始化</b>的重要性?

    在51平臺(tái)下初始化文件的引入導(dǎo)致全局變量無(wú)法初始化的問(wèn)題如何解決

    本文檔的主要內(nèi)容詳細(xì)介紹的是在51平臺(tái)下初始化文件的引入導(dǎo)致全局變量無(wú)法初始化的問(wèn)題如何解決。
    發(fā)表于 08-20 17:31 ?0次下載
    在51平臺(tái)下<b class='flag-5'>初始化</b>文件的引入導(dǎo)致全局<b class='flag-5'>變量</b>無(wú)法<b class='flag-5'>初始化</b>的問(wèn)題如何解決

    EE-88:使用21xx編譯器初始化C語(yǔ)言中的變量

    EE-88:使用21xx編譯器初始化C語(yǔ)言中的變量
    發(fā)表于 05-19 21:08 ?1次下載
    EE-88:使用21xx編譯器<b class='flag-5'>初始化</b>C語(yǔ)言中的<b class='flag-5'>變量</b>

    單片機(jī)C語(yǔ)言之指針變量

    單片機(jī)C語(yǔ)言變量分別有char,int,long,float,它們分別占用內(nèi)存為1個(gè)單
    發(fā)表于 11-21 09:06 ?15次下載
    單片機(jī)C語(yǔ)言之<b class='flag-5'>指針</b><b class='flag-5'>變量</b>

    dart語(yǔ)言的變量聲明與初始化

    變量是每一們語(yǔ)言的基礎(chǔ),在Dart中所有變量都是對(duì)象,并且都有一個(gè)初始化的值null。
    的頭像 發(fā)表于 12-08 16:47 ?1389次閱讀

    實(shí)戰(zhàn)經(jīng)驗(yàn) | Keil、IAR、CubeIDE 中變量不被初始化方法

    關(guān)鍵詞:不被初始化,編譯環(huán)境 目錄預(yù)覽 1、前言 2、IAR 實(shí)現(xiàn)變量初始化方法 3、Keil 實(shí)現(xiàn)變量不被初始化方法 4、CubeIDE
    的頭像 發(fā)表于 11-24 18:05 ?5003次閱讀

    C語(yǔ)言編程時(shí),各種類型的變量如何初始化?

    C語(yǔ)言編程時(shí),各種類型的變量如何初始化? 在C語(yǔ)言中,每個(gè)變量都需要在使用之前進(jìn)行初始化初始化
    的頭像 發(fā)表于 12-07 13:53 ?1485次閱讀