<ruby id="bdb3f"></ruby>

    <p id="bdb3f"><cite id="bdb3f"></cite></p>

      <p id="bdb3f"><cite id="bdb3f"><th id="bdb3f"></th></cite></p><p id="bdb3f"></p>
        <p id="bdb3f"><cite id="bdb3f"></cite></p>

          <pre id="bdb3f"></pre>
          <pre id="bdb3f"><del id="bdb3f"><thead id="bdb3f"></thead></del></pre>

          <ruby id="bdb3f"><mark id="bdb3f"></mark></ruby><ruby id="bdb3f"></ruby>
          <pre id="bdb3f"><pre id="bdb3f"><mark id="bdb3f"></mark></pre></pre><output id="bdb3f"></output><p id="bdb3f"></p><p id="bdb3f"></p>

          <pre id="bdb3f"><del id="bdb3f"><progress id="bdb3f"></progress></del></pre>

                <ruby id="bdb3f"></ruby>

                # 引入 ## 實驗 我想通過以下方式來打印字符數組`a`和`b` ```c #include <stdio.h> int main(int argc, char const *argv[]) { char a[3] = {'d','e','f'}; char b[3] = {"abc"}; printf("%s\n", b); printf("%s\n", a); return 0; } ``` ## 運行 ```sh zhoumengkang@OSX10111-3c15c2ba060a:~/Downloads$ gcc test4.c -o test4 zhoumengkang@OSX10111-3c15c2ba060a:~/Downloads$ ./test4 abcdef??6R? def??6R? zhoumengkang@OSX10111-3c15c2ba060a:~/Downloads$ ./test4 abcdef? R? def? R? zhoumengkang@OSX10111-3c15c2ba060a:~/Downloads$ ./test4 abcdef??R? def??R? zhoumengkang@OSX10111-3c15c2ba060a:~/Downloads$ ./test4 abcdef?*?^? def?*?^? ``` ## 規律 打印 b 的時候總是會把 a 也附帶在后面; a 本身也會附帶一些“詭異”的亂碼。 ## 原因 因為我們在定義`a`和`b`的時候都沒有在末尾加上`\0`,這樣在打印字符串的時候,會一直從字符串首字符的指針地址向后,一直輸出,直到遇到`\0`。 而 a 和 b 都是在棧上分配內存,所以是向下增長,所以 b 的地址比 a 的小; 當打印 b 的時候,末尾沒有找到`\0`,而緊接著后面就是 a 了,所以繼續打印。一直打印完 a 還是沒有發現`\0`,繼續向后輸出,直到發現`\0`。 這樣就解釋了上面發現的規律。 ## 改進 ```c char a[4] = {'d','e','f','\0'}; char b[4] = {"abc"}; // 等同于 char b[4] = "abc"; ``` 定義的時候多申請一個字節的內存(也就是數組數加一),然后末尾加上`\0`;然后再打印就不會出現詭異的亂碼了。 雙引號初始化的時候,會申請的內存空間夠用的情況下,末尾加上`\0`,詳情見之前數組的筆記:https://mengkang.net/1008.html#blog-title-4 # 字符串 在 C 語言中,字符串實際上是使用 null 字符 `\0` 終止的一維字符數組。 **初始化字符串時,請務必使用`雙引號`,java 里面也如此。** ```c #include <stdio.h> int main(int argc, char const *argv[]) { char *c = "abcdef"; printf("%s\n", c); return 0; } ``` 以指針的方式來定義的時候,則會默認在字符串的末尾加上一個`\0`,這樣打印的時候就不會越界了。 ## 字符串初始化的原理 按照我們前面對指針的理解:這里的`c`是一個`char`類型的指針,應該是賦值一個`char`字符的地址才對呀。這么用才是前面說的基本數據類型和指針對應的思路 ```c char a = 'a'; char *c = &a; ``` 的確,上面的方式沒問題。 **那么為什么字符串也可以賦值給字符指針變量呢?** ```c char *c = "abcdef"; ``` ### 雙引號的秘密 雙引號做了3件事: - 在常量區申請內存,存放字符串 - 在字符串尾加上了'/0' - 返回字符串的首地址 所以這里的賦值操作是將`abcdef\0`的首地址賦值給了`c`。 ### 字符串的生命周期 假如在一個函數里聲明了一個常量字符串,那么在函數運行結束后,它的內存會回收嗎? ```c #include <stdio.h> char * a(); int main(int argc, char const *argv[]) { a(); a(); return 0; } char * a() { char *b = "string"; printf("%p\n", b); return b; } ``` 運行結果 ``` $ ./test 0x1069bdfa6 0x1069bdfa6 ``` 可以看出,字符串的內存在函數運行結束后是沒有被回收的。
                  <ruby id="bdb3f"></ruby>

                  <p id="bdb3f"><cite id="bdb3f"></cite></p>

                    <p id="bdb3f"><cite id="bdb3f"><th id="bdb3f"></th></cite></p><p id="bdb3f"></p>
                      <p id="bdb3f"><cite id="bdb3f"></cite></p>

                        <pre id="bdb3f"></pre>
                        <pre id="bdb3f"><del id="bdb3f"><thead id="bdb3f"></thead></del></pre>

                        <ruby id="bdb3f"><mark id="bdb3f"></mark></ruby><ruby id="bdb3f"></ruby>
                        <pre id="bdb3f"><pre id="bdb3f"><mark id="bdb3f"></mark></pre></pre><output id="bdb3f"></output><p id="bdb3f"></p><p id="bdb3f"></p>

                        <pre id="bdb3f"><del id="bdb3f"><progress id="bdb3f"></progress></del></pre>

                              <ruby id="bdb3f"></ruby>

                              哎呀哎呀视频在线观看