<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>

                ??一站式輕松地調用各大LLM模型接口,支持GPT4、智譜、豆包、星火、月之暗面及文生圖、文生視頻 廣告
                本文目錄 - [一、字節和地址](http://www.cnblogs.com/mjios/archive/2013/05/25/3068114.html#label0) - [二、變量的存儲](http://www.cnblogs.com/mjios/archive/2013/05/25/3068114.html#label1) - [三、負數的二進制形式](http://www.cnblogs.com/mjios/archive/2013/05/25/3068114.html#label2) - [四、變量的作用域](http://www.cnblogs.com/mjios/archive/2013/05/25/3068114.html#label3) - [五、變量的初始化](http://www.cnblogs.com/mjios/archive/2013/05/25/3068114.html#label4) 在前面一節中簡單介紹了[變量](http://www.cnblogs.com/mjios/archive/2013/05/07/3065522.html)的使用,當我們定義一個變量的時候,系統就會為變量分配一塊存儲空間。而變量的數值在內存中是以二進制的形式存儲的,這講來深入研究變量在內存中的一些存儲細節。 [回到頂部](http://www.cnblogs.com/mjios/archive/2013/05/25/3068114.html#labelTop) ##一、字節和地址 為了更好地理解變量在內存中的存儲細節,先來認識一下內存中的“字節”和“地址”。 1.計算機中的內存是以[字節](http://www.cnblogs.com/mjios/archive/2013/05/07/3065522.html)為單位的存儲空間。內存的每一個字節都有一個唯一的編號,這個編號就稱為地址。就好像酒店是以房間為單位的,每個房間都有一個唯一的房號,我們根據房號就能找到對應的房間。 ![](https://box.kancloud.cn/2016-05-07_572d76614a025.png) 里面的每個小框框就代表著內存中的一個字節,白色數字就是每個字節的地址(這里采取十六進制來顯示,地址值是隨便寫的,僅作為參考,真實情況中的地址值不一定是這個),可以發現,內存中相鄰字節的地址是連續的。 2.大家都知道,一個字節有8位,所能表示的數據范圍是非常有限的,因此,范圍較大的數據就要占用多個字節,也就是說,不同類型的數據所占用的字節數是不一樣的。 [回到頂部](http://www.cnblogs.com/mjios/archive/2013/05/25/3068114.html#labelTop) ##二、變量的存儲 ### 1.變量類型的作用 跟其他編程語言一樣,C語言中用[變量](http://www.cnblogs.com/mjios/archive/2013/05/07/3065522.html)來存儲計算過程使用的值,任何變量都必須先定義類型再使用。為什么一定要先定義呢?因為變量的類型決定了變量占用的存儲空間,所以定義變量類型,就是為了給該變量分配適當的存儲空間,以便存放數據。比如char類型,它是用來存儲一個字符的,一個字符的話只需要1個字節的存儲空間, 因此系統就只會給char類型變量分配1個字節,沒必要分配2個字節、3個字節乃至更多的存儲空間。 ### 2.變量占用多少存儲空間 1> 一個變量所占用的存儲空間,不僅跟變量類型有關,而且還跟編譯器環境有關系。同一種類型的變量,在不同編譯器環境下所占用的存儲空間又是不一樣的。我們都知道操作系統是有不同位數的,比如Win7有分32位、64位,編譯器也是一樣的,也有不同位數:16位、32位、64位(Mac系統下的clang編譯器是64bit的)。由于我們是Mac系統下開發,就以64位編譯器為標準。 2> 下面的表格描述了在64位編譯器環境下,基本數據類型所占用的存儲空間,了解這些細節,對以后學習指針和數組時是很有幫助的。 ![](https://box.kancloud.cn/2016-05-07_572d766162835.png) 3> 下面的表格描述了在不同編譯器環境下的存儲空間占用情況 ![](https://box.kancloud.cn/2016-05-07_572d76617a9f3.png) ### 3.變量示例 當定義一個變量時,系統就會為這個變量分配一定的存儲空間。 ~~~ int main() { char a = 'A'; int b = 10; return 0; } ~~~ 1> 在64bit編譯器環境下,系統為變量a、b分別分配1個字節、4個字節的存儲單元。也就是說: - 變量b中的10是用4個字節來存儲的,4個字節共32位,因此變量b在內存中的存儲形式應該是0000 0000 0000 0000 0000 0000 0000 1010。 - 變量a中的'A'是用1個字節來存儲的,1個字節共8位,變量a在內存中的存儲形式是0100 0001,至于為什么'A'的二進制是這樣呢,后面再討論。 2> 上述變量a、b在內存中的存儲情況大致如下表所示: ![](https://box.kancloud.cn/2016-05-07_572d76619262b.png) (注:"存儲的內容"那一列的一個小格子就代表一個字節,"地址"那一列是指每個字節的地址) - 從圖中可以看出,變量b占用了內存地址從ffc1~ffc4的4個字節,變量a占用了內存地址為ffc5的1個字節。每個字節都有自己的地址,其實變量也有地址。變量存儲單元的第一個字節的地址就是該變量的地址。變量a的地址是ffc5,變量b的地址是ffc1。 - 內存尋址是從大到小的,也就是說做什么事都會先從內存地址較大的字節開始,因此系統會優先分配地址值較大的字節給變量。由于是先定義變量a、后定義變量b,因此你會看到變量a的地址ffc5比變量b的地址ffc1大。 - 注意看表格中變量b存儲的內容,變量b的二進制形式是:0000 0000 0000 0000 0000 0000 0000 1010。由于內存尋址是從大到小的,所以是從內存地址最大的字節開始存儲數據,存放順序是ffc4 -> ffc3 -> ffc2 -> ffc1,所以把前面的0000 0000都放在ffc2~ffc4中,最后面的八位0000 1010放在ffc1中。 ### 4.查看變量的內存地址 在調試過程中,我們經常會采取打印的方式查看變量的地址 ~~~ #include <stdio.h> int main() { int a = 10; printf("變量a的地址是:%p", &a); return 0; } ~~~ 第6行中的&是一個地址運算符,&a表示取得變量a的地址。格式符%p是專門用來輸出地址的。輸出結果是: 變量a的地址是:0x7fff5fbff8f8 這個0x7fff5fbff8f8就是變量a的內存地址 [回到頂部](http://www.cnblogs.com/mjios/archive/2013/05/25/3068114.html#labelTop) ##三、負數的二進制形式 ~~~ int main() { int b = -10; return 0; } ~~~ 在第3行定義了一個整型變量,它的值是-10。-10在內存中怎樣存儲的呢?其實任何數值在內存中都是以補碼的形式存儲的。 - 正數的補碼與原碼相同。比如9的原碼和補碼都是1001 - 負數的補碼等于它正數的原碼取反后再+1。(取反的意思就是0變1、1變0) 那么-10的補碼計算過程如下: 1> 先算出10的二進制形式:0000 0000 0000 0000 0000 0000 0000 1010 2> 對10的二進制進行取反:1111 1111?1111 1111?1111 1111 1111 0101 3> 對取反后的結果+1:1111 1111?1111 1111?1111 1111 1111?0110 因此,整數-10在內存中的二進制形式是:1111 1111?1111 1111?1111 1111 1111?0110 ![](https://box.kancloud.cn/2016-05-07_572d7661a5c5f.png) [回到頂部](http://www.cnblogs.com/mjios/archive/2013/05/25/3068114.html#labelTop) ##四、變量的作用域 ### 1.作用域簡介 變量的作用域就是指變量的作用范圍。先來看看下面的程序: ~~~ int main() { int a = 7; return 0; } ~~~ - 在第3行定義了一個變量a,當執行到這行代碼時,系統就會為變量a分配存儲空間 - 當main函數執行完畢,也就是執行完第5行代碼了,變量a所占用的內存就會被系統自動回收 - 因此,變量a的作用范圍是從定義它的那行開始,一直到它所在的大括號{}結束,也就是第3~6行,一旦離開這個范圍,變量a就失效了 ### 2.代碼塊 1> 代碼塊其實就是用大括號{}括住的一塊代碼。 ~~~ int main() { { int a = 10; printf("a=%d", a); } a = 9; return 0; } ~~~ - 注意第3~7行的大括號,這就是一個代碼塊 - 當執行到第4行時,系統會分配內存給變量a - 當代碼塊執行完畢,也就是執行完第6行代碼后,變量a所占用的內存就會被系統回收 - 因此,變量a的作用范圍是從定義它的那行開始,一直到它所在的大括號{}結束,也就是第4~7行,離開這個范圍,變量a就失效了 - 所以,上面的程序是編譯失敗的,第9行代碼是錯誤的,變量a在第7行的時候已經失效了,不可能在第9行使用 2> 如果是下面這種情況 ~~~ int main() { int a = 9; { int a = 10; printf("a=%d", a); } return 0; } ~~~ - 注意第3、6行,各自定義了一個變量a,這種情況是沒問題的。C語言規定:在不同作用域中允許有同名變量,系統會為它們分配不同的存儲空間。 - 在第3行定義的變量a的作用域是:第3~12行;在第6行定義的變量a的作用域是:第6~9行。 - 最后注意第8行:嘗試輸出變量a的值。那這里輸出的是哪一個變量a呢?先看輸出結果: a=10 這里采取的是“就近原則”,也就是第8行訪問的是在第6行定義的變量a,并不是在第3行的變量a。 [回到頂部](http://www.cnblogs.com/mjios/archive/2013/05/25/3068114.html#labelTop) ##五、變量的初始化 變量在沒有進行初始化之前,不要拿來使用,因為它里面存儲的是一些垃圾數據 ~~~ #include <stdio.h> int main() { int c; printf("%d", c); return 0; } ~~~ 注意第5行的變量c,只是定義了變量,并沒有給它賦初值。輸出結果: 1606422622 可以發現,變量c里面存儲的是一些亂七八糟的數據
                  <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>

                              哎呀哎呀视频在线观看