• <ins id="pjuwb"></ins>
    <blockquote id="pjuwb"><pre id="pjuwb"></pre></blockquote>
    <noscript id="pjuwb"></noscript>
          <sup id="pjuwb"><pre id="pjuwb"></pre></sup>
            <dd id="pjuwb"></dd>
            <abbr id="pjuwb"></abbr>

            兔子的技術博客

            兔子

               :: 首頁 :: 聯系 :: 聚合  :: 管理
              202 Posts :: 0 Stories :: 43 Comments :: 0 Trackbacks

            留言簿(10)

            最新評論

            閱讀排行榜

            評論排行榜

            C++操作符的優先級

            操作符及其結合性

            功能

            用法

            L
            L
            L
            ::
            ::
            ::
            全局作用域
            類作用域
            名字空間作用域
            ::name
            class::name
            namespace::name
            L
            L
            L
            L
            L
            .
            ->
            []
            ()
            ()
            成員選擇
            成員選擇
            下標
            函數調用
            類型構造
            object.member
            pointer->member
            variable[expr]
            name(expr_list)
            type(expr_list)
            R
            R
            R
            R
            R
            ++
            --
            typeid
            typeid
            顯示強制類型轉換
            后自增操作
            后自減操作
            類型ID
            運行時類型ID
            類型轉換
            lvalue++
            lvalue--
            typeid(type)
            typeid(expr)
            cast_name<type>(expr)
            R
            R
            R
            R
            R
            R
            R
            R
            R
            R
            R
            R
            R
            R
            sizeof
            sizeof
            ++
            --
            ~
            !
            -
            +
            *
            &
            ()
            new
            delete
            delete[]
            對象的大小
            類型的大小
            前自增操作
            前自減操作
            位求反
            邏輯非
            一元負號
            一元正號
            解引用
            取地址
            類型轉換
            創建對象
            釋放對象
            釋放數組
            sizeof expr
            sizeof(type)
            ++lvalue
            --lvalue
            ~expr
            !expr
            -expr
            +expr
            *expr
            &expr
            (type)expr
            new type
            delete expr
            delete []expr
            L
            L
            ->*
            .*
            指向成員操作的指針
            指向成員操作的指針
            ptr->*ptr_to_member
            obj.*ptr_to_member
            L
            L
            L
            *
            /
            %
            乘法
            除法
            求模(求余)
            expr * expr
            expr / expr
            expr % expr
            L
            L
            +
            -
            加法
            減法
            expr + expr
            expr - expr
            L
            L
            <<
            >>
            位左移
            位右移
            expr << expr
            expr >> expr
            L
            L
            L
            L
            <
            <=
            >
            >=
            小于
            小于或等于
            大于
            大于或等于
            expr < expr
            expr <= expr
            expr > expr
            expr >= expr
            L
            R
            ==
            !=
            相等
            不等
            Expr == expr
            Expr != expr
            R & 位與 Expr & expr
            R ^ 位異或 Expr ^ expr
            R | 位或 Expr | expr
            R && 邏輯與 Expr && expr
            R || 邏輯或 Expr || expr
            R ?: 條件操作 Expr ? expr : expr
            R
            R
            R
            R
            R
            =
            *=,/=,%=
            +=,-=
            <<=,>>=
            &=,|=,^=
            賦值操作
            符合賦值操作

            Lvalue= expr
            Lvalue+= expr
            ……

            R throw 拋出異常 Throw expr
            L , 逗號 Expr, expr
            記憶方法:
            --摘自《C語言程序設計實用問答》 -呂鳳翥 呂 濤著
            問題:如何記住運算符的15種優先級和結合性?
            解答:C語言中運算符種類比較繁多,優先級有15種,結合性有兩種。
            如何記憶兩種結合性和15種優先級?下面講述一種記憶方法。
            結合性有兩種,一種是自左至右,另一種是自右至左,大部分運算符的結合性是自左至右,只有單目運算符、三目運算符的賦值運算符的結合性自右至左。
            優先級有15種。記憶方法如下:
            記住一個最高的:構造類型的元素或成員以及小括號。
            記住一個最低的:逗號運算符。
            剩余的是一、二、三、賦值。
            意思是單目、雙目、三目和賦值運算符。
            在諸多運算符中,又分為:
            算術、關系、邏輯。
            兩種位操作運算符中,移位運算符在算術運算符后邊,邏輯位運算符在邏輯運算符的前面。再細分如下:
            算術運算符分 *,/,%高于+,-。
            關系運算符中,》,》=,《,〈=高于==,!=。
            邏輯運算符中,除了邏輯求反(!)是單目外,邏輯與(&&)高于邏輯或(||)。
            邏輯位運算符中,除了邏輯按位求反(~)外,按位與(&)高于按位半加(^),高于按位或(|)。
            這樣就將15種優先級都記住了,再將記憶方法總結如下:
            去掉一個最高的,去掉一個最低的,剩下的是一、二、三、賦值。雙目運算符中,順序為算術、關系和邏輯,移位和邏輯位插入其中。

            為什么后綴++比*操作符優先級高卻后對p加1?” ——*p++、*++p、++*p和(*p)++中的操作符優先級問題
            假設
            int a[10]
            p1=a;

            那么
            *p++=1;
            *++p=2;
            ++*p=3;
            (*p)++=4;

            分別應該怎么按照優先級別運算?
            按照書上的說法++ (后置) >++(前置) >* 解引用用 > = 等于
            *p++ 是否應該是 現算(p++) 在算* 最后 賦值?
            求所有的正確的算法 和解答
            ---------------------------------------------------------------

            ++(后綴)屬于“后綴操作符”,其優先級高于“前綴操作符”。
            * 和++(前綴)都屬于“前綴操作符”,優先級相同,按從左到右結合的順序。都高于賦值運算符。

            所以:
            *p++=1 相當于 (*(p++)) = 1,也就是說++操作于p上,結果為p原來的值,再作*運算,去除引用,再賦為1。總的作用就是把p引用的對象賦值為1,并把p加1。

            *++p=2 相當于(*(++p)) = 2,也就是說++操作于p上,結果為p加1后的值,再作*運算,去除引用,再賦值為1。總的作用就是把p加1,然后對其引用的對象賦值為2。

            ++*p=3 相當于(++(*p)) = 3,也就是說先對p作*運算去除引用,其結果為p引用的對象,再把這個對象+1,結果還是這個對象,再把它賦值為3。這個表達式要求對象的前綴++操作符的返回值為左值。

            (*p)++=4 這里有一個強制優等級(括號),它的級別最高,結果就是((*p)++) = 4,也就是先對p作*運算去除引用,其結果為它引用的對象,然后對這個對象作后綴++操作符,結果為這個對象操作前的值(一般是一個臨時變量),然后把它賦值為4,這個表達式要求對象的后綴++操作符的返回值為左值(整數類型是不符合要求的,只對定義了這個操作符的對象類型才有可能符合要求)。

            這個問題以C中很難試驗出來,在C++中可以用操作符重載的方法看清楚(操作符重載不會改變優先級):

            #include <iostream>

            class test
            {
            public:
            test(){}
            test(int){}
            test& operator = (const test&){std::cout<<"Assignment of test" << std::endl; return *this;}
            test& operator ++ (){std::cout << "Prefix ++ of test" << std:: endl; return * this;}
            test& operator ++ (int) {std::cout << "Suffix ++ of test" << std::endl; return *this;}
            };
            class testptr
            {
            test Value;
            public:
            testptr& operator = (const test&){std::cout<<"Assignment of testptr" << std::endl; return *this;}
            testptr& operator ++ (){std::cout << "Prefix ++ of testptr" << std:: endl; return * this;}
            testptr& operator ++ (int) {std::cout << "Suffix ++ of testptr" << std::endl; return *this;}
            test& operator *(){std::cout<< "Operator * of testptr"<<std::endl; return Value;}
            };

            #define TRACK(X) std::cout <<std::endl<<"***** "<< #X << " *****" <<std::endl; X
            int main()
            {
            testptr p;
            TRACK(*p++=1);
            TRACK(*++p=2);
            TRACK(++*p=3);
            TRACK((*p)++=4);
            std::cin.get();
            }

            輸出為
            ***** *p++=1 *****
            Suffix ++ of testptr
            Operator * of testptr
            Assignment of test

            ***** *++p=2 *****
            Prefix ++ of testptr
            Operator * of testptr
            Assignment of test

            ***** ++*p=3 *****
            Operator * of testptr
            Prefix ++ of test
            Assignment of test

            ***** (*p)++=4 *****
            Operator * of testptr
            Suffix ++ of test
            Assignment of test


            int p = 1;
            int a = p++;
            結果a=1,并不是因為后綴++優先級低(我記得有一本C教材就是這樣寫的,真是誤人子弟),而是由后綴++的語義決定的。標準的后綴++應該是 “對操作對象做+1操作,并返回操作前的值”,它在賦值運算前運算了,但它的返回值并不是p,而是p在做+1運算前的值。因此我們還可以知道,p++的返回值應該不是一個左值,p++=a是無法編譯通過的。而前綴++則不一樣,++p的含義就是“對p做+1運算,并返回p”,其返回值就是p本身(引用),是一個左值,++p = a是可以編譯的(但沒什么意義)。

            如果用代碼描述一下這兩個操作符,應該是這樣的:

            const int int::operator ++(int)//后綴++
            {
            int temp = *this;
            *this = *this +1;
            return temp;
            }

            int& int::operator ++()//前綴++
            {
            *this = *this + 1;
            return *this;
            }


            補充:
            在C中,上述語句含義分別是:
            *p++=1; --> temp = p + 1; *temp = 1;
            *++p=2; --> p = p +1; * p = 1;
            ++*p=3; --> *p = *p + 1; *p = 3;
            (*p)++=4;//語法錯誤,無法寫出對應的語句。

            由于后綴增/減量操作符的特殊性,導致初學者很難理解“為什么后綴的++優先級高卻后對變量加1呢?”事實上,事實上,“后綴++”并不是后對變量加1,而是先做了,只是它的返回值并不是這個變量,而是這個變量改變前的值。如果對它很難理解,建議不要使用這幾個操作符,而改用普通的加/減法操作符:
            *p++=1; --> *p = 1; p = p + 1;
            *++p=2; --> p = p + 1; *p = 2;
            ++*p=3; --> *p = *p + 1; *p = 3;
            (*p)++=4;//語法錯誤,無法寫出對應的語句。

            由于在C++中這幾個操作符不再是整數和指針類型特有的,而是可以為類定義的,并且它們可以和+/-1操作語義不同或根本沒有加/減法操作符(如雙向迭代器),不能簡單地用加/減法代替。不過C++程序員們可以通過看比較好的類的操作符重載函數(如迭代器的)代碼真正明白后綴增/減量操作符的語義,不會因為它“優先級高卻后對變量加1”的問題糊涂。不過,僅管如此,我還是認為使用增/減量操作符時最好讓一個表達式中或者沒有增/減量操作符,或者只有一個增/減量操作符,如:++p;*p = 1;(相當于*++p = 1)或*p = 1;++p;(相當于*p++=1),這樣也不用去區分前綴和后綴的區別了。



            轉自:http://blog.163.com/wjh2-316/blog/static/2787275320086810153137/
            posted on 2011-04-19 13:46 會飛的兔子 閱讀(639) 評論(0)  編輯 收藏 引用 所屬分類: C++及開發環境
            久久久久亚洲AV无码专区网站| 久久综合狠狠综合久久综合88| 精品欧美一区二区三区久久久| 91精品日韩人妻无码久久不卡| 狠狠色综合网站久久久久久久| 久久综合九色综合网站| …久久精品99久久香蕉国产| 精品国产一区二区三区久久蜜臀 | 精品熟女少妇av免费久久| 久久人人爽人人爽人人av东京热 | 国色天香久久久久久久小说| 久久99亚洲网美利坚合众国| 久久天天躁狠狠躁夜夜2020老熟妇| 色偷偷88888欧美精品久久久| 久久久久亚洲AV成人网人人网站| 婷婷伊人久久大香线蕉AV| 久久久久无码专区亚洲av| 久久精品无码专区免费青青| 香蕉久久久久久狠狠色| 久久久无码精品午夜| 波多野结衣中文字幕久久| 无码国内精品久久人妻| 亚洲精品97久久中文字幕无码| 久久九九亚洲精品| 国产精品天天影视久久综合网| 中文精品99久久国产| 久久综合久久鬼色| 久久久久综合中文字幕| 久久青青草原国产精品免费 | 亚洲精品无码久久千人斩| 性欧美大战久久久久久久| 九九久久精品无码专区| 一本久久久久久久| 国产高清国内精品福利99久久| 国产精品久久一区二区三区 | 欧美粉嫩小泬久久久久久久| 国产成人综合久久久久久| 久久99国产一区二区三区| 久久乐国产精品亚洲综合| 亚洲国产成人久久综合野外| 日韩精品久久久久久久电影|