C/C++運算符優先級和結合性

2021-12-29 靈均之舍

運算過程存在優先級和結合性兩個問題。在數學的四則運算中規定,先算括號,再算乘除,最後算加減,不同運算符具有不同的計算順序,這就是運算優先級問題;同時,還規定同級運算從左往右依次計算,這是計算的結合性問題。在C/C++中,運算符也需要注意優先級和結合性,而且C/C++中的運算符很多,遠比數學四則運算複雜,它們的優先級和結合性如下表所示:

優先級

運算符

名稱或含義

使用形式

結合方向

說明

1

[]

數組下標

數組名[常量表達式]

左到右


()

圓括號

(表達式)
 函數名(形參表)


.

成員選擇(對象)

對象.成員名


->

成員選擇(指針)

對象指針->成員名


2

-

負號運算符

-表達式

右到左

單目運算符

(類型)

強制類型轉換

(數據類型)表達式


++

自增運算符

++變量名   變量名++

單目運算符

--

自減運算符

--變量名    變量名--

單目運算符

*

取值運算符

*指針變量

單目運算符

&

取地址運算符

&變量名

單目運算符

!

邏輯非運算符

!表達式

單目運算符

~

按位取反運算符

~表達式

單目運算符

sizeof

長度運算符

sizeof(表達式)


3

/

表達式 / 表達式

左到右

雙目運算符

*

表達式*表達式

雙目運算符

%

餘數(取模)

整型表達式%整型表達式

雙目運算符

4

+

表達式+表達式

左到右

雙目運算符

-

表達式-表達式

雙目運算符

5

<< 

左移

變量<<表達式

左到右

雙目運算符

>> 

右移

變量>>表達式

雙目運算符

6

大於

表達式>表達式

左到右

雙目運算符

>=

大於等於

表達式>=表達式

雙目運算符

小於

表達式<表達式

雙目運算符

<=

小於等於

表達式<=表達式

雙目運算符

7

==

等於

表達式==表達式

左到右

雙目運算符

!=

不等於

表達式!= 表達式

雙目運算符

8

&

按位與

表達式&表達式

左到右

雙目運算符

9

^

按位異或

表達式^表達式

左到右

雙目運算符

10

|

按位或

表達式|表達式

左到右

雙目運算符

11

&&

邏輯與

表達式&&表達式

左到右

雙目運算符

12

||

邏輯或

表達式||表達式

左到右

雙目運算符

13

?:

條件運算符

表達式1? 表達式2: 表達式3

右到左

三目運算符

14

=

賦值運算符

變量=表達式

右到左


/=

除後賦值

變量/=表達式


*=

乘後賦值

變量*=表達式


%=

取模後賦值

變量%=表達式


+=

加後賦值

變量+=表達式


-=

減後賦值

變量-=表達式


<<=

左移後賦值

變量<<=表達式


>>=

右移後賦值

變量>>=表達式


&=

按位與後賦值

變量&=表達式


^=

按位異或後賦值

變量^=表達式


|=

按位或後賦值

變量|=表達式


15

,

逗號運算符

表達式,表達式,…

左到右


總結上表規律:

(1)結合性

所有雙目運算符中只有賦值運算符的結合方向是從右往左。另外兩個從右往左結合的運算符也很好記,因為它們很特殊:一個是單目運算符,一個是三目運算符。其餘都是從左往右的結合性。

(2)優先級

基本優先級:算術運算符 > 關係運算符 > 邏輯運算符 > 賦值運算符。比較特殊的是邏輯非(!)作為單目運算符,優先級高於所有的雙目和三目運算符。複合運算符的級別比其他運算符都低,僅僅高於逗號運算符。

優先級的細節問題:乘除模運算高於加減。二進位移位運算 >   關係運算符 > 位運算符。如果添加了括號,那麼括號的優先級最高。

(3)目運算

一個運算符需要n個操作數就稱為n目運算符。例如,++、--只需要一個操作數,就是單目運算符;+、-、*、/的兩邊都有操作數,稱為雙目運算符;?:是三目運算符,也是C語言中唯一的三目運算符。

當一個表達式中出現多個運算符時,C/C++會先比較各個運算符的優先級,按照優先級從高到低的順序依次執行;當遇到優先級相同的運算符時,再根據結合性決定先執行哪個運算符:如果是左結合性就先執行左邊的運算符,如果是右結合性就先執行右邊的運算符。

分析一:表達式a+b*c。

根據優先級,*大於+,那麼應該先計算乘法,再計算加法。所以C/C++和數學中的規則一樣。

分析二:表達式a/b*c。

*和/的優先級相同,那麼看結合性,*和/都是從左向右結合,因此先算除法,再算乘法。所以C語言和數學中的規則一樣。類似於這種從左向右結合方式,稱為左結合性;那麼先執行右邊的稱為右結合性。

分析三:表達式d=a+b--

由於--運算優先級高於+,--是右到左的結合性。右邊沒有變量,這時直接執行a+b,把值賦給d。然後--才開始執行b-1的操作。

分析四:表達式d=a+--b

由於--運算優先級高於+,--是右到左的結合性,於是執行--b得到b-1;然後執行才進行加法運算,所以d的值是a+b-1。

在指針和函數中關於*、&、()的優先級要特別注意:

優先級問題

表達式

經常誤認為的結果

實際結果

.的優先級高於*(->操作符用於消除這個問題)

*p.f

p所指對象的欄位f,等價於:
 (*p).f

對p取f偏移,作為指針,然後進行解除引用操作,等價於:
 *(p.f)

[]高於*

int*ap[]

ap是個指向int數組的指針,等價於:
 int(*ap)[]

ap是個元素為int指針的數組,等價於:
 int*(ap[])

函數()高於*

int*fp()

fp是個函數指針,所指函數返回int,等價於:
 int(*fp)()

fp是個函數,返回int*,等價於:
 int*(fp())

此外,位運算、關係運算與算術運算符之間,也是分析優先級容易錯誤的地方:

優先級問題

表達式

經常誤認為的結果

實際結果

==和!=高於位操作

(val&mask!=0)

(val&mask)!=0

val&(mask!=0)

==和!=高於賦值符

c=getchar()!=EOF

(c=getchar())!=EOF

c=(getchar()!=EOF)

算術運算符高於位移運算符

msb<<4+lsb

(msb<<4)+lsb

msb<<(4+lsb)

逗號運算符在所有運算符中優先級最低

i=1,2

i=(1,2)

(i=1),2

最後,逗號運算符在所有運算符中優先級最低:

等價於

溫馨提示:為了防止出現優先級錯誤,在實際編程中,記得優先計算的運算添加括號。

相關焦點

  • c語言運算符號
    C語言運算符號指的是運算符號。C語言中的符號分為10類:算術運算符、關係運算符、邏輯運算符、位操作運算符、賦值運算符、條件運算符、逗號運算符、指針運算符、求字節數運算符和特殊運算符。注意事項運算符號的優先級總個數34 種相關概念優先級、結合性種類算術運算符用於各類數值運算。
  • c語言的選擇結構(一)
    例如:(一)工程師崗位面試(關係運算符和邏輯運算符)題目要求:上海一家IT企業招聘c/c++開發工程師,滿足以下任職要求者可以獲得面試機會。(1)學歷:計算機相關專業畢業,碩士及以上學歷;(2)工作年限:兩年以上c/c++開發工程師崗位從業經驗;(3)業務要求:熟練或精通c/c++和數據壓縮算法。
  • MATLAB運算符優先級一覽表
    MATLAB 在執行含有關係運算和邏輯運算的數學運算時,同樣遵循一套優先級原則。
  • C語言之·操作符
    > 316 + (c = 3 + 8 )17最後一個表達式看上去雖然很奇怪,但是在C中完全合法,因為它是兩個子表達式的和,每個子表達式都有一個值🍓2.一些複雜表達式的值表達式求值的順序一部分是由操作符的優先級和結合性決定。
  • python運算符優先級,加減乘除只是基礎,學習python第2天
    在計算機編程中少不了運算,而python運算符有哪些呢?python運算符優先級順序又是怎麼樣的?就像數學一樣,加減乘除只是基礎,了解python運算符才能解決實際性的問題。而python運算符有哪些以及它們的優先級又是怎麼樣的呢?下面用一張表格來說明,下表將按照python運算符的優先級順序從高到底進行排序。(在實際項目中,如果搞不清楚運算符優先級,可以通過括號保證括號內的運算優先進行。)
  • c++運算符重載
    算符重載,就是對已有的運算符重新進行定義,賦予其另一種功能,以適應不同的數據類型。<返回類型說明符>  operator  <運算符符號>  (<參數表>) {      <函數體>  }重載運算符的方式有哪幾種?
  • Excel運算符優先級全面解析,值得收藏(三)
    Excel公式的計算順序與運算符優先級有關,如果一個公式中的多個運算符具有相同的優先順序,那麼應該按照等號開始從左向右的順序進行計算,如果公式中的多個運算符屬於不同的的優先順序,則按照運算符的優先級進行運算。
  • c語言基礎語法五:運算符與表達式
    amp;逗號運算符sizeof運算符運算符的優先性與結合性二:表達式一:運算符intnNum = 10;nNum=10, 20, 30;運算完畢之後,nNum等於10,因為=運算符的優先級更高。nNum= (10, 20, 30);運算完畢之後,nNum等於30,因為先算括號裡面的,逗號表達式的值是最後一個數的值,所以(10, 20, 30)的結果是30,然後再賦值。
  • C語言中的運算符
    ,他們也是運算符,並且優先級與括號相當,這也是我們把兩者放在一起討論的原因。至於如何使用則是結構體的內容。單目運算符:單目運算符有很多,例如:!邏輯非、~按位取反、++自增、--自減、+正、-負、&求地址運算符、*間址運算符、sizeof()求所佔字節數、(類型名)強制類型轉換。這些運算符的運算對象只有一個。
  • 從零開始的C語言學習生活|W4 邏輯類型和運算
    c>=』A』&&c<=理解一下lage>20&&age<30lindex<0||index>99l!age<20              先進行!age,後進行<的判斷,所以一直是1,那麼它怎麼樣才能做到運算結果是,判斷age不是小於20的值的真假呢?
  • 跟我學java編程—Java運算符的優先級
    Java表達式可能存在多個運算符,運算符之間存在優先級的關係,級別高的運算符先執行運算,級別低的運算符後執行運算算,下表列出了運算符的優先級。表中優先級欄,數字越小優先級越高,運算符每個運算符用中文頓號分割。
  • 單片機c語言教程第七章--運算符和表達式(關係運算符)
    單片機c語言教程第七章--運算符和表達式(關係運算符) 佚名 發表於 2009-04-15 09:37:37 關係運算符,同樣我們也並不陌生。
  • Java 算術運算及其優先級講解,可以說很詳細了
    ++ 和 -- :表示所操作的變量自增1和自減1,都只能操作變量,不能操作常量;自增:++,自增操作符,變量值自增1,有前置和後置之分,只能操作變量。自減: -- ,自減操作符,變量值自減1,有前置和後置之分,只能操作變量。
  • c程序的運算符和表達式(一)
    一、計算a/b和a%b的值「/」是運算符中的除,在使用該運算符時除了分母不能為0外,還要特別注意在c語言中如果兩個操作數a、b的值都是整型,結果也是整型;「%」是取餘運算,要求兩個操作數必須是整型。例如9%2的值為1,而9.5%2是非法的。
  • C++之操作重載符學習總結(二)
    一、完善的複數類:在上一篇文章裡面我們已經提到了操作符重載的概念和使用,同時也舉例了一個數學裡面的複數操作,從一開始使用友元到使用操作符重載全局函數,再到使用操作符重載類成員函數,這樣一步步演變而成我們最終實現了複數的實部加實部,虛部加虛部;而且當時我們只講解了一個操作重載符「+」,所以為了完善學習體系
  • c++的輸入與輸出
    c++輸入與輸出C++ 標準庫提供了一組豐富的輸入/輸出功能,本章將討論 C++ 編程中最基本和最常見的 I/O 操作。輸入輸出並不是c++語言的正式組成成分,c和c++沒有為輸入輸出提供專門的結構。在c語言中輸入輸出是通過調用scanf和printf 實現的,在c++中是通過調用流對象cin和cout實現的。
  • 用實例代碼帶你回顧C語言基礎運算符和表達式知識點匯總
    我們已經把基礎的運算符和表達式,今天我們主要就是根據幾個錯誤的程序來鞏固相關的知識。自加和自減都有兩種書寫格式:++a、a++、--a、a—那麼他們不僅僅是書寫格式的不一樣,它們所得出的數值也不一樣,符號在前的會先去進行運算後出數值,符號在後則是先輸出數值在進行運算,所以我們要想i輸出為5的話,我們應當把符號加為後綴,輸出語句應當為:
  • 什麼是運算符和表達式,在python中是如何處理數學運算的?
    它與表達式和運算符,又有什麼關聯的呢?一:什麼是表達式和運算符?表達式(expression)由一個數字和運算符組成。其作用是讓計算機做一些事情(如數學運算)並返回結果:如1+2=3;運算符包括算術運算符和邏輯運算符。
  • C語言——選擇結構設計(switch語句和關係運算符及關係表達式)
    廢話不多說了,我們先來看例題;#include<stdio.h>int main(){char grade;scanf("%c",&grade);關係運算符和關係表達式在循環語句中,少不了判斷,大家都知道判斷的符號有大於,小於等等。那在C語言的編程系統中,也有相對應的判斷符,並且這些運算符還有優先級。接下來我先為大家介紹幾種常見的運算符。其中,5和6的運算優先級低於其他的運算優先級。
  • 運算符重載(多態):最通俗易懂的「重載」解釋(附代碼)
    運算符重載什麼是重載?——以C++為例以運算符「+」為例,通常情況下,我們使用加號的方式如下:int a=2, b=3, c=4;a=b+c;功能就是將int類型的兩個變量b,c算術相加,返回int類型的值並賦值給變量a。「+」運算符重載就是將運算符擴展到能夠把用戶自定義的兩種類型相加,一般情況下都是重載「+」把兩個對象相加。