1.運算符概述
運算符是一種編譯器執行特定的數學或邏輯操作的符號。C語言提供了以下類型的運算符:
- 算術運算符
- 關系運算符
- 邏輯運算符
- 位運算符
- 賦值運算符
- 條件運算符
- 其他運算符
2.算術運算符
算術運算符分為單目運算符和雙目運算符,單目運算符表示只需要一個操作數,雙目運算符需要兩個操作數。
2.1 雙目算術運算符
- 1)+ :加法,把兩個操作數相加
- 2)- :減法,從第一個操作數中減去第二個操作數
- 3)* :乘法,把兩個操作數相乘
- 4)/ :除法,第一個操作數除以第二個操作數
- 5)% :求模(取余),第一個操作數除以第二個操作數所得余數
雙目運算符中,C語言中的加號、減號與數學中的一樣。乘號、除號因為ASCII符號中沒有與數學中相對應的符號,所以使用星號表示乘號,使用斜線表示除號。C語言中增加了一個求模運算符,是用來取余的。需要注意的是,求模運算符的兩個操作數必須是整型。
【實例6.1】加減乘除以及取模運算
#include <stdio.h>
int main()
{
int a = 21;
int b = 10;
int c;
float d = 2.5;
double e;
int f = -21;
int g = -10;
c = a + b;
printf(" a + b = %d\n", c);
c = a - b;
printf(" a - b = %d\n", c);
c = a * b;
printf(" a * b = %d\n", c);
c = a / b;
printf(" a / b = %d\n", c);
e = a / d;
printf(" a / d = %lf\n", e);
c = a % b;
printf(" a %% b = %d\n", c);
c = a % g;
printf(" a %% g = %d\n", c);
c = f % b;
printf(" f %% b = %d\n", c);
c = f % g;
printf(" f %% g = %d\n", c);
return 0;
}
執行以上程序,輸出結果為:
a + b = 31
a - b = 11
a * b = 210
a / b = 2
a / d = 8.400000
a % b = 1
a % g = 1
f % b = -1
f % g = -1
實例解析:
加、減與數學中的一樣,其中需要說明的是除法以及取模運算。C語言中的除法運算,不同類型的除數和被除數會導致不同類型的運算結果。一種情況是,當除數和被除數都是整數時,運算結果也是整數。當不能整除時,就直接舍棄小數部分,只保留整數部分。另一種情況是,一旦除數和被除數中有一個是小數,那么運算結果也是小數,並且是double類型的小數。C語言中的取余運算,就是求相除后的余數。取余運算中%的兩邊都必須是整數,不能出現小數,否則會報錯。余數可以是正數也可以是負數,由%左邊的整數決定:如果%左邊是正數,那么余數也是正數;如果%左邊是負數,那么余數也是負數。
2.2 單目算術運算符
- 1)- :取負,把操作數乘以-1
- 2)++:自增運算符,把操作數增加1
- 3)--:自減運算符,把操作數減少1
單目運算符中,只需要一個操作數。取負操作符將正操作數設置為負數,負操作數設置為正數。自增運算符使得變量的值增加1,自減運算符使得變量的值減少1。比如:
i++;
j--;
變量i的值增加1,變量j的值減少1,相當於:
i = i+1;
j = j-1;
自增運算符和自減運算符的運算對象只能是變量,不能是常量或者表達式,否則將會報錯。比如:
1++;//報錯
--(i+1);//報錯
自增運算符和自減運算符分為兩種方式:一種是在變量前面,稱為前綴模式;一種是在變量后面,稱為后綴模式。下面介紹一下兩種方式的區別:
- 前綴模式,先執行變量的自增或者自減操作,再將得到的結果參與表達式運算。
- 后綴模式,先將變量參與表達式運算,再執行變量的自增或者自減操作。
前綴模式,也被理解為先運算后賦值,比如:
i = 1;
j = ++i;
執行上面語句,i和j的值都是2。先是變量i自增,i的值變為2,再將結果2賦值給j。
后綴模式,也被理解為先賦值后運算,比如:
i = 1;
j = i++;
執行上面語句,i的值是2,j的值是1。先是變量i賦值給j,這個時候i還沒有自增操作,i的值還是1,所以j的值是1。賦值后,i再自增,i的值變為2。
【實例6.2】前綴模式和后綴模式
#include <stdio.h>
int main()
{
int a = 10;
int c;
c = a++;
printf("先賦值后運算:\n");
printf(" c 的值是 %d\n", c);
printf(" a 的值是 %d\n", a);
a = 10;//重新賦值為10
c = a--;
printf(" c 的值是 %d\n", c);
printf(" a 的值是 %d\n", a);
printf("先運算后賦值:\n");
a = 10;
c = ++a;
printf(" c 的值是 %d\n", c);
printf(" a 的值是 %d\n", a);
a = 10;
c = --a;
printf(" c 的值是 %d\n", c);
printf(" a 的值是 %d\n", a);
}
執行以上程序,輸出結果為:
先賦值后運算:
c 的值是 10
a 的值是 11
c 的值是 10
a 的值是 9
先運算后賦值:
c 的值是 11
a 的值是 11
c 的值是 9
a 的值是 9
實例解析:
++ 在變量前面和后面是有區別的:++ 在前面叫做前自增。前自增先進行自增運算,再進行其他操作。++ 在后面叫做后自增。后自增先進行其他操作,再進行自增運算。
對於,c = a++; a 的值不會立馬加 1,而是先把 a 原來的值(也就是10)交給 c,然后再加 1。a 原來的值為 10,所以 c 的值也就為 10。而 a 經過自增,最終值為 11。
對於,c = a--; a 的值不會立馬減 1,而是先把 a 原來的值(也就是10)交給 c,然后再減 1。a 原來的值為 10,所以 c 的值也就為 10。而 a 經過自減,最終值為 9。
對於,c = ++a,先執行 ++a,結果為 11,再將 11 賦值給 c,所以 c 的最終值為11。而 a 經過自增,最終的值也為 11。
對於,c = --a,先執行 --a,結果為 9,再將 9 賦值給 c,所以 c 的最終值為9。而 a 經過自減,最終的值也為 9。
2.3 算術運算符的優先級
在數學運算中,運算符是有優先級的,C語言中的運算符也有優先級。算術運算符的優先級:單目算術運算符(-、++、--) > 乘號(*)、除號(/)、求模(%) > 加號(+)、減號(-)。比如:
int a = 1 + 2 * 3;
根據優先級,將會先計算2 * 3,再將得到的結果6和1相加,得到7,賦值給變量a。
當表達式中有多個相同優先級的運算符時,按照從左到右的順序運算。比如:
int a = 1 + 2 * 3 / 3;
乘號(*)、除號(/)優先級相同,按照從左到右的順序運算,先計算2 * 3,將結果6 / 3,得到結果2和1相加,得到3,賦值給變量a。
如果需要改變表達式的運算順序,我們還可以使用圓括號。比如:
int a = (1 + 2) * 3 / 3;
先計算圓括號內的1 + 2,得到的結果3再去運算,最后得到3,賦值給變量a。
3.關系運算符
- 1)==:檢查兩個操作數的值是否相等,如果相等則條件為真。
- 2)!=:檢查兩個操作數的值是否相等,如果不相等則條件為真。
- 3)> :檢查左操作數的值是否大於右操作數的值,如果是則條件為真。
- 4)< :檢查左操作數的值是否小於右操作數的值,如果是則條件為真。
- 5)>=:檢查左操作數的值是否大於或等於右操作數的值,如果是則條件為真。
- 6)<=:檢查左操作數的值是否小於或等於右操作數的值,如果是則條件為真。
關系運算符只有兩種結果:true或者false。true代表條件為真,false代表條件為假。C語言中,一般非0值代表true,0代表false。比如:
1 == 2;//條件為假,結果是false。
1 != 2;//條件為真,結果是true。
1 > 2;//條件為假,結果是false。
1 < 2;//條件為真,結果是true。
1 >= 2;//條件為假,結果是false。
1 <= 2;//條件為真,結果是true。
4.邏輯運算符
- 1)! :單目運算符,稱為邏輯非運算符。用來逆轉操作數的邏輯狀態。如果條件為真則邏輯非運算符將使其為假。
- 2)&&:雙目運算符,稱為邏輯與運算符。如果兩個操作數都非零,則條件為真。
- 3)||:雙目運算符,稱為邏輯或運算符。如果兩個操作數中有任意一個非零,則條件為真。
邏輯運算符與數學上有相同之處。邏輯運算符和關系運算符一樣,也只有兩種結果:true或者false。邏輯運算符可以將多個關系表達式的結果合並起來。我們要判斷變量i是否在0和100之間,不能直接表示成:0 =< i =< 100。需要使用邏輯運算符來表示,比如:
i >= 0 && i =< 100
如果變量i在0和100之間,則結果為true,否則為false。
邏輯運算符也是有優先級的,邏輯非運算符(!)>邏輯與運算符(&&)>邏輯或運算符(||)。
【實例6.3】邏輯運算符
#include <stdio.h>
int main()
{
int a = 0, b = 1, c = 2, d = 3;
printf("!a = %d\n", !a);
printf("!b = %d\n", !b);
printf("a&&b = %d\n", a && b);
printf("a||b = %d\n", a || b);
printf("a&&b||c&&d = %d\n", a&&b || c&&d);
printf("a&&!b||c&&d = %d\n", a && !b || c&&d);
return 0;
}
執行以上程序,輸出結果為:
!a = 1
!b = 0
a&&b = 0
a||b = 1
a&&b||c&&d = 1
a&&!b||c&&d = 1
實例解析:
在使用printf()函數以整數形式輸出邏輯結果時,1代表true,0代表false。!a代表a取反,0取反結果為true,所以輸出1。那么!b取反則輸出0。a&&b代表a和b做與運算,0和1做與運算,結果為false,則輸出0。a||b 代表a和b做或運算,0和1做或運算,結果為true,則輸出1。a&&b || c&&d,根據優先級,我們先運算a&&b和c&&d,得到的結果是false和true,false和true進行或運算,結果還是true,所以輸出1。a && !b || c&&d,根據優先級,我們先運算!b,得到的結果是false,然后運算a和false以及c&&d,得到的結果是,false和true進行或運算,結果是true,所以輸出1。
5.位運算符
位運算符作用於位,並逐位執行操作,也就是二進制的運算。
- 1)~ :單目運算符,按二進制位進行取反運算。
- 2)& :雙目運算符,按二進制位進行與運算。
- 3)| :雙目運算符,按二進制位進行或運算。
- 4)^ :雙目運算符,按二進制位進行異或運算。
- 5)<<:雙目運算符,二進制左移運算符。
- 6)>>:雙目運算符,二進制右移運算符。
位運算符不能用於float、double等類型,只能用於整數類型。
【實例6.4】位運算符
#include <stdio.h>
int main()
{
int a = 50; /* 50 = 0011 0010 */
int b = 19; /* 19 = 0001 0011 */
int c = 0;
c = a & b; /* 18 = 0001 0010 */
printf("a & b 的值是 %d\n", c);
c = a | b; /* 51 = 0011 0011 */
printf("a | b 的值是 %d\n", c);
c = a ^ b; /* 33 = 0010 0001 */
printf("a ^ b 的值是 %d\n", c);
c = ~a; /* -51 = 1100 1100 */
printf("~a 的值是 %d\n", c);
c = a << 2; /* 200 = 1100 1000 */
printf("a << 2 的值是 %d\n", c);
c = a >> 2; /* 12 = 0000 1100 */
printf("a >> 2 的值是 %d\n", c);
return 0;
}
執行以上程序,輸出結果為:
a & b 的值是 18
a | b 的值是 51
a ^ b 的值是 33
~a 的值是 -51
a << 2 的值是 200
a >> 2 的值是 12
實例解析:
A = 50,B = 19,現在以二進制格式表示,它們如下所示:
A = 0011 0010
B = 0001 0011
然后按照二進制位進行相應運算得到結果值。二進制左移運算符,運算對象的各二進制位全部左移若干位,左邊的二進制位丟棄,右邊補0;二進制右移運算符,運算對象的的各二進制位全部右移若干位,正數左補0,負數左補1,右邊丟棄。
6.賦值運算符
C語言中,可以將賦值運算符分為兩類:簡單賦值運算符和復合賦值運算符。
2.1 簡單賦值運算符
簡單賦值運算符就是"=",一般語法格式:
變量 = 表達式;
賦值運算符"="和數學表達式中的等號"="的意義是不同的。前面我們就多次用到了賦值運算符"="。"="的作用是把結果賦值給變量,所以賦值運算符的左邊必須是變量,賦值運算符從右向左的順序計算。比如:
a = b = 1;
以上語句,先將1賦值給b,再將變量b賦值給變量a。
賦值也是一種運算,我們可以放在表達式中。比如:
a = (b = 1) + (c = 2);
以上語句,先將1賦值給b和將2賦值給c,再將變量b和c的值相加,最后得到的結果3賦值給a。
2.2 復合賦值運算符
- 1)+=:加賦值,a += b等價於a = a + b。
- 2)-=:減賦值,a -= b等價於a = a - b。
- 3)*=:乘賦值,a *= b等價於a = a * b。
- 4)/=:除賦值,a /= b等價於a = a / b。
- 5)%=:取余賦值,a %= b等價於a = a % b。
- 6)&=:位與賦值,a &= b等價於a = a & b。
- 7)|=:位或賦值,a |= b等價於a = a | b。
- 8)^=:位異或賦值,a ^= b等價於a = a ^ b。
- 9)<<=:位左移賦值,a <<= b等價於a = a << b。
- 10)>>=:位右移賦值,a >>= b等價於a = a >> b。
賦值運算的規則是將左側的變量和右側的操作數進行運算,然后再將得到的結果賦值給左側的變量。比如:
a += 1;
等價於:
a = a + 1;
7.條件運算符
條件運算的一般語法格式如下:
表達式1?表達式2:表達式3
從語法格式中,我們可以看出,這是一個三目運算。通過問號和冒號將三個表達式連接起來。整個表達式的運算過程:先計算表達式1的值,如果它的值為true(非0值),則將表達式2的值返回;如果它的值為false(0值),則將表達式3的值返回。
【實例6.5】條件運算符,比較兩個數的最大值
#include <stdio.h>
int main()
{
int a, b, max;
printf("Please input a:");
scanf("%d", &a);
printf("Please input b:");
scanf("%d", &b);
max = a > b ? a : b;
printf("max is:%d\n",max);
return 0;
}
執行以上程序,輸出結果為:
Please input a:5
Please input b:10
max is:10
實例解析:
先計算a > b,值為false,將b的值返回,結果為10。
8.其他運算符
- 1)sizeof:長度運算符
- 2)& :取地址運算符
- 3)[]:下標運算符
- 4)* :指針運算符
- 5). :結構體成員運算符
- 6)->:指向結構體成員運算符
這里介紹一下sizeof長度運算符,其余的在后面會講到。sizeof運算符返回一個數據類型、變量、常量所占的字節長度,可以使用printf()函數來輸出。
【實例6.6】sizeof長度運算符
#include <stdio.h>
int main()
{
int a = 100;
printf("int類型字節長度:%d\n", sizeof(int));
printf("變量a字節長度:%d\n", sizeof(a));
printf("常量100字節長度:%d\n", sizeof(100));
return 0;
}
執行以上程序,輸出結果為:
int類型字節長度:4
變量a字節長度:4
常量100字節長度:4
實例解析:
可以看到結果都是4,這是因為int類型的字節長度是4,變量a的字節長度也就是4,存儲的常量100自然也就是4。
9.總結
總結一下,本節內容主要介紹了C語言的算術運算符、關系運算符、邏輯運算符、位運算符、賦值運算符、條件運算符和其他運算符。
10.練習
6-1 下面程序的輸出結果是什么?
#include <stdio.h>
int main()
{
int a = 12, b = 1;
int c = a - (b--);
int d = (++a) - (--b);
printf("c=%d, d=%d\n", c, d);
return 0;
}
6-2 判斷下面結果是true還是flase:
1 > 1 && 3 < 4 || 4 > 5 && 2 > 1 && 9 > 8 || 7 < 6
! 2 > 1 and 3 < 4 or 4 > 5 and 2 > 1 and 9 > 8 or 7 < 6
6-3 編寫一個程序,比較三個數的最大值。
可以在評論中,寫下你們的練習答案。
之后的文章會給大家帶來更精彩的內容
歡迎關注我的知乎專欄:程序員基礎知識
獲取練習答案以及更多實戰項目
歡迎關注我的公眾號:程序員基礎知識
交(gao)流(ji)群:493584686