<kbd id="afajh"><form id="afajh"></form></kbd>
<strong id="afajh"><dl id="afajh"></dl></strong>
    <del id="afajh"><form id="afajh"></form></del>
        1. <th id="afajh"><progress id="afajh"></progress></th>
          <b id="afajh"><abbr id="afajh"></abbr></b>
          <th id="afajh"><progress id="afajh"></progress></th>

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

          共 3334字,需瀏覽 7分鐘

           ·

          2021-02-28 22:20

          關(guān)注、星標(biāo)公眾號,直達(dá)精彩內(nèi)容

          ID:技術(shù)讓夢想更偉大

          整理:李肖遙


          在敲代碼的時候,我們會給變量一個初始值,以防止因為編譯器的原因造成變量初始值的不確定性。對于數(shù)值類型的變量往往初始化為0,但對于其他類型的變量,如字符型、指針型等變量等該如何初始化呢?

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

          整型、浮點型的變量可以在定義的同時進(jìn)行初始化,一般都初始化為0。
          1int    inum  = 0;
          2float  fnum = 0.00f;
          3double dnum = 0.00;

          字符型變量初始化

          字符型變量也可在定義的同時進(jìn)行初始化,一般初始化為'\0'。
          1char ch = '\0'

          字符串初始化

          字符串初始化的方法比較多,我這里簡單介紹三種,因為字符串本質(zhì)上是由一個個字符組成的字符數(shù)組,所以其初始化的最終目的,就是將字符數(shù)組里面的一個個字符都初始化為'\0'
          方法一:使用空的字符串""。
          char str[10] = "";
            方法二:使用memset
            char str[10];
            memset(str, 0, sizeof(str));
              方法三:寫一個循環(huán)。
              char str[10];
              for(int i = 0; i < 10; i++)
              {
              str[i] = '\0';
              }
                這里比較推薦的是第二種初始化方法。也即使用memset進(jìn)行初始化。
                很多人對memset這個函數(shù)一知半解,只知道它可以初始化很多數(shù)據(jù)類型的變量,卻不知道其原理是什么樣的,這里做一下簡要的說明: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);
                  在討論之前,我們先看一下運行結(jié)果
                  chenyc@DESKTOP-IU8FEL6:~/src$ gcc -o memset memset.c -g
                  chenyc@DESKTOP-IU8FEL6:~/src$ ./memset
                  step1 = 0
                  step2 = 16843009
                  chenyc@DESKTOP-IU8FEL6:~/src$
                    看到這個運行結(jié)果,是不是和你想象中的不一樣呢?
                    step1 = 0 相信大家都好理解,可 step2 = 16843009 很多人就不能理解了。按照一般的慣性思維,不是應(yīng)該 = 1 才對么?
                    這就是我要說的,memset是按照字節(jié)進(jìn)行填充的。
                    我們知道,
                    int 型是4個字節(jié)(每個字節(jié)有8位),按二進(jìn)制表示出來就應(yīng)該是:
                    00000000 00000000 00000000 00000000
                      按照按字節(jié)填充的原則,step1 的結(jié)果就是將4個字節(jié)全部填充0,所以得到的結(jié)果仍然是0:
                      00000000 00000000 00000000 00000000
                        而 step2 則是將每個字節(jié)都填充為1 (注意是每個字節(jié),而不是每個byte位) ,所以相對應(yīng)的結(jié)果就應(yīng)該是:
                        00000001 00000001 00000001 00000001
                          大家可以自己將上面那個二進(jìn)制數(shù)轉(zhuǎn)換成十進(jìn)制看看,看看是不是16843009
                          所以嚴(yán)格來說,memset函數(shù)本身并不具有初始化的功能,而是一個單純的按字節(jié)填充函數(shù),只是人們在使用的過程中,擴(kuò)展出了初始化的作用。
                          字符串初始化有一個小竅門,我們知道字符串本質(zhì)上是字符數(shù)組,因此它具有兩個特性,
                          • 字符串在內(nèi)存里是連續(xù)的,
                          • 字符串遇'\0'結(jié)束。
                            所以我們在初始化的時候,總是愿意給字符串本身長度加1的長度的內(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;
                              指針是個讓人又愛又恨的東西,一般的整形、字符串等,初始化之后就可以直接拿來用了,可指針如果初始化為NULL后,沒有給該指針重新分配內(nèi)存,則會出現(xiàn)難以預(yù)料的錯誤(最最常見的就是操作空指針引起的段錯誤)。
                              在動態(tài)內(nèi)存管理中,由于變量的內(nèi)存是分配在堆中的,所以一般用malloccalloc等函數(shù)申請過動態(tài)內(nèi)存,在使用完后需要及時釋放,一般釋放掉動態(tài)內(nèi)存后要及時將指針置空,這也是很多人容易忽略的。
                              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; //這一行給指針置空必不可少,否則很可能后面操作了這個野指針而不自知,從而導(dǎo)致出現(xiàn)嚴(yán)重的問題
                                很多人經(jīng)常會犯的一個錯誤,我們知道,在指針作為實參進(jìn)行參數(shù)傳遞時,該指針就已經(jīng)退化成了數(shù)組,所以很多人就想到用memset來對該指針進(jìn)行初始化:
                                void fun(char *pstr)
                                {
                                memset(pstr, 0, sizeof(pstr));
                                ...
                                }
                                  這種寫法是不正確的。我們姑且不管指針能不能用memset來進(jìn)行初始化,指針首先保存的是一個4字節(jié)的地址,所以sizeof(pstr)永遠(yuǎn)只能 = 4,這樣的初始化就毫無意義。

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

                                  結(jié)構(gòu)體的初始化就比較簡單了,基本也都是采用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)體的長度問題,也即memset的第三個參數(shù),一般來說,傳入數(shù)據(jù)類型和變量名效果是一樣的,上例中,下面寫法是等價的效果:
                                    memset((char *)&stu1, 0, sizeof(STU));
                                      但是對于結(jié)構(gòu)體數(shù)組的初始化,長度就需要注意一下了,還是以上例來做說明:
                                      STU stus[10];
                                      memset((char *)&stus, 0, sizeof(stus)); //正確,數(shù)組本身在內(nèi)存里就是連續(xù)的,sizeof取出的就是數(shù)組的字節(jié)長度
                                      memset((char *)&stus, 0, sizeof(STU)); //錯誤,只會初始化第一個STU結(jié)構(gòu)體,后面還有9個STU元素并未初始化
                                      memset((char *)&stus, 0, sizeof(STU)*10); //正確,效果與第一個是一樣的
                                        有些人習(xí)慣將memset的第二個參數(shù)寫成以下形式:
                                        memset((char *)&stu1, 0x00, sizeof(stu1));
                                          只要理解了memset是按字節(jié)進(jìn)行填充的,就知道這樣寫也是正確的,完全沒有問題。

                                          ????????????????  END  ????????????????

                                          掃描下方微信,加作者微信進(jìn)技術(shù)交流群,請先自我介紹喔。



                                          推薦閱讀:


                                          嵌入式編程專輯
                                          Linux 學(xué)習(xí)專輯
                                          C/C++編程專輯
                                          Qt進(jìn)階學(xué)習(xí)專輯
                                          關(guān)注微信公眾號『技術(shù)讓夢想更偉大』,后臺回復(fù)“m”查看更多內(nèi)容。

                                          長按前往圖中包含的公眾號關(guān)注

                                          瀏覽 38
                                          點贊
                                          評論
                                          收藏
                                          分享

                                          手機(jī)掃一掃分享

                                          分享
                                          舉報
                                          評論
                                          圖片
                                          表情
                                          推薦
                                          點贊
                                          評論
                                          收藏
                                          分享

                                          手機(jī)掃一掃分享

                                          分享
                                          舉報
                                          <kbd id="afajh"><form id="afajh"></form></kbd>
                                          <strong id="afajh"><dl id="afajh"></dl></strong>
                                            <del id="afajh"><form id="afajh"></form></del>
                                                1. <th id="afajh"><progress id="afajh"></progress></th>
                                                  <b id="afajh"><abbr id="afajh"></abbr></b>
                                                  <th id="afajh"><progress id="afajh"></progress></th>
                                                  不卡视频免费在线播放 | a在线观看视频 | 在线观看av天堂 在线观看无码高清 | 麻豆AV无码精品一区二区色欲 | 久久r这里只有精品 |