日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

C语言学习及应用笔记之一:C运算符优先级及使用问题

發布時間:2024/7/23 编程问答 32 豆豆
生活随笔 收集整理的這篇文章主要介紹了 C语言学习及应用笔记之一:C运算符优先级及使用问题 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

C語言中的運算符絕對是C語言學習和使用的一個難點,因為在2011版的標準中,C語言的運算符的數量超過40個,甚至比關鍵字的數量還要多。這些運算符有單目運算符、雙目運算符以及三目運算符,又涉及到左結合和右結合的問題,真是令人眼花繚亂。

1、運算符及優先級

運算符多可能使用更靈活方便,但這還涉及到運算符之間的優先級問題。我們做四則運算式時,有先乘除后加減的規定,在C語言的這些運算符中自然也是有的,但40多個運算符排起優先級來,使用就不那么容易了。

接下來我們簡單的總結一下C語言中運算符以及他們的優先級。C語言中各運算符的優先級如下表所示:

優先級

運算符

名稱或含義

使用形式

結合方向

說明

1

[]

數組下標

數組名[常量表達式]

左到右

?

()

圓括號

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

?

.

成員選擇(對象)

對象.成員名

?

->

成員選擇(指針)

對象指針->成員名

?

++

后置自增運算符

++變量名

單目運算符

--

后置自減運算符

--變量名

單目運算符

2

-

負號運算符

-表達式

右到左

單目運算符

(類型)

強制類型轉換

(數據類型)表達式

?

++

前置自增運算符

變量名++

單目運算符

--

前置自減運算符

變量名--

單目運算符

*

取值運算符

*指針變量

單目運算符

&

取地址運算符

&變量名

單目運算符

!

邏輯非運算符

!表達式

單目運算符

~

按位取反運算符

~表達式

單目運算符

sizeof

長度運算符

sizeof(表達式)

?

3

/

表達式/表達式

左到右

雙目運算符

*

表達式*表達式

雙目運算符

%

余數(取模)

整型表達式/整型表達式

雙目運算符

4

+

表達式+表達式

左到右

雙目運算符

-

表達式-表達式

雙目運算符

5

<<

左移

變量<<表達式

左到右

雙目運算符

>>

右移

變量>>表達式

雙目運算符

6

>

大于

表達式>表達式

左到右

雙目運算符

>=

大于等于

表達式>=表達式

雙目運算符

<

小于

表達式<表達式

雙目運算符

<=

小于等于

表達式<=表達式

雙目運算符

7

==

等于

表達式==表達式

左到右

雙目運算符

!=

不等于

表達式!= 表達式

雙目運算符

8

&

按位與

表達式&表達式

左到右

雙目運算符

9

^

按位異或

表達式^表達式

左到右

雙目運算符

10

|

按位或

表達式|表達式

左到右

雙目運算符

11

&&

邏輯與

表達式&&表達式

左到右

雙目運算符

12

||

邏輯或

表達式||表達式

左到右

雙目運算符

13

?:

條件運算符

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

右到左

三目運算符

14

=

賦值運算符

變量=表達式

右到左

?

/=

除后賦值

變量/=表達式

?

*=

乘后賦值

變量*=表達式

?

%=

取模后賦值

變量%=表達式

?

+=

加后賦值

變量+=表達式

?

-=

減后賦值

變量-=表達式

?

<<=

左移后賦值

變量<<=表達式

?

>>=

右移后賦值

變量>>=表達式

?

&=

按位與后賦值

變量&=表達式

?

^=

按位異或后賦值

變量^=表達式

?

|=

按位或后賦值

變量|=表達式

?

15

,

逗號運算符

表達式,表達式,…

左到右

從左向右順序運算

在上表中,我們歸納了運算符、個運算符的功能、通常的應用表達式形式以及結合性。說到結合性主要應用于相同優先級的運算符,運算次序由結合方向所決定。絕大部分的運算符都是左結合的,與我們的常識一致。不過有一部分運算符是右結合的,這些就需要記憶了,但記憶有時候卻不見得百分百準確,所以我們可以在編寫代碼時以( )加以規范。

2、優先級的一些特別說明

我們見面歸納了運算符的用法,但這只是一般性情況,實際的使用情況有時候依然讓人迷惑。比方說,在上表中,如果優先級同為1 的幾種運算符同時出現時,想要確定表達式的優先級就不是那么明顯了。例如我們常常對指向多維數組的指針和指針數組,還有指向函數的指針數組等含混不清,對初學者來說就更是迷惑不解。所以在這樣的定義表達式中,如果優先級不明確結果有可能相去甚遠。在這里,接下來我們整理了一些常常容易出錯的情況說明如下:

優先級問題

表達式

想要的結果

實際結果

.的優先級高于*

*p.f

指針p所指向的對象的某一字段f,即:(*p).f

對p取f偏移作為指針,然后進行解除飲用操作,即:*(p.f)

[]的優先級高于*

int *p[]

P是指向int數組的指針,即:int (*p)[]

P是元素為指向int的指針的數組,即:int *(p[])

函數()優先級高于*

int *p()

p是個函數指針所指函數返回值是int,即:int (*p)()

P是個函數,返回值是int *,即:int *(p())

==和!=優先級高于位操作

(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

那么是不是有了上面的總結就完事大吉了呢?當然不可能,且不說我們的總結很不完備,就算你記住了所有的規則,在使用過程中仍然有可能漏洞百出,最好的辦法是養成良好的編碼習慣。

3、由優先級引發的錯誤

優先級問題經常會造成一些意想不到的結果,有的甚至是非常嚴重的。本人在編寫程序時,就出現過一些因為疏忽運算符優先級造成的問題,而且檢查起來非常不容易發現。

例如,有一次,我們采集了傳感器的原始數據,然后會對數據進行一些處理,在其中的一種條件下會對一個數進行左移幾位并加上一個數。由于算術運算符的優先級大于移位運算符,而程序員忘記了給移位操作加括號,所以得出了結果總是有誤,只好從頭開始查找,花了不少時間才發現這出錯誤。如msb<<4+lsb和(msb<<4)+lsb是完全不一樣,因為算術運算符的優先級大于移位運算符。

還有一次,我們定義一個指向函數的指針數組用于回調函數的操作。定義時,沒有考慮到指針運算符、函數運算符以及數組運算符的優先級問題而造成調用出錯。如,void (*p[])f()的形式,如果寫成void *p[]f()的形式就完全錯誤了。

當然,如果能夠熟記各種運算符的優先級也許能解決上面的問題,但這實際上卻很難達到,因為應用是非常靈活的,你不可能時時刻刻只關注于此。我覺得養成良好的編碼習慣以及多多練習似乎更有效。

歡迎關注:

總結

以上是生活随笔為你收集整理的C语言学习及应用笔记之一:C运算符优先级及使用问题的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。