最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

C 語言基礎教程(我的C之旅開始了)[九]

 更新時間:2007年02月25日 00:00:00   作者:  

24. +、-、*、/、= 的優(yōu)先級

1. 優(yōu)先級

    和數(shù)學一樣,C 語言規(guī)定先乘除后加減。也就是說,乘法運算符和除法運算符的優(yōu)先級Precedence)比加法運算符和減法運算符高。同時,C 語言也規(guī)定,如果兩個運算符的優(yōu)先級相同,并且它們之間沒有被優(yōu)先級比它們高或者低的運算符隔開,則它們的運算順序根據(jù)它們在語句中出現(xiàn)的先后而定。大多數(shù)運算符都是從左向右進行運算的,不過也有從右向左進行運算的(例如賦值運算符)。乘法運算符和除法運算符的優(yōu)先級相同,加法運算符和減法運算符的優(yōu)先級相同。因此,以下語句

        var = 8.0 + 20.0 / 4.0 * 2.0;

運算順序為:

        20.0 / 4.0
        5.0 * 2.0  (20.0 / 4.0 得 5.0)
        8.0 + 10.0
        var = 18.0

在這個表達式中,/ 和 * 優(yōu)先級相同,而且是從左向右進行運算的,所以先運算 20.0 / 4.0,然后才輪到 5.0 * 2.0。

    如果我們想讓加法先進行,可以給 8.0 + 20.0 加上括號

        var = (8.0 + 20.0) / 4.0 * 2.0;

這個語句的運算順序為:

        8.0 + 20.0
        28.0 / 4.0
        7.0 * 2.0
        var = 14.0

    C 語言規(guī)定,先進行括號里面的運算,后進行括號外面的運算。在括號里面,運算順序和上面討論的一樣。例如:

        var = (8.0 + 20.0 / 4.0 * 2.0) / 3.0;

運算順序為:

        20.0 / 4.0
        5.0 * 2.0
        8.0 + 10.0
        18.0 / 3.0
        var = 6.0

下表總結(jié)了這幾個運算符的優(yōu)先級以及它們的結(jié)合律,按優(yōu)先級從高到低進行排列

        運算符             結(jié)合律

          ()               從左向右
       + -(單目)         從右向左
         * /               從左向右
       + -(二目)         從左向右
          =                從右向左


2. 優(yōu)先級和運算順序

    運算符優(yōu)先級Operator precedence)是決定運算順序的重要規(guī)則,但不能完全(也沒必要完全)確定運算順序。例如:

        5 * 3 + 8 * 4;

根據(jù)運算符優(yōu)先級,我們知道,乘法運算先于加法運算。但是 5 * 3 和 8 * 4 誰先誰后,我們并不能確定。它們運算的先后是由編譯器決定的。這是因為某種運算順序在某種系統(tǒng)中效率更高,而另一種運算順序在另一種系統(tǒng)中效率更高。無論它們的運算先后如何,最終得到的結(jié)果都是 47。

    您可能會說:“乘法不是從左向右進行運算的嗎?這不是說明最左邊的乘法最先進行嗎?”是的,乘法的確是從左向右進行運算,但是您也要看到,這兩個乘法運算符之間被加法運算符隔開了!我們舉一個例子來說明乘法從左向右進行運算的意思。以下語句

        5 * 2 * 9 * 4;

運算順序為:

        5 * 2
        10 * 9
        90 * 4


下面我們來看一個小程序。

        /* precedence.c -- 優(yōu)先級測試 */
        #include <stdio.h>

        int main(void)
        {
            int var1, var2;

            var1 = var2 = -(9 + 4) * 5 + (6 + 8 * (7 - 1));
            printf("var1 = var2 = %d\n", var1);

            return 0;
        }

請認真閱讀以上程序,想想會出現(xiàn)什么結(jié)果,然后編譯運行,看看運行結(jié)果和您想象的是否一樣。

    首先,括號運算符優(yōu)先級最高。但是 (9 + 4) 和 (6 + 8 * (7 - 1)) 運算的先后是由編譯器決定的。假設 (9 + 4) 先進行,則運算后得 13,然后負號運算符作用于 13 得 -13。于是我們得到:

        var1 = var2 = -13 * 5 + (6 + 8 * (7 - 1));

在 (6 + 8 * (7 - 1)) 中,先運算 (7 - 1),得:

        var1 = var2 = -13 * 5 + (6 + 8 * 6);

因為 * 優(yōu)先級高于 +,于是我們得到:

        var1 = var2 = -13 * 5 + (6 + 48);

進而

        var1 = var2 = -13 * 5 + 54;
        var1 = var2 = -65 + 54;
        var1 = var2 = -11;

因為賦值運算是從右向左的,所以 -11 被賦值給 var2,接著 var2 被賦值給 var1。最終的結(jié)果是,var1 和 var2 相等,它們的值都是 -11。


 

25. 模除運算符 %

 

    %模除運算符Modulus Operator),用于求余數(shù)。% 只可用于對整數(shù)進行模除,不可用于浮點數(shù)。例如:

          15 % 2       // 正確。余數(shù)為 1
          15.2 % 3     // 錯誤!

C99 以前,并沒有規(guī)定如果操作數(shù)中有負數(shù),模除的結(jié)果會是什么。C99 規(guī)定,如果 % 左邊的操作數(shù)是正數(shù),模除的結(jié)果也是正數(shù);如果 % 左邊的操作數(shù)是負數(shù),模除的結(jié)果就是負數(shù)。例如:

          15 % 2       // 余 1
          15 % -2      // 余 1
          -15 % 2      // 余 -1
          -15 % -2     // 余 -1

標準規(guī)定,如果 a 和 b 都是整數(shù),則 a % b 可以用公式 a - (a / b) * b 算出。例如:

          -15 % 2 == -15 - (-15 / 2) * 2 == -15 - (-7) * 2 == -1

最后,我們看一個小程序。

        /* months_to_year.c -- 將用戶輸入的月數(shù)轉(zhuǎn)換成年數(shù)和月數(shù) */

        #include <stdio.h>

        int main(void)
        {
            int months, years, months_left, months_per_year = 12;

            printf("Enter the number of months: ");
            scanf("%d", &months);

            years = months / months_per_year;         /* 算出年數(shù) */
            months_left = months % months_per_year;   /* 算出剩余的月數(shù) */

            printf("%d months is %d years, %d months.\n", months, years, months_left);

            return 0;
        }

26. 自增運算符和自減運算符
 

1. 自增運算符(Increment Operator)

    自增運算符 ++ 使操作數(shù)的值增 1。++ 可以置于操作數(shù)前面,也可以放在后面。例如:

        ++n ;
        n++ ;

這兩個語句產(chǎn)生的結(jié)果都是使 n 增 1,可以說沒什么區(qū)別。使用以下語句得到的效果也是一樣的:

        n = n + 1 ;

    盡管上面兩個語句中,++ 前置和后置沒有區(qū)別。但是,++ 前置和后置其實是有區(qū)別的。例如:

        int n = 1, post, pre;

        post = n++;
        pre = ++n;

對于 post = n++; 這個語句,n 的值被賦予 post 后,n 才增 1。也就是說,這個語句執(zhí)行完后,post 的值是 1,而 n 的值變成 2。而 pre = ++n; 這個語句,n 先增 1,然后再把自增后的值賦予 pre。也就是說,這個語句執(zhí)行完后,pre 的值是 3,n 的值也是 3。

    由此可得,如果 ++ 前置,則 ++ 的操作數(shù)先增 1,然后再參與其它運算;如果 ++ 后置,則 ++ 的操作數(shù)先參與其它運算,然后才增 1。嚴格地說,前置 ++ 的操作數(shù)的值在被使用之前增 1,而后置 ++ 的操作數(shù)的值在被使用之后增 1。例如:

        int n = 5, post = 1, pre = 1;
        pre = ++n + pre;    // 運算結(jié)束后 pre 為 7
        n = 5;
        post = n++ + post;  // 運算結(jié)束后 post 為 6

 

2. 自減運算符(Decrement Operator)

    自減運算符 -- 使操作數(shù)的值減 1。-- 可以置于操作數(shù)前面,也可以放在后面。例如:

        --n ;
        n-- ;

自減運算符和自增運算符非常相似,區(qū)別只在于自減運算符使操作數(shù)減 1,而自增運算符使操作數(shù)增 1。例如:

        int n = 5, post = 1, pre = 1;
        pre = --n + pre;    // 運算結(jié)束后 pre 為 5
        n = 5;
        post = n-- + post;  // 運算結(jié)束后 post 為 6

 

3. 優(yōu)先級

    自增運算符和自減運算符的優(yōu)先級很高,只有圓括號的優(yōu)先級比它們高。因此,n*m++; 表示 n*(m++); 而不是 (n * m)++; 。而且 (n * m)++; 是錯誤的。因為 ++ 和 -- 的操作數(shù)只能是可變左值(modifiable lvalue),而 n * m 不是。

    注意,不要把優(yōu)先級和取值順序混淆了。例如:

        int x = 1, y = 2, z;

        z = (x + y++) * 3;   // 運算結(jié)束后 z 為 9,y 為 3

用數(shù)字代替上面的語句得:

        z = (1 + 2) * 3;

僅當 y 的值被使用后,y 才會增 1。優(yōu)先級表明的是 ++ 僅作用于 y,而不是 (x + y)。優(yōu)先級也表明 y 的值何時被使用,但是 y 的值何時增 1 是由自增運算符的本質(zhì)決定的。

    當 y++ 是某個算術表達式的一部分時,您可以認為它表示“先使用 y 的值,然后自增”。類似地,++y 表示“先自增,然后使用自增后的值”。

==========================================================================

以下內(nèi)容引自《C 語言常見問題集》 原著:Steve Summit 翻譯:朱群英, 孫 云

http://c-faq-chn.sourceforge.net/ccfaq/index.html

http://www.eskimo.com/~scs/C-faq/top.html

==========================================================================

4.3 對于代碼  int i = 3; i = i++; 不同編譯器給出不同的結(jié)果, 有的為 3, 有的為 4, 哪個是正確的?

    沒有正確答案;這個表達式無定義。參見問題 3.1, 3.7 和  11.32。 同時注意, i++ 和 ++i 都不同于 i+1。如果你要使 i 自增 1, 使用 i=i+1, i+=1, i++ 或 ++i, 而不是任何組合, 參見問題 3.10。

12.35 有人說 i = i++ 的行為是未定義的, 但是我剛在一個兼容 ANSI  的編譯器上測試, 得到了我希望的結(jié)果。

    面對未定義行為的時候, 包括范圍內(nèi)的實現(xiàn)定義行為和未確定行為, 編譯器可以做任何實現(xiàn), 其中也包括你所有期望的結(jié)果。但是依靠這個實現(xiàn)卻不明智。參加問題 7.4, 11.31, 11.32 和 11.34

4.2 使用我的編譯器,下面的代碼  int i=7; printf("%d\n", i++ * i++); 返回 49?不管按什么順序計算, 難道不該打印出56嗎?

    盡管后綴自加和后綴自減操作符 ++ 和 -- 在輸出其舊值之后才會執(zhí)行運算, 但這里的``之后"常常被誤解。沒有任何保證確保自增或自減會在輸出變量原值之后和對表達式的其它部分進行計算之前立即進行。也不能保證變量的更新會在表達式 ``完成" (按照 ANSI C 的術語, 在下一個 ``序列點" 之前, 參見問題 3.7) 之前的某個時刻進行。本例中, 編譯器選擇使用變量的舊值相乘以后再對二者進行自增運算。

    包含多個不確定的副作用的代碼的行為總是被認為未定義。(簡單而言, ``多個不確定副作用" 是指在同一個表達式中使用導致同一對象修改兩次或修改以后又被引用的自增, 自減和賦值操作符的任何組合。這是一個粗略的定義; 嚴格的定義參見問題 3.7, ``未定義" 的含義參見問題 11.32。) 甚至都不要試圖探究這些東西在你的編譯器中是如何實現(xiàn)的 (這與許多 C 教科書上的弱智練習正好相反); 正如  K&R 明智地指出, ``如果你不知道它們在不同的機器上如何實現(xiàn), 這樣的無知可能恰恰會有助于保護你。

4.7 我怎樣才能理解復雜表達式?``序列點" 是什么?

    序列點是一個時間點(在整個表達式全部計算完畢之后或在 ||、  &&、 ? : 或逗號 運算符處, 或在函數(shù)調(diào)用之前), 此刻塵埃落定, 所有的副作用都已確保結(jié)束。 ANSI/ISO C 標準這樣描述:

在上一個和下一個序列點之間, 一個對象所保存的值至多只能被表達式的計算修改一次。而且前一個值只能用于決定將要保存的值。

第二句話比較費解。它說在一個表達式中如果某個對象需要寫入, 則在同一表達式中對該對象的訪問應該只局限于直接用于計算將要寫入的值。這條規(guī)則有效地限制了只有能確保在修改之前才訪問變量的表達式為合法。例如 i = i+1 合法, 而 a[i] = i++ 則非法 (參見問題 3.1)。

參見下邊的問題 3.8。

相關文章

  • Qt數(shù)據(jù)庫應用之實現(xiàn)文件編碼格式識別

    Qt數(shù)據(jù)庫應用之實現(xiàn)文件編碼格式識別

    在做數(shù)據(jù)導入導出的過程中,如果應用場景多了,相信各位都會遇到一個問題就是文件編碼的問題。本文將用Qt實現(xiàn)文件編碼格式識別,感興趣的可以了解一下
    2022-06-06
  • 使用Qt封裝一個發(fā)送http請求通用類

    使用Qt封裝一個發(fā)送http請求通用類

    這篇文章主要為大家詳細介紹了如何使用Qt封裝一個通用類,可以通過QNetworkRequest和QNetworkReply進行http請求,感興趣的可以了解一下
    2024-12-12
  • C++實現(xiàn)猜數(shù)字小游戲

    C++實現(xiàn)猜數(shù)字小游戲

    這篇文章主要為大家詳細介紹了C++實現(xiàn)猜數(shù)字小游戲,文中示例代碼介紹的非常詳細,具有一定的參考價值,感興趣的小伙伴們可以參考一下
    2020-10-10
  • 人臉檢測中AdaBoost算法詳解

    人臉檢測中AdaBoost算法詳解

    這篇文章主要為大家詳細介紹了人臉檢測中AdaBoost算法的相關資料,具有一定的參考價值,感興趣的小伙伴們可以參考一下
    2018-01-01
  • C++11?std::transform函數(shù)使用小結(jié)

    C++11?std::transform函數(shù)使用小結(jié)

    std::transform是C++標準庫中的一個算法,它用于對輸入范圍內(nèi)的元素進行操作,并將結(jié)果存儲在輸出范圍內(nèi),本文就介紹了std::transform函數(shù)的具體使用,感興趣的可以了解一下
    2023-09-09
  • C++中vector與remove()函數(shù)詳解

    C++中vector與remove()函數(shù)詳解

    這篇文章主要介紹了C++中vector與remove()函數(shù),本文實例代碼給大家介紹的非常詳細,對大家的學習或工作具有一定的參考借鑒價值,需要的朋友可以參考下
    2023-06-06
  • VC++文件監(jiān)控之ReadDirectoryChangesW

    VC++文件監(jiān)控之ReadDirectoryChangesW

    文章主要介紹文件監(jiān)控的另一種實現(xiàn)方式,利用ReadDirectoryChangesW來實現(xiàn)文件的監(jiān)控,希望對大家有幫助
    2019-04-04
  • C++深入淺出探索數(shù)據(jù)結(jié)構的原理

    C++深入淺出探索數(shù)據(jù)結(jié)構的原理

    C++的數(shù)據(jù)結(jié)構很多,很復雜,所以本文將通過示例帶大家深入了解一下C++中的數(shù)據(jù)結(jié)構與算法。文中的示例代碼講解詳細,感興趣的可以了解一下
    2022-05-05
  • C語言實現(xiàn)動態(tài)順序表詳解

    C語言實現(xiàn)動態(tài)順序表詳解

    這篇文章主要介紹了C語言實現(xiàn)動態(tài)順序表的實現(xiàn)代碼的相關資料,動態(tài)順序表在內(nèi)存中開辟一塊空間,可以隨我們數(shù)據(jù)數(shù)量的增多來擴容,需要的朋友可以參考下
    2021-08-08
  • QT修改項目名稱的圖文示例

    QT修改項目名稱的圖文示例

    本文主要介紹了QT修改項目名稱的圖文示例,文中通過圖文介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友們下面隨著小編來一起學習學習吧
    2024-01-01

最新評論

曲麻莱县| 南昌县| 科技| 石景山区| 南宫市| 海阳市| 黎平县| 亳州市| 许昌县| 濮阳市| 会理县| 忻城县| 舞钢市| 西昌市| 黄梅县| 如皋市| 台南县| 延安市| 洛扎县| 南丹县| 泰州市| 历史| 崇左市| 太仆寺旗| 肃北| 弋阳县| 西丰县| 萨嘎县| 启东市| 色达县| 石家庄市| 安陆市| 墨竹工卡县| 商都县| 广水市| 哈巴河县| 政和县| 惠水县| 丘北县| 博野县| 丰镇市|