日韩黑丝制服一区视频播放|日韩欧美人妻丝袜视频在线观看|九九影院一级蜜桃|亚洲中文在线导航|青草草视频在线观看|婷婷五月色伊人网站|日本一区二区在线|国产AV一二三四区毛片|正在播放久草视频|亚洲色图精品一区

分享

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

 西北望msm66g9f 2021-02-14
在敲代碼的時(shí)候,我們會(huì)給變量一個(gè)初始值,以防止因?yàn)?/span>編譯器的原因造成變量初始值的不確定性。對(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)行初始化,一般初始化為'\0'。
1char ch = '\0'

字符串初始化

字符串初始化的方法比較多,我這里簡(jiǎn)單介紹三種,因?yàn)樽址举|(zhì)上是由一個(gè)個(gè)字符組成的字符數(shù)組,所以其初始化的最終目的,就是將字符數(shù)組里面的一個(gè)個(gè)字符都初始化為'\0'。
方法一:使用空的字符串''
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] = '\0';
      }
        這里比較推薦的是第二種初始化方法。也即使用memset進(jìn)行初始化。
        很多人對(duì)memset這個(gè)函數(shù)一知半解,只知道它可以初始化很多數(shù)據(jù)類型的變量,卻不知道其原理是什么樣的,這里做一下簡(jiǎn)要的說明:memset是按照字節(jié)進(jìn)行填充的。
        先看下面的一段代碼:
        int num;
        memset(&num, 0, sizeof(int));
        printf('step1=%d\n', num);
        memset(&num, 1, sizeof(int));
        printf('step2=%d\n', 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ì)么?
            這就是我要說的,memset是按照字節(jié)進(jìn)行填充的。
            我們知道,
            int 型是4個(gè)字節(jié)(每個(gè)字節(jié)有8位),按二進(jìn)制表示出來就應(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)格來說,memset函數(shù)本身并不具有初始化的功能,而是一個(gè)單純的按字節(jié)填充函數(shù),只是人們?cè)谑褂玫倪^程中,擴(kuò)展出了初始化的作用。
                  字符串初始化有一個(gè)小竅門,我們知道字符串本質(zhì)上是字符數(shù)組,因此它具有兩個(gè)特性,
                  • 字符串在內(nèi)存里是連續(xù)的,
                  • 字符串遇'\0'結(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');

                    指針初始化

                    一般來說,指針都是初始化為NULL。
                    int *pnum = NULL;
                    int num = 0;
                    pnum = &num;
                      指針是個(gè)讓人又愛又恨的東西,一般的整形、字符串等,初始化之后就可以直接拿來用了,可指針如果初始化為NULL后,沒有給該指針重新分配內(nèi)存,則會(huì)出現(xiàn)難以預(yù)料的錯(cuò)誤(最最常見的就是操作空指針引起的段錯(cuò)誤)。
                      在動(dòng)態(tài)內(nèi)存管理中,由于變量的內(nèi)存是分配在堆中的,所以一般用malloc、calloc等函數(shù)申請(qǐng)過動(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\n',p);
                      }
                      else
                      {
                      printf('Not Enough Memory!\n');
                      }
                      free(p);
                      p = NULL; //這一行給指針置空必不可少,否則很可能后面操作了這個(gè)野指針而不自知,從而導(dǎo)致出現(xiàn)嚴(yán)重的問題
                        很多人經(jīng)常會(huì)犯的一個(gè)錯(cuò)誤,我們知道,在指針作為實(shí)參進(jìn)行參數(shù)傳遞時(shí),該指針就已經(jīng)退化成了數(shù)組,所以很多人就想到用memset來對(duì)該指針進(jìn)行初始化:
                        void fun(char *pstr)
                        {
                        memset(pstr, 0, sizeof(pstr));
                        ...
                        }
                          這種寫法是不正確的。我們姑且不管指針能不能用memset來進(jìn)行初始化,指針首先保存的是一個(gè)4字節(jié)的地址,所以sizeof(pstr)永遠(yuǎn)只能 = 4,這樣的初始化就毫無意義。

                          結(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)度問題,也即memset的第三個(gè)參數(shù),一般來說,傳入數(shù)據(jù)類型和變量名效果是一樣的,上例中,下面寫法是等價(jià)的效果:
                            memset((char *)&stu1, 0, sizeof(STU));
                              但是對(duì)于結(jié)構(gòu)體數(shù)組的初始化,長(zhǎng)度就需要注意一下了,還是以上例來做說明:
                              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)行填充的,就知道這樣寫也是正確的,完全沒有問題。

                                  來源:網(wǎng)絡(luò)

                                    本站是提供個(gè)人知識(shí)管理的網(wǎng)絡(luò)存儲(chǔ)空間,所有內(nèi)容均由用戶發(fā)布,不代表本站觀點(diǎn)。請(qǐng)注意甄別內(nèi)容中的聯(lián)系方式、誘導(dǎo)購(gòu)買等信息,謹(jǐn)防詐騙。如發(fā)現(xiàn)有害或侵權(quán)內(nèi)容,請(qǐng)點(diǎn)擊一鍵舉報(bào)。
                                    轉(zhuǎn)藏 分享 獻(xiàn)花(0

                                    0條評(píng)論

                                    發(fā)表

                                    請(qǐng)遵守用戶 評(píng)論公約

                                    類似文章 更多