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

                合規國際互聯網加速 OSASE為企業客戶提供高速穩定SD-WAN國際加速解決方案。 廣告
                【20.1 **隱藏中間變量為何物?**】 “隱藏中間變量”雖然視之不見摸之不著,但是像空氣一樣無處不在。它有什么規律,是什么類型,數值范圍是多大,研究它有什么實用價值?這就是本節要解開之謎。 前面章節提到,兩個加數相加,其結果暫時先保存在一個“隱藏中間變量”里,運算結束后才把這個“隱藏中間變量”賦值給左邊的“保存變量”。這里的“隱藏中間變量”到底是unsigned int類型還是unsigned long類型?為了研究它的規律,我在Keil自帶的C51編譯環境下,專門編寫了幾個測試程序來觀察實際運行的結果。 “保存變量”=“加數1”+“加數2”; 下面分別變換“保存變量”、“加數1”、“加數2”這三個元素的數據類型,來觀察“隱藏中間變量”背后的秘密。 (1)“unsigned int”=“unsigned char”+“unsigned char”; unsigned int a; unsigned char x1=0x12; unsigned char y1=0xfe; a=x1+y1; 運算結果:a等于0x0110。 分析過程:兩個char類型的數相加其運算結果暫時保存在“隱藏中間變量”,當運算結果大于兩個“加數”unsigned char本身時,并沒有發生溢出現象,unsigned int類型的“保存變量”a最終得到了完整的結果0x0110。 初步結論:這種情況,“隱藏中間變量”估計為unsigned int 類型。 (2)“unsigned long”=“unsigned int”+“unsigned char”; unsigned long b; unsigned int x2=0xfffe; unsigned char y2=0x12; b=x2+y2; 運算結果:b等于十六進制的0x0010。 分析過程:一個unsigned int類型的數與一個unsigned char類型的數相加,當運算結果大于其中最大加數unsigned int類型本身時,因為左邊的“保存變量”本來就是unsigned long類型,所以我本來以為運算結果應該是unsigned long類型的0x00010010,但是實際結果出乎我的意料,最終結果是unsigned int類型的0x0010,顯然發生了溢出現象。 初步結論:這種情況,“隱藏中間變量”估計為unsigned int 類型。 (3)“unsigned long”=“常量”+“常量”; unsigned long c; c=50000+50000; 運算結果:c等于100000。 分析過程:unsigned int的最大數據范圍是65535,而兩個常量相加,其結果超過了65535卻還能完整保存下來。 初步結論:這種右邊加數都是常量的情況下,“隱藏中間變量”估計等于左邊的“保存變量”類型。 (4)“unsigned long”=“unsigned int”+“常量”; unsigned long d; unsigned long e; unsigned int x3=50000; d=x3+30000; e=x3+50000; 運算結果:d等于14464,e等于100000。 分析過程:本來以為d應該等于80000的,結果卻是14464顯然發生了溢出。而同樣的條件下,e是100000卻沒有發生溢出。 **個人結論**:這個現象讓我突然崩潰,實在研究不下去了。這是一種很怪異的現象,為什么同樣的類型,因為常量的不同,一個發生了溢出,另外一個沒有發生溢出?這時的“隱藏中間變量”到底是unsigned int類型還是unsigned long類型?我無法下結論。經過上述簡單的測試,我發現規律是模糊的,模糊的規律就不能成為規律。如果真要按這種思路研究下去,那真是沒完沒了,因為還有很多情況要研究,當超過3個以上加數相加,同時存在unsigned long,unsigned int,unsigned char,以及“常量”這4種類型時又是什么規律?在不同的C編譯器里又會是什么現象?即使把所有情況的規律摸清楚了又能怎么樣,因為那么繁雜很容易忘記導致出錯。有什么解決的辦法嗎? 【20.2 **解決辦法。**】 “當遇到有爭議的問題時,與其參與爭議越陷越深,還不如想辦法及時抽身繞開爭議。”根據這個指導思想,我提出一種解決思路**“為了避免出現意想不到的溢出,在實際項目中,所有參與運算的變量都預先轉化為unsigned long變量,再參與運算。”** 當然,也可能有人會問,如果計算結果超過了unsigned long最大范圍時怎么辦?我的回答是:首先,大多數項目的計算量都比較簡單,一般情況下都不會超過unsigned long最大范圍,但是,如果真遇到有可能超過unsigned long最大范圍的運算項目時,那么就要用另外一種BCD碼數組的運算算法來解決,而這個方法本節暫時不介紹,等以后再講。 繼續回到剛才的話題,“為了避免出現意想不到的溢出,在實際項目中,所有參與運算的變量都預先轉化為unsigned long變量,再參與運算。”如何把所有的運算變量都轉化為unsigned long變量?現在介紹一下這個方法。 第一個例子:比如上述第(2)個例子,其轉換方法如下: unsigned long f; unsigned int x2=0xfffe; unsigned char y2=0x12; unsigned long t; //多增加一個long類型的變量,用來變換類型。 unsigned long r; //多增加一個long類型的變量,用來變換類型。 t=0; //把變量的高位和低位全部清零。 t=x2; //把x2的數值先放到一個long類型的變量里,讓”加數”跟”保存變量”類型一致。 r=0; //把變量的高位和低位全部清零。 r=y2; //把y2的數值先放到一個long類型的變量里,讓”加數”跟”保存變量”類型一致。 f=t+r; 運算結果:f等于十六進制的0x00010010,沒有發生溢出現象。 第二個例子:比如上述第(4)個例子,其轉換方法如下: unsigned long g; unsigned long h; unsigned int x3=50000; unsigned long t; //多增加一個long類型的變量,用來變換類型 t=0; //把變量的高位和低位全部清零。 t=x3; //把x3的數值先放到一個long類型的變量里,讓”加數”跟”保存變量”類型一致。 g=t+30000; h=t+50000; 運算結果:g等于80000,h等于100000。都沒有發生溢出。 【20.3 例程練習和分析。】 現在我們編寫一個程序來驗證上面講到的例子: 程序代碼如下: /\*---C語言學習區域的開始。-----------------------------------------------\*/ void main() //主函數 { unsigned int a; //第(1)個例子 unsigned char x1=0x12; unsigned char y1=0xfe; unsigned long b; //第(2)個例子 unsigned int x2=0xfffe; unsigned char y2=0x12; unsigned long c; //第(3)個例子 unsigned long d; //第(4)個例子 unsigned long e; unsigned int x3=50000; unsigned long f; //第(2)個例子改進之后 unsigned long g; //第(4)個例子改進之后 unsigned long h; unsigned long t; //多增加一個long類型的變量,用來變換類型。 unsigned long r; //多增加一個long類型的變量,用來變換類型。 //第(1)個例子 a=x1+y1; //第(2)個例子 b=x2+y2; //第(3)個例子 c=50000+50000; //第(4)個例子 d=x3+30000; e=x3+50000; //第(2)個例子改進之后 t=0; //把變量的高位和低位全部清零。 t=x2; //把x2的數值先放到一個long類型的變量里,讓”加數”跟”保存變量”類型一致。 r=0; //把變量的高位和低位全部清零。 r=y2; //把y2的數值先放到一個long類型的變量里,讓”加數”跟”保存變量”類型一致。 f=t+r; //第(4)個例子改進之后 t=0; //把變量的高位和低位全部清零。 t=x3; //把x3的數值先放到一個long類型的變量里,讓”加數”跟”保存變量”類型一致。 g=t+30000; h=t+50000; View(a); //把第1個數a發送到電腦端的串口助手軟件上觀察。 View(b); //把第2個數b發送到電腦端的串口助手軟件上觀察。 View(c); //把第3個數c發送到電腦端的串口助手軟件上觀察。 View(d); //把第4個數d發送到電腦端的串口助手軟件上觀察。 View(e); //把第5個數e發送到電腦端的串口助手軟件上觀察。 View(f); //把第6個數f發送到電腦端的串口助手軟件上觀察。 View(g); //把第7個數g發送到電腦端的串口助手軟件上觀察。 View(h); //把第8個數h發送到電腦端的串口助手軟件上觀察。 while(1) { } } /\*---C語言學習區域的結束。-----------------------------------------------\*/ 在電腦串口助手軟件上觀察到的程序執行現象如下: 開始... 第1個數 十進制:272 十六進制:110 二進制:100010000 第2個數 十進制:16 十六進制:10 二進制:10000 第3個數 十進制:100000 十六進制:186A0 二進制:11000011010100000 第4個數 十進制:14464 十六進制:3880 二進制:11100010000000 第5個數 十進制:100000 十六進制:186A0 二進制:11000011010100000 第6個數 十進制:65552 十六進制:10010 二進制:10000000000010000 第7個數 十進制:80000 十六進制:13880 二進制:10011100010000000 第8個數 十進制:100000 十六進制:186A0 二進制:11000011010100000 分析: 通過實驗結果,發現在單片機上的計算結果和我們的分析是一致的。 【20.4 如何在單片機上練習本章節C語言程序?】 直接復制前面章節中第十一節的模板程序,練習代碼時只需要更改“C語言學習區域”的代碼就可以了,其它部分的代碼不要動。編譯后,把程序下載進帶串口的51學習板,通過電腦端的串口助手軟件就可以觀察到不同的變量數值,詳細方法請看第十一節內容。
                  <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>

                              哎呀哎呀视频在线观看