? ?? 歡迎大家來到貝蒂大講堂??
? ????養(yǎng)成好習(xí)慣,先贊后看哦~????
? 所屬專欄:C語言學(xué)習(xí)
? 貝蒂的主頁:Betty‘s blog
1. 操作符的分類
操作符又叫運(yùn)算符,它在C語言中起著非常大的作用,以下是對(duì)操作符的分類:
- 算術(shù)操作符: + 、- 、* 、/ 、%
- 移位操作符: <<、 >>
- 位操作符: & 、| 、^、~
- 賦值操作符: = 、+= 、 -= 、 *= 、 /= 、%= 、<<= 、>>= 、&= 、|= 、^=
- 單目操作符:!、++、--、&、*、+、-、~ 、sizeof、(類型)
- 關(guān)系操作符:> 、>= 、< 、<= 、 == 、 !=
- 邏輯操作符: && 、||
- 條件操作符: ? :
- 逗號(hào)表達(dá)式: ,
- 下標(biāo)引用:[]
- 函數(shù)調(diào)用: ()
- 結(jié)構(gòu)成員訪問: . 、->
2. 算術(shù)操作符
2.1 用法
算術(shù)操作符顧名思義就是參與運(yùn)算的操作符
下表顯示了 C 語言支持的所有算術(shù)操作符。假設(shè)變量 A 的值為 1,變量 B 的值為 2,則:
運(yùn)算符 | 描述 | 實(shí)例 |
---|---|---|
+ | 把兩個(gè)操作數(shù)相加 | A + B 將得到 3 |
- | 從第一個(gè)操作數(shù)中減去第二個(gè)操作數(shù) | A - B 將得到 -1 |
* | 把兩個(gè)操作數(shù)相乘 | A * B 將得到 2 |
/ | 分子除以分母 | A / B 將得到 0 |
% | 取模運(yùn)算符,整除后的余數(shù) | A%B將得到 1 |
2.2 代碼實(shí)現(xiàn)
#include<stdio.h>
int main()
{
int a = 1;
int b = 2;
int 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);
c = a / b;
printf("a/b=%d\n", c);
c = a % b;
printf("a%%b=%d\n", c);
return 0;
輸出結(jié)果:
a+b=3
a-b=-1
a*b=2
a/b=0
a%b=1
3. 移位操作符
3.1 用法
移位操作符改變的是二進(jìn)制序列,所以操作對(duì)象是整數(shù),且移動(dòng)位數(shù)不能為負(fù)數(shù)
下表顯示了 C 語言支持的移位操作符。假設(shè)變量 A 的值為 1:
運(yùn)算符 | 描述 | 實(shí)例 |
---|---|---|
<< | 將操作數(shù)的所有位向左移動(dòng)指定的位數(shù)。運(yùn)算規(guī)則:左邊的二進(jìn)制位丟棄,右邊補(bǔ)0。 | A<<1=2 |
>> | 將操作數(shù)的所有位向右移動(dòng)指定的位數(shù)。運(yùn)算規(guī)則分兩種:1. 邏輯右移:左邊?0填充,右邊丟棄 2. 算術(shù)右移:左邊?原該值的符號(hào)位填充,右邊丟棄 | A>>1=0 |
3.2 圖像演示
- 左移操作符
- 右移操作符
3.3 代碼實(shí)現(xiàn)
int main()
{
int a = 1;
printf("左移之后值為%d\n", a << 1);
int b = -1;
printf("右移之后值為%d\n",b>> 1);
return 0;
}
輸出結(jié)果:
左移之后值為2
右移之后值為-1
- 右移之后為-1,說明在VS2022的環(huán)境下,右移操作符是算術(shù)右移
4. 位操作符
4.1 用法
位操作符與移位操作符一樣作用對(duì)象是二進(jìn)制序列,所以操作數(shù)自然只能為整數(shù)
下表顯示了 C 語言支持的位操作符。假設(shè)變量 A 的值為 1,變量 B 的值為 2,則:
運(yùn)算符 | 描述 | 實(shí)例 |
---|---|---|
& | 對(duì)兩個(gè)操作數(shù)的每個(gè)二進(jìn)制位執(zhí)行邏輯與操作,如果兩個(gè)相應(yīng)的位都為 1,則結(jié)果為 1,否則為 0。 | (A & B) 將得到 0 |
| | 對(duì)兩個(gè)操作數(shù)的每個(gè)二進(jìn)制位執(zhí)行邏輯或操作,如果兩個(gè)相應(yīng)的位都為 0,則結(jié)果為 0,否則為 1。 | (A | B) 將得到 3 |
^ | 對(duì)兩個(gè)操作數(shù)的每個(gè)二進(jìn)制位執(zhí)行邏輯異或操作,如果兩個(gè)相應(yīng)的位值相同,則結(jié)果為 0,否則為 1。 | (A ^ B) 將得到 3 |
~ | 對(duì)操作數(shù)的每個(gè)二進(jìn)制位執(zhí)行邏輯取反操作,即將每一位的 0 變?yōu)?1,1 變?yōu)?0。 | (~A ) 將得到 -2 |
4.2 代碼實(shí)現(xiàn)
int main()
{
int a = 1;
int b = 2;
int 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);
c = ~a;
printf("~a=%d\n", c);
return 0;
}
輸出結(jié)果:
a&b=0
a|b=3
a^b=3
~a=-2
4.3 具體分析
- a的原碼,反碼,補(bǔ)碼:00000000000000000000000000000001
- b的原碼,反碼,補(bǔ)碼:00000000000000000000000000000010
- a&b:00000000000000000000000000000000——>0
- a|b:00000000000000000000000000000011——>3
- a^b:00000000000000000000000000000011——>3
- ~a的原碼:11111111111111111111111111111110
- ~a的反碼:11111111111111111111111111111101
- ~a的補(bǔ)碼:10000000000000000000000000000010——>-2
4.4 有趣的例題
題目: 不能創(chuàng)建臨時(shí)變量(第三個(gè)變量),實(shí)現(xiàn)兩個(gè)數(shù)的交換。
代碼實(shí)現(xiàn):
#include <stdio.h>
int main()
{
int a = 10;
int b = 20;
a = a ^ b;
b = a ^ b;
a = a ^ b;
printf("a = %d b = %d\n", a, b);
return 0;
}
分析:要想解決這個(gè)問題就要使用我們剛學(xué)的異或操作符,并且我們得知道一個(gè)數(shù)異或本身是0,因?yàn)樗卸M(jìn)制位都相同。并且0異或任何數(shù)都等于該數(shù),因?yàn)樗卸M(jìn)制位都不同。而且異或是遵循交換率與結(jié)合率的。
- 因?yàn)閍=ab,所以b=ab=abb=a^0=a
- a=ab=aba=b0=b,成功實(shí)現(xiàn)兩個(gè)數(shù)的交換
5. 賦值操作符
5.1 用法
賦值操作符顧名思義,就是對(duì)變量進(jìn)行賦值
下表列出了 C 語言支持的賦值操作符:
運(yùn)算符 | 描述 | 實(shí)例 |
---|---|---|
= | 簡(jiǎn)單的賦值運(yùn)算符,把右邊操作數(shù)的值賦給左邊操作數(shù) | C = A + B 將把 A + B 的值賦給 C |
+= | 加且賦值運(yùn)算符,把右邊操作數(shù)加上左邊操作數(shù)的結(jié)果賦值給左邊操作數(shù) | C += A 相當(dāng)于 C = C + A |
-= | 減且賦值運(yùn)算符,把左邊操作數(shù)減去右邊操作數(shù)的結(jié)果賦值給左邊操作數(shù) | C -= A 相當(dāng)于 C = C - A |
*= | 乘且賦值運(yùn)算符,把右邊操作數(shù)乘以左邊操作數(shù)的結(jié)果賦值給左邊操作數(shù) | C *= A 相當(dāng)于 C = C * A |
/= | 除且賦值運(yùn)算符,把左邊操作數(shù)除以右邊操作數(shù)的結(jié)果賦值給左邊操作數(shù) | C /= A 相當(dāng)于 C = C / A |
%= | 求模且賦值運(yùn)算符,求兩個(gè)操作數(shù)的模賦值給左邊操作數(shù) | C %= A 相當(dāng)于 C = C % A |
<<= | 左移且賦值運(yùn)算符 | C <<= 2 等同于 C = C << 2 |
>>= | 右移且賦值運(yùn)算符 | C >>= 2 等同于 C = C >> 2 |
&= | 按位與且賦值運(yùn)算符 | C &= 2 等同于 C = C & 2 |
^= | 按位異或且賦值運(yùn)算符 | C ^= 2 等同于 C = C ^ 2 |
|= | 按位或且賦值運(yùn)算符 | C |= 2 等同于 C = C | 2 |
5.2 代碼實(shí)現(xiàn)
#include <stdio.h>
int main()
{
int a = 10;
int c;
c = a;
printf(" = 運(yùn)算符實(shí)例:c 的值 = %d\n", c);
c += a;
printf("+= 運(yùn)算符實(shí)例:c 的值 = %d\n", c);
c -= a;
printf("-= 運(yùn)算符實(shí)例:c 的值 = %d\n", c);
c *= a;
printf("*= 運(yùn)算符實(shí)例:c 的值 = %d\n", c);
c /= a;
printf("/= 運(yùn)算符實(shí)例:c 的值 = %d\n", c);
c = 200;
c %= a;
printf("%%= 運(yùn)算符實(shí)例:c 的值 = %d\n", c);
c <<= 2;
printf("<<= 運(yùn)算符實(shí)例:c 的值 = %d\n", c);
c >>= 2;
printf(">>= 運(yùn)算符實(shí)例:c 的值 = %d\n", c);
c &= 2;
printf("&= 運(yùn)算符實(shí)例:c 的值 = %d\n", c);
c ^= 2;
printf("^= 運(yùn)算符實(shí)例:c 的值 = %d\n", c);
c |= 2;
printf("|= 運(yùn)算符實(shí)例:c 的值 = %d\n", c);
return 0;
}
輸出結(jié)果:
= 運(yùn)算符實(shí)例:c 的值 = 10
+= 運(yùn)算符實(shí)例:c 的值 = 20
-= 運(yùn)算符實(shí)例:c 的值 = 10
*= 運(yùn)算符實(shí)例:c 的值 = 100
/= 運(yùn)算符實(shí)例:c 的值 = 10
%= 運(yùn)算符實(shí)例:c 的值 = 0
<<= 運(yùn)算符實(shí)例:c 的值 = 0
>>= 運(yùn)算符實(shí)例:c 的值 = 0
&= 運(yùn)算符實(shí)例:c 的值 = 0
^= 運(yùn)算符實(shí)例:c 的值 = 2
|= 運(yùn)算符實(shí)例:c 的值 = 2
6. 單目操作符
6.1 用法
單目操作符簡(jiǎn)單來說就是,操作的對(duì)象只有一個(gè)
下表列出了 C 語言支持的單目操作符:
運(yùn)算符 | 描述 | 實(shí)例 |
---|---|---|
sizeof() | 返回變量的大小。 | sizeof(a) 將返回a變量的大小 |
& | 返回變量的地址。 | &a, 將給出變量的實(shí)際地址。 |
* | 指向一個(gè)變量。 | *a,將指向一個(gè)變量。 |
++ | 自增運(yùn)算符,整數(shù)值增加 1 | a++等價(jià)于a=a+1 |
-- | 自減運(yùn)算符,整數(shù)值減少 1 | a--等價(jià)于a=a-1 |
! | 稱為邏輯非運(yùn)算符。用來逆轉(zhuǎn)操作數(shù)的邏輯狀態(tài)。如果條件為真,則邏輯非運(yùn)算符將使其為假。 | 假設(shè)a為真,!a為假 |
(類型) | 將一種類型強(qiáng)制轉(zhuǎn)換為另一種類型 | 假設(shè)a為int型,(float)a將a轉(zhuǎn)換為float型 |
6.2 代碼實(shí)現(xiàn)
int main()
{
int a = 1;
printf("a的大小為%d\n", sizeof(a));
int* p = &a;
printf("a的地址為%p\n",p );
int b = *p;
printf("b的值為%d\n", b);
a++;
printf("a的值為%d\n",a);
a--;
printf("a的值為%d\n", a);
printf("a的值為%d\n", !a);//0為假
float c = (float)a;
return 0;
}
輸出結(jié)果:
a的大小為4
a的地址為010FFC08
b的值為1
a的值為2
a的值為1
a的值為0
6.3 前置與后置++,--的區(qū)別
首先我們先來看一段代碼
int main()
{
int a = 1;
int b = a++;//后置++
printf("a=%d b=%d\n", a, b);
int c = ++a;//前置++
printf("a=%d c=%d\n", a, c);
int m = a--;//后置
printf("a=%d m=%d\n", a, m);
int n = --a;//前置--
printf("a=%d n=%d\n", a, n);
return 0;
}
輸出結(jié)果:
a=2 b=1
a=3 c=3
a=2 m=3
a=1 n=1
通過上述代碼,我們可以總結(jié)以下結(jié)論:
- 前置++,--先執(zhí)行++或--,然后對(duì)等式左邊進(jìn)行賦值
- 后置++,--恰好相反,先對(duì)等式左邊進(jìn)行賦值,然后再++或--
6.4 易錯(cuò)題
題目:下例代碼輸出結(jié)果為?
int main()
{
int a = 12;
int b = 1;
int c = a - (b--);//1
int d = (++a) - (--b);//2
printf("c=%d d=%d\n", c, d);
return 0;
}
輸出結(jié)果:
c=11 d=14
代碼分析:
-
執(zhí)行語句1時(shí),因?yàn)閎后置--,所以b先使用,后--,然后進(jìn)行a-b運(yùn)算,結(jié)果是 11,隨后b 再自減,就變成了 0;最后再將a-b的結(jié)果(也就是11)交給 c,所以 c 的值是 11。
-
執(zhí)行語句2之前,b 的值已經(jīng)變成 0。對(duì)于d=(++a)-(--b),a 會(huì)先自增,變成 13,然后 b 再自減,變成 -1,最后再計(jì)算13-(-1),結(jié)果是 14,交給 d,所以 d 最終是 14。
7. 關(guān)系操作符
7.1 用法
關(guān)系操作符就是進(jìn)行關(guān)系之間的比較
下表顯示了 C 語言支持的所有關(guān)系運(yùn)算符。假設(shè)變量 A 的值為 1,變量 B 的值為 2,則:
運(yùn)算符 | 描述 | 實(shí)例 |
---|---|---|
== | 檢查兩個(gè)操作數(shù)的值是否相等,如果相等則條件為真。 | (A == B) 為假。 |
!= | 檢查兩個(gè)操作數(shù)的值是否相等,如果不相等則條件為真。 | (A != B) 為真。 |
> | 檢查左操作數(shù)的值是否大于右操作數(shù)的值,如果是則條件為真。 | (A > B) 為假。 |
< | 檢查左操作數(shù)的值是否小于右操作數(shù)的值,如果是則條件為真。 | (A < B) 為真。 |
>= | 檢查左操作數(shù)的值是否大于或等于右操作數(shù)的值,如果是則條件為真。 | (A >= B) 為假。 |
<= | 檢查左操作數(shù)的值是否小于或等于右操作數(shù)的值,如果是則條件為真。 | (A <= B) 為真。 |
7.2 代碼實(shí)現(xiàn)
int main()
{
int a = 1;
int b = 2;
if (a == b)
{
printf(" a 等于 b\n");
}
else
{
printf(" 不等于 b\n");
}
if (a < b)
{
printf(" a 小于 b\n");
}
else
{
printf(" a 不小于 b\n");
}
if (a > b)
{
printf(" a 大于 b\n");
}
else
{
printf(" a 不大于 b\n");
}
if (a <= b)
{
printf(" a 小于或等于 b\n");
}
if (b >= a)
{
printf(" b 大于或等于 a\n");
}
}
輸出結(jié)果:
不等于 b
a 小于 b
a 不大于 b
a 小于或等于 b
b 大于或等于 a
8. 邏輯操作符
8.1 用法
下表顯示了 C 語言支持的所有關(guān)系邏輯運(yùn)算符。假設(shè)變量 A 的值為 1,變量 B 的值為 0,則:
運(yùn)算符 | 描述 | 實(shí)例 |
---|---|---|
&& | 稱為邏輯與運(yùn)算符。如果兩個(gè)操作數(shù)都非零,則條件為真。 | (A && B) 為假。 |
|| | 稱為邏輯或運(yùn)算符。如果兩個(gè)操作數(shù)中有任意一個(gè)數(shù)非零,則條件為真。 | (A || B) 為真。 |
8.2 代碼實(shí)現(xiàn)
int main()
{
int a = 1;
int b = 0;
if (a && b)
{
printf("a&&b條件為真\n");
}
else
{
printf("a&&b條件為假\n");
}
if (a || b)
{
printf("a||b條件為真\n");
}
else
{
printf("a||b條件為假\n");
}
}
輸出結(jié)果:
a&&b條件為假
a||b條件為真
8.3 補(bǔ)充講解
- 下列代碼會(huì)輸出什么
#include <stdio.h>
int main()
{
int i = 0, a = 0, b = 2, c = 3, d = 4;
i = a++ && ++b && d++;
printf("a=%d\nb=%d\nc=%d\nd=%d\n", a, b, c, d);
return 0;
}
輸出結(jié)果:
a=1
b=2
c=3
d=4
代碼分析
為什么會(huì)出現(xiàn)這個(gè)結(jié)果呢?這是因?yàn)檫壿嬇c(&&)一遇見假(0)等式就為假,不會(huì)在往后運(yùn)算
所以a先使用為0,等式為假,然后再++,a為1,其他變量不會(huì)改變
- 同樣的道理,下列代碼輸出什么
#include <stdio.h>
int main()
{
int i = 0, a = 0, b = 2, c = 3, d = 4;
i=a++||++b||d++;
printf("a=%d\nb=%d\nc=%d\nd=%d\n", a, b, c, d);
return 0;
}
輸出結(jié)果:
a=1
b=3
c=3
d=4
代碼分析:
與邏輯與同樣的道理,邏輯或(||)是一遇見真,整個(gè)表達(dá)式就為真,后面就不會(huì)執(zhí)行
a先使用為0,++變?yōu)?,b先++變?yōu)?,在使用為真,后面表達(dá)式不執(zhí)行
9. 條件操作符與逗號(hào)表達(dá)式
9.1 條件操作符
條件操作符又稱為三目操作符,它的語法規(guī)則為:
如果條件為真 ? 則值為 X : 否則值為 Y
代碼示例:
int main()
{
int a = 1;
int b = 1;
int c = a == b ? 20 : 10;
//含義:如果a=b為真,就將20賦給c,反之把10賦給c
return 0;
}
9.2 逗號(hào)表達(dá)式
逗號(hào)表達(dá)式,就是?逗號(hào)隔開的多個(gè)表達(dá)式。
逗號(hào)表達(dá)式,從左向右依次執(zhí)?。整個(gè)表達(dá)式的結(jié)果是最后?個(gè)表達(dá)式的結(jié)果。
exp1, exp2, exp3, …expN
代碼示例:
int main()
{
int a = 1;
int b = 2;
int c = (a > b, a = b + 10, a, b = a + 1);
printf("c=%d",c);
return 0;
}
輸出結(jié)果:
c=13
代碼分析:
逗號(hào)表達(dá)式從左往右依次計(jì)算,a>b為假,a=b+10=12,a為12,b=a+1=13,再將13賦值給c
10. 下標(biāo)引用和函數(shù)調(diào)用操作符
10.1 下標(biāo)引用
下標(biāo)引用一般是與數(shù)組有關(guān),它一般有兩個(gè)作用
int arr[10];//創(chuàng)建數(shù)組
arr[1]=10;//對(duì)數(shù)組賦值
10.2 函數(shù)調(diào)用
函數(shù)調(diào)用肯定是與函數(shù)相關(guān),因?yàn)榇蠹以谇懊鎸W(xué)過函數(shù),所以就簡(jiǎn)單舉個(gè)例子
代碼示例:
int Add(int x, int y)
{
return x + y;
}
int main()
{
int a = 1;
int b = 2;
int ret = Add(a, b);
return 0;
}
11. 結(jié)構(gòu)體成員訪問操作符
我們知道結(jié)構(gòu)結(jié)構(gòu)體訪問一般有兩種方式,直接訪問(.)與間接訪問(->)
11.1 用法
下表顯示了 C 語言支持的結(jié)構(gòu)體成員訪問操作符。假設(shè)已定義結(jié)構(gòu)體struct stu s則:
運(yùn)算符 | 描述 | 實(shí)例 |
---|---|---|
直接訪問(.) | 通過結(jié)構(gòu)體變量直接訪問其中成員 | s.age=10 |
間接訪問(->) | 通過結(jié)構(gòu)體變量地址間接訪問其中成員 | &s->age=11 |
11.2 代碼實(shí)現(xiàn)
struct stu
{
int age;
char name[14];
};
int main()
{
struct stu s;
s.age = 10;
(&s)->age = 11;
return 0;
}
12. 操作符的優(yōu)先級(jí)與結(jié)合性
12.1 介紹
優(yōu)先級(jí)指的是,如果?個(gè)表達(dá)式包含多個(gè)運(yùn)算符,哪個(gè)運(yùn)算符應(yīng)該優(yōu)先執(zhí)?。各種運(yùn)算符的優(yōu)先級(jí)是不?樣的。
結(jié)合性指的是如果兩個(gè)運(yùn)算符優(yōu)先級(jí)相同,優(yōu)先級(jí)沒辦法確定先計(jì)算哪個(gè)了,這時(shí)候就看結(jié)合性了,則根據(jù)運(yùn)算符是左結(jié)合,還是右結(jié)合,決定執(zhí)?順序。?部分運(yùn)算符是左結(jié)合(從左到右執(zhí)?),少數(shù)運(yùn)算符是右結(jié)合(從右到左執(zhí)?),?如賦值運(yùn)算符( = )。
下面是各種操作符的優(yōu)先級(jí)與結(jié)合性
12.2 弊端
優(yōu)先級(jí)和結(jié)合性其實(shí)是有弊端的,因?yàn)檫@兩者都不能解決所有問題,比如說下面這段代碼輸出什么
#include <stdio.h>
int main()
{
int i = 1;
int ret = (++i) + (++i) + (++i);
printf("%d\n", ret);
printf("%d\n", i);
return 0;
}
這其實(shí)是道錯(cuò)題,因?yàn)樵诓煌幾g器下結(jié)果是不同的。
VS 2022環(huán)境下:
gcc環(huán)境下:文章來源:http://www.zghlxwxcb.cn/news/detail-814764.html
文章來源地址http://www.zghlxwxcb.cn/news/detail-814764.html
- 而且不得不吐槽一句,在公司里寫代碼哪個(gè)程序員會(huì)這樣賦值寫代碼呀~
到了這里,關(guān)于C語言中的操作符:了解與實(shí)踐的文章就介紹完了。如果您還想了解更多內(nèi)容,請(qǐng)?jiān)谟疑辖撬阉鱐OY模板網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關(guān)文章,希望大家以后多多支持TOY模板網(wǎng)!