本文目錄
- [一、算術運算符](http://www.cnblogs.com/mjios/archive/2013/06/07/3071334.html#label0)
- [二、賦值運算符](http://www.cnblogs.com/mjios/archive/2013/06/07/3071334.html#label1)
- [三、自增運算符和自減運算符](http://www.cnblogs.com/mjios/archive/2013/06/07/3071334.html#label2)
- [四、sizeof](http://www.cnblogs.com/mjios/archive/2013/06/07/3071334.html#label3)
- [五、逗號運算符](http://www.cnblogs.com/mjios/archive/2013/06/07/3071334.html#label4)
- [六、關系運算符](http://www.cnblogs.com/mjios/archive/2013/06/07/3071334.html#label5)
- [七、邏輯運算符](http://www.cnblogs.com/mjios/archive/2013/06/07/3071334.html#label6)
- [八、三目運算符](http://www.cnblogs.com/mjios/archive/2013/06/07/3071334.html#label7)
- [九、位運算符](http://www.cnblogs.com/mjios/archive/2013/06/07/3071334.html#label8)
計算機的基本能力就是計算,所以一門程序設計語言的計算能力是非常重要的。C語言之所以無所不能,是因為它不僅有豐富的數據類型,還有強大的計算能力。C語言一共有34種運算符,包括了常見的加減乘除運算。這講就對C語言中的運算符做一個詳細介紹。
[回到頂部](http://www.cnblogs.com/mjios/archive/2013/06/07/3071334.html#labelTop)
##一、算術運算符
算術運算符非常地簡單,就是小學數學里面的一些加減乘除操作。不過呢,還是有一些語法細節需要注意的。
### 1.加法運算符 +?
~~~
1 int a = 10;
2
3 int b = a + 5;
~~~
在第3行利用加法運算符 + 進行了加法運算,再將和賦值給了變量b,最終變量b的值是15
### 2.減法運算符 或 負值運算符?-?
~~~
1 int b = 10 - 5;
2
3 int a = -10;
~~~
1> 在第1行利用減法運算符 - 進行了減法運算,再將差賦值給了變量b,最終變量b的值是5
2> 在第3行中,這個 - 并不是什么減法運算符,而算是一個負值運算符,-10代表的是負十
### 3.乘法運算符?*?
~~~
1 int b = 10 * 5;
~~~
注意:乘法運算符并不是x或者X,而是星號*。變量b最終的值是50。
### 4.除法運算符?/?
~~~
1 double a = 10.0 / 4;
2 double b = 10 / 4;
3
4 printf("a=%f, b=%f \n", a, b);
~~~
注意:除法運算符并不是÷,而是一個正斜杠 /
1> 第1行中的10.0是浮點型,4是整型,因此會將4自動類型提升為浮點型后再進行運算,最后變量b的值是2.5
2> 第2行中的10和4都是整型,計算機中的運算有個原則:相同數據類型的值才能進行運算,而且運算結果依然是同一種數據類型。因此,整數除于整數,求出來的結果依然是整數,會損失小數部分。最后變量b的值是2。查看輸出結果:

3> 如果想讓 整數除于整數 不損失精度的話,可以將某個整數強制轉換為浮點型數據
~~~
1 double a = (double)10 / 4;
2
3 double b = 10 / (double)4;
4
5 double c = (double)10 / (double)4;
6
7 double d = (double) (10 / 4);
~~~
- 10和4之間只要有1個強轉為浮點型數據即可,另外1個整數會自動類型提升為浮點型數據。因此,變量a、b、c的值都是2.5。
- 變量d的情況就不一樣了,第7行代碼的意思是先計算(10/4)的值,再將(10/4)的值強轉為浮點型數據。(10/4)的值是2,將2強轉為浮點型數據,那不也就是2么?所以,變量d的值是2
### 5.模運算符 或稱 取余運算符 %?
注意:這個%并不是除號÷,它是一個取余運算符,或者叫做模運算符。取余的意思是,取得兩個整數相除之后的余數。比如,5除于2的余數是1,5除于3的余數是2。因此使用這個%有個原則:%兩側必須都為整數。下面的寫法是錯誤的:
~~~
1 int a = 5.0 % 2;
~~~
編譯器會直接報錯,因為5.0并非整數。
#### 1> 正數取余
~~~
1 int a = 5 % 2;
2 int b = 2 % 5;
~~~
簡單計算可得:變量a的值為1,變量b的值為2
#### ?2> 負數取余
~~~
1 int a = -5 % 2;
2 int b = 5 % -2;
3 int c = -5 % -2;
~~~
利用%求出來的余數是正數還是負數,由%左邊的被除數決定,被除數是正數,余數就是正數,反之則反。因此變量a、b、c的值分別是-1、1、-1
### 6.運算順序
#### 1> 算術表達式
用算術運算符將數據連接起來的式子,稱為“算術表達式”。比如a + b、10 * 5等。如果表達式比較復雜的話,那么就要注意一下它的運算順序。表達式的運算順序是按照運算符的結合方向和優先級進行的。
#### 2> 結合方向
算術運算符的結合方向是從左到右。例如表達式2+3+4,先計算2+3。
#### 3> 優先級
優先級越高,就越先進行運算,當優先級相同時,參照結合方向。下面是算術運算符的優先級排序:
負值運算符(-)?>?乘(*)、除(/)、模(%)運算符?>?加(+)、減(-)運算符
例如表達式4+5*8/-2的計算順序為:-、*、/、+,最后的結果是-16
#### 4> 小括號
如果需要先計算優先級低的可以使用小括號()括住,小括號的優先級是最高的!
- 例如4+5*8-2默認的計算順序是:*、+、-
- 如果想先執行加法運算,就可以這樣寫:(4+5)*8-2,最后的結果都是不一樣的
[回到頂部](http://www.cnblogs.com/mjios/archive/2013/06/07/3071334.html#labelTop)
##二、賦值運算符
賦值運算符又分兩種:簡單賦值運算符 和 復合賦值運算符。
### 1.簡單賦值運算符 =
#### 1> 簡單用法
其實這個等號 = 從講[變量](http://www.cnblogs.com/mjios/archive/2013/05/07/3065522.html)開始就見過它了,它的作用是將右邊的值賦值給左邊。
~~~
1 int a = 10 + 5;
~~~
賦值運算符的結合方向是:從右到左,而且優先級比算術運算符低。因此先進行等號=右邊的加法運算,運算完畢后再將結果賦值給等號右邊的變量。最后變量a的值是15。
#### 2> 連續賦值
~~~
1 int a, b;
2
3 a = b = 10;
~~~
- 在第1行分別定義了int類型的變量a、b
- 第3行代碼的意思:將10賦值給變量b,再把變量b的值賦值給a。所以最后變量a、b的值都是10
#### 3> 使用注意
等號=左邊只能是變量,不能是常量!常量都是不可變的,怎么可以再次賦值呢?下面的寫法是錯誤的:
~~~
1 10 = 10 + 5;
~~~
### 2.復合賦值運算符
- +=? 加賦值運算符。如a += 3+2,等價于 a = a +(3+2)
- -=? 減賦值運算符。如a -= 3+2,等價于 a = a -(3+2)
- *=? 乘賦值運算符。如a *= 3+2,等價于 a = a *(3+2)
- /=? 除賦值運算符。如a /= 3+2,等價于 a = a /(3+2)
- %=? 取余賦值運算符。如a %= 3+2,等價于 a = a %(3+2)
[回到頂部](http://www.cnblogs.com/mjios/archive/2013/06/07/3071334.html#labelTop)
##三、自增運算符和自減運算符
### 1.簡介
- ++? 自增運算符。如a++,++a,都等價于a = a+1
- --? 自減運算符。如a--,--a,都等價于a = a-1
注意:你寫個5++是錯誤的,因為5是常量。
### 2.++a和a++的區別
1> 單獨使用++a和a++時,它們是沒區別的
~~~
1 int a = 10;
2 a++;
~~~
~~~
1 int a = 10;
2 ++a;
~~~
上面兩段代碼的效果都是讓a的值+1,最后a的值都為11
2> 下面這種情況,++a和a++就有區別了
~~~
1 int a = 10;
2
3 int b = ++a;
~~~
~~~
1 int a = 10;
2
3 int b = a++;
~~~
上面兩段代碼的執行結果是有區別的。
- 第1段代碼:++a的意思是先對a執行+1操作,再將a的值賦值給b。因此最后a、b的值都是11
- 第2段代碼:a++的意思是先將a的值拷貝出來一份,然后對a執行+1操作,于是a變成了11,但是拷貝出來的值還是10,a++運算完畢后,再將拷貝出來的值10賦值給了b,所以最后變量b的值是10,變量a的值是11
--a和a--的區別也是一樣的。
3> 再來看一個比較刁鉆的例子
~~~
1 int a = 10;
2
3 a = a++;
~~~
很多人一眼看上去,覺得最后a的值應該是11,其實最后a的值是10。前面已經說過a++的作用了,這里也是一樣的。先將a的值拷貝出來一份,然后對a執行+1操作,于是a變成了11,但是拷貝出來的值還是10,a++運算完畢后,再將拷貝出來的值10賦值給了a,所以最后變量a的值是10
[回到頂部](http://www.cnblogs.com/mjios/archive/2013/06/07/3071334.html#labelTop)
##四、sizeof
* sizeof可以用來計算一個變量或者一個常量、一種數據類型所占的內存字節數。
~~~
int size = sizeof(10);
printf("10所占的字節數:%d", size);
~~~
輸出結果:
,10是int類型的數據,在64bit編譯器環境下,int類型需要占用4個字節
* sizeof一共有3種形式
- sizeof( 變量\常量 )
~~~
sizeof(10);
char c = 'a';
sizeof(c);
~~~
- sizeof? 變量\常量
~~~
sizeof 10;
char c = 'a';
sizeof c;
~~~
- sizeof( 數據類型 )
~~~
sizeof(float);
~~~
注意,不可以寫成sizeof float;
[回到頂部](http://www.cnblogs.com/mjios/archive/2013/06/07/3071334.html#labelTop)
##五、逗號運算符
* 逗號運算符主要用于連接表達式,例如:
~~~
1 int a = 9;
2 int b = 10;
3
4 a = a+1 , b = 3*4;
~~~
* 用逗號運算符連接起來的表達式稱為逗號表達式,它的一般形式為:
表達式1, 表達式2, … …, 表達式n
逗號表達式的運算過程是:從左到右的順序,先計算表達式1,接著計算表達式2,...,最后計算表達式n
* 逗號運算符也是一種運算符,因此它也有運算結果。整個逗號表達式的值是最后一個表達式的值
~~~
1 int a = 2;
2 int b = 0;
3 int c;
4
5 c = (++a, a *= 2, b = a * 5);
6
7 printf("c = %d", c);
~~~
++a的結果為3,a *= 2的結果為6,b = a * 5的結果為30。因此,輸出結果為:
這里要注意的是,右邊的表達式是有用括號()包住的,如果不用括號包住,也就是:
~~~
1 c = ++a, a *= 2, b = a * 5;
2 printf("c = %d", c);
~~~
輸出結果將為:
,因為c = ++a也屬于逗號表達式的一部分,跟后面的a *= 2以及b = a * 5是相互獨立的
[回到頂部](http://www.cnblogs.com/mjios/archive/2013/06/07/3071334.html#labelTop)
##六、關系運算符
### 1.“真”與“假”
1> 默認情況下,我們在程序中寫的每一句正確代碼都會被執行。但很多時候,我們想在某個條件成立的情況下才執行某一段代碼。比如微信的這個界面:

如果用戶點擊了注冊按鈕,我們就執行“跳轉到注冊界面”的代碼;如果用戶點擊了登錄按鈕,我們就執行“跳轉到登錄界面”的代碼。如果用戶沒做出任何操作,就不執行前面所說的兩段代碼。像這種情況的話可以使用條件語句來完成,但是我們暫時不學習條件語句,先來看一些更基礎的知識:如何判斷一個條件成不成立。如果這個都不會判斷,還執行什么代碼。
2> 在C語言中,條件成立稱為“真”,條件不成立稱為“假”,因此,判斷條件是否成立,就是判斷條件的“真假”。那怎么判斷真假呢?C語言規定,任何非0值都為“真”,只有0才為“假”。也就是說,108、-18、4.5、-10.5等都是“真”,0則是“假”。
### 2.關系運算符的簡單使用
C語言中還提供了一些關系運算符,可以用來比較兩個數值的大小。
- <?? 小于。比如a<5
- <=? 小于等于。比如a<=5
- >?? 大于。比如a>5
- >=? 大于等于。比如a>=5
- ==? 等于。比如a==5
- !=? 不等于。比如a!=5
關系運算符的運算結果只有2種:如果條件成立,結果就為1,也就是“真”;如果條件不成立,結果就為0,也就是“假”。
~~~
1 int a1 = 5 > 4; // 1
2
3 int a2 = 5 < 4; // 0
~~~
### 3.關系運算符的使用注意
1> 關系運算符中==、!=的優先級相等,<、<=、>、>=的優先級相等,且前者的優先級低于后者
例如2==3>1 :先算3>1,條件成立,結果為1。再計算2==1,條件不成立,結果為0。因此2==3>1的結果為0。
2> 關系運算符的結合方向為“從左往右”
例如4>3>2 :先算4>3,條件成立,結果為1。再與2比較,即1>2,條件不成立,結果為0。因此4>3>2的結果為0。
3> 關系運算符的優先級小于算術運算符
例如3+4>8-2 :先計算3+4,結果為7。再計算8-2,結果為6。最后計算7>6,條件成立,結果為1。因此3+4>8-2的結果為1。
[回到頂部](http://www.cnblogs.com/mjios/archive/2013/06/07/3071334.html#labelTop)
##七、邏輯運算符
有時候,我們需要在多個條件同時成立的時候才能執行某段代碼,比如:用戶只有同時輸入了QQ和密碼,才能執行登錄代碼,如果只輸入了QQ或者只輸入了密碼,就不能執行登錄代碼。這種情況下,我們就要借助于C語言提供的邏輯運算符。
C語言提供了3個邏輯運算符:&&(邏輯與)、||(邏輯或)、!(邏輯非)。注意:這些都是英文字符,不要寫成中文字符。跟關系運算符一樣,邏輯運算的結果只有2個:“真”為1,“假”為0
### 1.&& 邏輯與
#### 1> 使用格式
“條件A && 條件B”
#### 2> 運算結果
只有當條件A和條件B都成立時,結果才為1,也就是“真”;其余情況的結果都為0,也就是“假”。因此,條件A或條件B只要有一個不成立,結果都為0,也就是“假”
#### 3> 運算過程
- 總是先判斷條件A是否成立
- 如果條件A成立,接著再判斷條件B是否成立:如果條件B成立,“條件A && 條件B”的結果就為1,即“真”,如果條件B不成立,結果就為0,即“假”
- 如果條件A不成立,就不會再去判斷條件B是否成立:因為條件A已經不成立了,不管條件B如何,“條件A && 條件B”的結果肯定是0,也就是“假”
#### 4> 舉例
邏輯與的結合方向是“自左至右”。比如表達式?(a>3) && (a<5)
- 若a的值是4:先判斷a>3,成立;再判斷a<5,也成立。因此結果為1
- 若a的值是2:先判斷a>3,不成立,停止判斷。因此結果為0
- 因此,如果a的值在(3, 5)這個范圍內,結果就為1;否則,結果就為0
#### 5> 注意
- 若想判斷a的值是否在(3, 5)范圍內,千萬不能寫成3<a<5,因為關系運算符的結合方向為“從左往右”。比如a為2,它會先算3<a,也就是3<2,條件不成立,結果為0。再與5比較,即0<5,條件成立,結果為1。因此3<a<5的結果為1,條件成立,也就是說當a的值為2時,a的值是在(3, 5)范圍內的。這明顯是不對的。正確的判斷方法是:(a>3) && (a<5)
- C語言規定:任何非0值都為“真”,只有0才為“假”。因此邏輯與也適用于數值。比如 5 && 4的結果是1,為“真”;-6 && 0的結果是0,為“假”
### 2.||? 邏輯或
#### 1> 使用格式
“條件A || 條件B”
#### 2> 運算結果
當條件A或條件B只要有一個成立時(也包括條件A和條件B都成立),結果就為1,也就是“真”;只有當條件A和條件B都不成立時,結果才為0,也就是“假”。
#### 3> 運算過程
- 總是先判斷條件A是否成立
- 如果條件A成立,就不會再去判斷條件B是否成立:因為條件A已經成立了,不管條件B如何,“條件A || 條件B”的結果肯定是1,也就是“真”
- 如果條件A不成立,接著再判斷條件B是否成立:如果條件B成立,“條件A || 條件B”的結果就為1,即“真”,如果條件B不成立,結果就為0,即“假”
#### 4> 舉例
邏輯或的結合方向是“自左至右”。比如表達式?(a<3) || (a>5)
- 若a的值是4:先判斷a<3,不成立;再判斷a>5,也不成立。因此結果為0
- 若a的值是2:先判斷a<3,成立,停止判斷。因此結果為1
- 因此,如果a的值在(-∞, 3)或者(5, +∞)范圍內,結果就為1;否則,結果就為0
#### 5> 注意
C語言規定:任何非0值都為“真”,只有0才為“假”。因此邏輯或也適用于數值。比如 5 || 4的結果是1,為“真”;-6 || 0的結果是1,為“真”;0 || 0的結果是0,為“假”
### 3.!?? 邏輯非
#### 1> 使用格式
“! 條件A”
#### 2> 運算結果
其實就是對條件A進行取反:若條件A成立,結果就為0,即“假”;若條件A不成立,結果就為1,即“真”。也就是說:真的變假,假的變真。
#### 3> 舉例
邏輯非的結合方向是“自右至左”。比如表達式?! (a>5)
- 若a的值是6:先判斷a>5,成立,再取反之后的結果為0
- 若a的值是2:先判斷a>3,不成立,再取反之后的結果為1
- 因此,如果a的值大于5,結果就為0;否則,結果就為1
#### 4> 注意
- 可以多次連續使用邏輯非運算符:!(4>2)結果為0,是“假”,!!(4>2)結果為1,是“真”,!!!(4>2)結果為0,是“假”
- C語言規定:任何非0值都為“真”,只有0才為“假”。因此,對非0值進行邏輯非!運算的結果都是0,對0值進行邏輯非!運算的結果為1。!5、!6.7、!-9的結果都為0,!0的結果為1
### 4.優先級
邏輯運算符的優先級順序為: 小括號() > 負號 - >?!?> 算術運算符 > 關系運算符 >?&&?>?||
- 表達式!(3>5) || (2<4) && (6<1) :先計算 !(3>5)、(2<4)、(6<1),結果為1,式子變為1 || 1 && 0,再計算1 && 0,式子變為1 || 0,最后的結果為1
- 表達式3+2<5||6>3 等價于 ((3+2) < 5) || (6>3),結果為1
- 表達式4>3 && !-5>2 等價于 (4>3) &&? ((!(-5)) > 2) ,結果為0
[回到頂部](http://www.cnblogs.com/mjios/archive/2013/06/07/3071334.html#labelTop)
##八、三目運算符
### 1.N目運算符
- 像邏輯非(!)、負號(-)這種只連接一個數據的符號,稱為“單目運算符”,比如!5、-5。
- 像算術運算符、關系運算符、邏輯運算符這種連接二個數據的負號,稱為“雙目運算符”,比如6+7、8*5、5>6、4 && 0、
- 以此類推,連接3個數據的運算符,應該稱為“三目運算符”
### 2.三目運算符
C語言提供了唯一一個三目運算符:條件運算符。
#### 1> 使用格式
表達式A???表達式B?:?表達式C
#### 2> 運算結果
如果表達式A成立,也就是為“真”,條件運算符的結果就是表達式B的值,否則,就為表達式C的值
#### 3> 結合方向和優先級
- 優先級順序為:算術運算符 > 關系運算符 >?條件運算符?> 賦值運算符
- 條件運算符的結合方向是“從右至左”
~~~
1 int a = 3>4 ? 4+5 : 5>4 ? 5+6 : 6>7+1;
~~~
上面的代碼等價于
~~~
1 int a = (3>4) ? (4+5) : ( (5>4) ? (5+6) : (6>(7+1)) );
~~~
簡化一下就是
~~~
1 int a = 0 ? 9 : ( 1 ? 11 : 0 );
~~~
繼續簡化為
~~~
1 int a = 0 ? 9 : 11;
~~~
所以a的值是11
[回到頂部](http://www.cnblogs.com/mjios/archive/2013/06/07/3071334.html#labelTop)
##九、位運算符
所謂位運算就是對每一個二進制位進行運算。C語言一共提供了6種位運算符,只能對整數進行操作,分別是:&按位與、|按位或、^按位異或、<<左移、>>右移、~取反。
### 1.& 按位與
1> 使用形式:整數a & 整數b
2> 功能:整數a和b各對應的二進位相與。只有對應的兩個二進位均為1時,結果位才為1,否則為0。參與運算的數以[補碼](http://www.cnblogs.com/mjios/archive/2013/05/25/3068114.html)方式出現。
3> 舉例:比如9&5,其實就是1001&101=1,因此9&5=1
4> 規律:
- 相同整數相&的結果是整數本身。比如5&5=5
- 多個整數相&的結果跟順序無關。比如5&6&7=5&7&6
### 2.| 按位或
1> 使用形式:整數a | 整數b
2> 功能:整數a和b各對應的二進位相或。只要對應的二個二進位有一個為1時,結果位就為1,否則為0。參與運算的數以[補碼](http://www.cnblogs.com/mjios/archive/2013/05/25/3068114.html)方式出現。
3> 舉例:比如9|5,其實就是1001|101=1101,因此9|5=13
4> 規律:
- 相同整數相|的結果是整數本身。比如5|5=5
- 多個整數相|的結果跟順序無關。比如5|6|7=5|7|6
### 3.^ 按位異或
1> 使用形式:整數a ^ 整數b
2> 功能:整數a和b各對應的二進位相異或。當對應的二進位相異(不相同)時,結果為1,否則為0。參與運算的數以[補碼](http://www.cnblogs.com/mjios/archive/2013/05/25/3068114.html)方式出現。
3> 舉例:比如9^5,其實就是1001^101=1100,因此9^5=12
4> 規律:
- 二進制中,與1相^就會取反,與0相^保持原位
- 相同整數相^的結果是0。比如5^5=0
- 多個整數相^的結果跟順序無關。比如5^6^7=5^7^6
- 因此得出結論:a^b^a = b
### 4.~ 取反
1> ~為單目運算符,具有右結合性,使用形式:~整數a
2> 功能:對整數a的各二進位進行取反(0變1,1變0)
3> 舉例:比如~9,其實就是~(0000 0000 0000 0000 0000 0000 0000 1001)=(1111 1111 1111 1111 1111 1111 1111 0110),因此~9=-10
### 5.<< 左移
1> <<是雙目運算符,使用形式:整數a<<正數n
2> 功能:把整數a的各二進位全部左移n位,高位丟棄,低位補0。左移n位其實就是乘以2的n次方。
3> 舉例:3<<4,3本來是0000 0011,左移4位后變成了0011 0000,因此3<<4 = 48 = 3 * 24
4> 需要注意的是:由于左移是丟棄最高位,0補最低位,所以符號位也會被丟棄,左移出來的結果值可能會改變正負性
### 6.>> 右移
1> >>是雙目運算符,使用形式:整數a>>正數n
2> 功能:把整數a的各二進位全部右移n位,保持符號位不變。右移n位其實就是除以2的n次方。
3> 舉例:32>>3,32本來是0010 0000,右移3位后變成了0000 0100,因此32>>3 = 4 = 32 / 23
- 前言
- C語言入門教程1-概述
- C語言入門教程2-第一個C程序
- C語言入門教程3-關鍵字、標識符、注釋
- C語言入門教程4-變量與常量
- C語言入門教程5-進制
- C語言入門教程6-變量與內存
- C語言入門教程7-基本數據類型
- C語言入門教程8-運算符
- C語言入門教程9-流程控制
- C語言入門教程10-函數
- C語言入門教程11-函數的聲明定義
- C語言入門教程12-scanf與printf輸入輸出函數
- C語言入門教程13-數組-批量數據存儲
- C語言入門教程14-字符串
- C語言入門教程15-字符與字符串常用處理函數
- C語言入門教程16-指針
- C語言入門教程17-指向一維數組元素的指針
- C語言入門教程18-指針與字符串
- C語言入門教程19-預處理指令1-宏定義
- C語言入門教程20-預處理指令2-條件編譯
- C語言入門教程21-預處理指令3-文件包含
- C語言入門教程22-變量類型與作用域
- C語言入門教程23-枚舉
- C語言入門教程24-結構體
- C語言入門教程25-typedef類型別名