運算符 | 進行的運算 | 所屬類別 | 備注 |
[ ] | 間隔符 | 標點符號 | |
( ) | 間隔符 | 標點符號 | |
· | 直接分量選擇 | 雙目操作符 | |
-> | 間接分量選擇 | 雙目操作符 | |
++ | 前增量、后增量 | 單目操作符 | |
-- | 前減量、后減量 | 單目操作符 | |
+ | 加 | 雙目操作符、單目操作符 | |
- | 減 | 雙目操作符、單目操作符 | |
* | 1)乘 2)間接引用 | 雙目操作符、單目操作符 | |
/ | 除 | 雙目操作符 | |
% | 求余 | 雙目操作符 | |
& | 1)位‘與’2)取地址 | 雙目操作符、單目操作符 | |
! | 邏輯‘非’ | 單目操作符 | |
&& | 邏輯‘與’ | 雙目操作符 | |
|| | 邏輯‘或’ | 雙目操作符 | |
<< | 左移位 | 雙目操作符 | |
>> | 右移位 | 雙目操作符 | |
< | 小于 | 雙目操作符 | |
> | 大于 | 雙目操作符 | |
== | 等于 | 雙目操作符 | |
!= | 不等于 | 雙目操作符 | |
^ | 位‘異或’ | 雙目操作符 | |
+= | 和賦值 | 雙目操作符 | |
-= | 差賦值 | 雙目操作符 | |
*= | 乘賦值 | 雙目操作符 | |
/= | 商賦值 | 雙目操作符 | |
<<= | 左移賦值 | 雙目操作符 | |
>>= | 右移賦值 | 雙目操作符 | |
&= | 按位‘與’賦值 | 雙目操作符 | |
^= | 按位異或賦值 | 雙目操作符 | |
|= | 按位或賦值 | 雙目操作符 | |
%= | 模賦值 | 雙目操作符 | |
= | 賦值 | 雙目操作符 | |
?: | 按條件取值 | 雙目操作符 | |
, | 間隔符 | 標點符號 | |
# | 預處理符號 | 標點符號 | |
## | 預處理符號 | 標點符號 | |
sizeof | 求字節數 | ||
~ | 按位求反 | ||
| | 位‘或’ | ||
: | 間隔符 | ||
; | 間隔符 | ||
... | 間隔符 | ||
要把表中的運算符仔細的分類是不容易的,因為同一個運算符,在不同的地方其含義是不同的。如*運算符,當作為乘運算時是雙目操作符(所謂雙目操作符,即運算時需要二個操作數),如3*6,那么3與6總共是二個操作數。當作為取值運算時就是單目操作符(所謂單目操作符是只需要一個操作數)如對一個數求反:!a,這里只有一個操作數a。
要記住運算符的二個特點,一個是運算符的操作對象,另一個就是運算符的優先級別。其中運算符的優先級別是最不容易搞清楚和最容易出錯的地方。
在講運算符之前講一下“表達式”的概念:所謂表達式,就是用運算符把各個操作數連接成符合C語法規則的進行運算的式子。這里說的“符合C語法的規則”也很重要。如 a+b+5就是一個用算術運算符連接起來的表達式。
1、算術運算符:+、-、*、/、%
1)+、-、*、/ 分別是相加、相減、相乘、相除
2)% 求二個數運算的模。所謂求模就是求二個數相除后的余數。例:25/3的余數是1,可以說25%3的模是1。要注意的是求模運算時二個操作數必須是整數。如果求25.3/3.1這樣是不能運算的。
下面寫一個例子:
#include<stdio.h> /*程序中要用到輸入輸出庫函數,所以包含了stdio.h*/
void main()
{
int a=10,b=20,c=30; /*定義了3個整型變量,并同時進行了初始化賦值*/
a=a*b+c; /*a*b+c組成了一個算術表達式,運算后的結果為230并把值*/
/*賦給變量a*/
printf("%d",a); /*以整型格式輸出變量a的值。這里輸出230*/
a=a%b; /*進行求模運算。因為沒有余數,最后的模為0*/
printf("%d",a); /*輸出變量a的值。這里輸出0*/
}
下面是一個要考慮運算符優先級的例子:
#include<stdio.h>
void main()
{
int a=10,b=20,c=30;
a=c-a*b; /*這里就要考慮運算符優先級,*運算符的優先級比-運算符*/
/*的高,所以先進行乘運算。這里最后結果為-170*/
}
由上面這個例子看到,在一個有多個運算符連接起來的表達式中需要考慮運算符的優先級,這個例子很簡單。關于運算符優先級的概念其實在小學生的算術運算中就有這樣的概念了,只不過這里的運算符多了一些,要考慮的情況也就復雜了。
如果這個式子改寫一下,寫成:a=(c-a)*b;在運算時就以括號中的運算優先。
幾個簡化的運算表達式:
在C語言的程序中,經??吹竭@樣的運算,如:i++;或者k--;這是運算符號的簡化寫法。
1、加1運算的簡寫
當一個變量進行加1運算時,如a=a+1;這是變量自身加1,簡寫為a++;
2、減1運算的簡寫
當一個變量進行減1運算時,如a=a-1;這是變量自身減1,簡寫為a--;
3、加1個常量運算的簡寫
當一個變量與一個常量相加時,如a=a+5;這是變量自身加5,簡寫為a+=5;
4、減一個常量運算的簡寫
當一個變量與一個常量相減時,如a=a-5;這是變量自身減5,簡寫為a-=5;
5、乘一個常量運算的簡寫
當一個變量與一個常量相乘時,如a=a*5,這是變量自身乘5,簡寫為a*=5;
6、除一個常量運算的簡寫
當一個變量與一個常量相除時,如a=a/5;這是變量自身除5,簡寫為a/=5;
運算符的結合性(或稱作關聯性)
在一個復雜的表達式中,常常有許多運算符和變量,這時就要判斷優先級和結合性這二個因素。
例:-5+7; 這樣的一個表達式用結合性來判斷,因為運算符'-'和'+'相對于運算的數來說是‘左’結合的,所以就有'-5'和'+7'所以運算的結果為 2。
通過這個例子要知道什么是“左結合性”和“右結合性”
左結合性--變量(或常量)與左邊的運算符結合
右結合性--變量(或常量)與右邊的運算符結合
運算符的優先級和結合性表
優先級 | 運算符(高?。停?/TD> | 結合率 | 運算符類型 | |
高 | ( ) [ ] -> . | 從左至右 | 雙目運算符 | |
! ~ ++ -- (類型) sizeof + - * & | 從右至左 | 單目運算符 | ||
* / % | 從左至右 | 雙目運算符 | ||
+ - | 從左至右 | 雙目運算符 | ||
<< >> | 從左至右 | 雙目運算符 | ||
< <= > >= | 從左至右 | 雙目運算符 | ||
== != | 從左至右 | 雙目運算符 | ||
& | 從左至右 | 雙目運算符 | ||
^ | 從左至右 | 雙目運算符 | ||
| | 從左至右 | 雙目運算符 | ||
&& | 從左至右 | 雙目運算符 | ||
|| | 從左至右 | 雙目運算符 | ||
?: | 從右至左 | 三目運算符 | ||
低 | = += -= *= /= %= &= ^= |= <<= >>= | 從左至右 | 雙目運算符 | |
高 ?。〉?/TD> |
從表中可以看出一個規律,凡是單目運算符都是“右結合”的,凡是雙目運算符都是“左結合”的。其中有一個?:運算符是三目運算符是右結合的,記住了這個規律,運算符的結合性也就掌握了。
如果代碼行中的運算符比較多,用括號確定表達式的操作順序,避免使用默認的優先級。
由于將表熟記是比較困難的,為了防止產生歧義并提高可讀性,應當用括號確定表達式的操作順序。例如:
d = (high << 8) | low /*用括號把需要先運算的括起來*/
if ((a | b) && (a & c)) /*用括號把需要先運算的括起來*/
例:
下列程序輸出的結果是
#include<stdio.h>
void main()
{
int a=2;
a%=4-1;
printf("%d",a);
a+=a*=a-=a*=3;
printf("\n%d",a);
}
A. 2,0 B. 1,0
C. -1,12 D. 2,12
分析:由于%=運算符的優先級別低于-運算,a%=4-1即是a%=3,等價于a=a%3即a=2%3=2,所以選項B和C是錯誤的。表達式a+=a*=a-=a*=3,計算時注意賦值類表達式的值和變量的值隨時被更新,計算表達式的值,開始時a=2,表達式賦值是從左至右進行的,表達a*=3使得a=6,此表達式的值也為6,于是表達式a-=a*=3相當于a-=6=6-6=0,a的值為0,后面的計算就不用做了,所以a的值最終為0。
答:A
下列語句中錯誤的是
A.x=sizeof int;
B.x=sizeof 3.14
C.printf("%d",a=a+1,b--,c+1);
D.printf("%d",++x,x++);
分析:此題的選項A的作用是測試int類型所占內存的字節數,因為類型符要用括號括起來,這時缺少括號是錯誤的。
選項B是正確的。
選項C從表面上看似乎復雜一些,但其中的a=a+1,b--,c+1是一個逗號表達式,C語言允許使用這種表達式所以D也是正確的。
答案:A
下面的語句中,符合C語言語法的賦值語句是
A.a=7+b+c=a+7; B.a=7+b++=a+7;
C.a=7+b,b++,a+7; D.a=7+b;c=a+7;
分析:一般情況下,表達式不能放在賦值號的左邊,所以A和B選項是錯誤的。
選項C不是一個C語言的語句,因為它不是以分號作為結束標志的。
答:D