操作符又稱為運算符。作為運算對象的變量或者常量稱為操作數。
操作符做左側的操作數稱為第一操作數或者左操作數,操作符右邊的操作數稱為第二操作數或者右操作數。
操作符同時對兩個操作數進行運算的稱為雙目操作符,操作符只對一個操作數進行運算的稱為單目操作符。
在大家使用的電子計算機中所有的數據都是用ON/OFF信號(即1/0)來表示的。而我們比較用于理解的在日常接觸的是以10為基數的十進制數,而對計算機來說以2為基數的二進制數則更易于理解。
基數,在表示數值的時候,基數是進位的基準?;鶖禐?0的十進制數哦,每逢10或10的倍數就進位。
雖說對于硬件底層的程序而言,二進制數會更加適宜,但是對于我們而言,將所有的數值都用二進制數來表示可就是一件令人頭疼的事情了。二進制雖然有很多優(yōu)點,但是位數過多使得處理和閱讀不便也是不可忽略的缺點,所以在寫法上還使用了相對書寫和便于閱讀的八進制數和十六進制數。
四種進制十進制
十進制中,如果0~9這十個數字用完就進位
0, 1, 2, 3, 4, 5, 6, 7, 8, 9
10,11,12,13,14,15,16,17,18,19
20,21,22,23,24,25,26,27,28,29
八進制
在八進制中,如果0~7這八個數字用完就進位
0, 1, 2, 3, 4, 5, 6, 7
10,11,12,13,14,15,16,17
20,21,22,23,24,25,26,27
在十六進制中,十六個數分別為0,1,2,3,4,5,6,7,8,9,A,B,C,D,E,F
,當這十六個數用完時,進位
0, 1, 2, 3, 4, 5, 6, 7, 8, 9, A, B, C, D, E, F
10,11,12,13,14,15,16,17,18,19,1A,1B,1C,1D,1F
在二進制中,0和1用于表示所有的數據,當0和1用完進位
00000000,00000001,00000010,00000011,00000100
上述五個二進制數分別表示十進制中:0,1,2,3,4
進制轉換二進制數規(guī)律:
對于一個十進制數
如果為偶數,那么這個數的二進制數末尾數字為0
如果為奇數,那么這個數的二進制數末尾數字為1
(也就是說用一個十進制數除以2做得到的余數就是末尾數字的值)
二進制、八進制、十六進制 轉 十進制數
十進制 轉 二進制、八進制、十六進制
轉 二進制
將十進制數57轉換為二進制數的步驟如下:
57
/
2
=
28............1
28
/
2
=
14............0
14
/
2
=
7.............0
7
/
2
=
3..............1
3
/
2
=
1..............1
1
/
2
=
0..............1
轉
化
為
二
進
制
結
果
為
:
111001
57/2=28............1\\ 28/2=14............0\\ 14/2=7.............0\\ 7 /2=3..............1\\ 3 /2=1..............1\\ 1 /2=0..............1\\ 轉化為二進制結果為:111001
57/2=28............128/2=14............014/2=7.............07/2=3..............13/2=1..............11/2=0..............1轉化為二進制結果為:111001
轉 八進制
將十進制數57轉換為八進制數的步驟如下:
57
/
8
=
7............1
7
/
8
=
0............7
轉
化
為
八
進
制
結
果
為
:
71
57/8=7............1\\ 7/8=0............7\\ 轉化為八進制結果為:71
57/8=7............17/8=0............7轉化為八進制結果為:71
轉 十六進制
將十進制數57轉換為十六進制數的步驟如下:
57
/
16
=
3............9
3
/
16
=
0............3
轉
化
為
十
六
進
制
結
果
為
:
39
57/16=3............9\\ 3/16=0............3\\ 轉化為十六進制結果為:39
57/16=3............93/16=0............3轉化為十六進制結果為:39
整數的二進制表示形式其實有三種,分別為原碼、反碼、補碼。
原碼是我們平時所書寫的二進制形式,例如把一個十進制數轉換為二進制數,這個二進制數就是原碼的形式。
而反碼和補碼,是通過原碼進行轉換得到的。
而在內存中,存儲的其實是補碼。所以對于對二進制位進行操作的操作符,本質上都是對補碼進行操作。
我們知道一個有符號數是分正負的,而在二進制中,用最高位表示符號位,正數最高位為0,負數最高位為1。
對于一個有符號數來說
正數:原碼、反碼、補碼相同。
負數:原碼、反碼、補碼不同,原碼經過計算可以得到反碼和補碼。
原碼反碼補碼計算
原碼:按照一個數的正負,直接寫出其二進制表示形式得到的就是原碼。
反碼:原碼的符號位不變,其余位全部按位取反,得到的就是反碼。
補碼:在反碼的基礎上加1,得到的就是補碼。
原碼求反碼計算流程
原碼 → 符 號 位 不 變 其 余 位 按 位 取 反 \xrightarrow[]{符號位不變其余位按位取反} 符號位不變其余位按位取反 ?反碼 → 反 碼 加 一 \xrightarrow[]{反碼加一} 反碼加一 ?補碼
反碼求原碼計算流程
操作符分類方法1:補碼 → 補 碼 減 一 \xrightarrow[]{補碼減一} 補碼減一 ?反碼 → 符 號 位 不 變 其 余 位 按 位 取 反 \xrightarrow[]{符號位不變其余位按位取反} 符號位不變其余位按位取反 ?原碼
方法2:補碼 → 符 號 位 不 變 其 余 位 按 位 取 反 \xrightarrow[]{符號位不變其余位按位取反} 符號位不變其余位按位取反 ?反碼 → 反 碼 加 一 \xrightarrow[]{反碼加一} 反碼加一 ?原碼
操作符 | 語法 | 求 |
---|---|---|
+ 操作符 | a + b | 和 |
- 操作符 | a - b | 差 |
* 乘法操作符 | a * b | 積 |
/ 除法操作符 | a / b | 商 |
% 取模(求余數)操作符 | a % b | 余數 |
9 / 2
的商為 49.0 / 2
的商為 4.500000(輸出為double類型)9 / 2
的余數為 1上面說過位操作符所操作的數是存儲在內存中的補碼,所以位移操作符是對補碼進行移位操作。
操作符 | 語法 | |
---|---|---|
<< 左移操作符 | a<< b | 將a左移b位,右邊空出的位用0填充 |
>>右移操作符 | a >>b | 將a右移b位 |
a<< b
會將a的所有位按位向左移動b位,并在右邊空出的位(低位)上補0,如果a為無符號整型,則a<< b
的運算結果為
a
×
2
b
a\times2^b
a×2b。十進制數在左移一位后,值會變成原本的十倍,例如196左移一位變?yōu)?960。二進制也是一樣,在沒有溢出的情況下,左移一位值變?yōu)樵档?倍。
a >>b
會將a的所有位按位向右移動b位。如果a為無符號整型或者有符號整型的非負數,則運算結果為 a ÷ 2 b a\div2^b a÷2b所得到結果的整數部分。
如果a為有符號整型的負數形式,位移運算的結果因編譯器的不同而會有所不同,在許多編譯器中會執(zhí)行邏輯位移或者算術位移,但是無論使用哪種方式都會降低程序的可移植性所以我們應該或者說不要對負數進行位移。
邏輯右移
邏輯右移不考慮符號位的情況是0還是1,所有的二進制位都進行位移,負整數右移時,符號位由1變?yōu)?,位移的結果為0或整數。
算術右移
算術右移,所有二進制位進行位移,用符號位來補空位,例如符號位為1,所有空位補1。
操作符 | 語法 | |
---|---|---|
& 按位與 | a & b | 計算a和b的邏輯與 |
| 按位或 | a | b | 計算a和b的邏輯或 |
^ 按位異或 | a ^ b | 計算a和b的邏輯異或 |
這些運算符的操作數必須是整型數據類型或者枚舉類型。
這些運算符會根據1為真0為假的運算規(guī)則對操作數的各二進制位進行邏輯運算。
int a = 3;
//正數:原反補相同
//補碼:00000000000000000000000000000011
int b = -5;
//原碼:10000000000000000000000000000101
//反碼:11111111111111111111111111111010
//補碼:11111111111111111111111111111011
int c = a & b;
//a-補碼:00000000000000000000000000000011
//b-補碼:11111111111111111111111111111011
// a & b:00000000000000000000000000000011
int c = a | b;
//a-補碼:00000000000000000000000000000011
//b-補碼:11111111111111111111111111111011
// a | b:11111111111111111111111111111011
int c = a | b;
//a-補碼:00000000000000000000000000000011
//b-補碼:11111111111111111111111111111011
// a ^ b:11111111111111111111111111111000
賦值操作符操作符 | 語法 | |
---|---|---|
= 賦值操作符 | a = b | 把b的值賦值給a |
利用賦值操作符,你可以將你之前不滿意的值修改為你滿意的值(例如你的工資)
復合賦值符操作符 | 語法 | |
---|---|---|
+= 加法賦值 | a += b | a = a + b |
-= 減法賦值 | a -= b | a = a - b |
*= 乘法賦值 | a *= b | a = a * b |
/= 除法賦值 | a /= b | a = a / b |
%= 取模賦值 | a %= b | a = a % b |
<<= 左移賦值 | a >>= b | a = a >>b |
>>= 右移賦值 | a<<= b | a = a<< b |
&= 位邏輯與賦值 | a &= b | a = a & b |
|= 位邏輯或賦值 | a |= b | a = a | b |
^= 位邏輯異或賦值 | a ^= b | a = a ^ b |
操作符 | 語法 | |
---|---|---|
! 邏輯反 | !a | 當a本身為0時,!a值為1, 當a本身為1時,!a值為0 |
- 負值 | -a | a值為正數時,-a值為負數 |
+ 正值 | +a | |
& 取地址 | &a | 取a的地址 |
sizeof 求類型長度 | sizeof(a) | 求a(對象、常量、類型名等)的長度 |
~ 按位取反 | ~a | 對一個數的二進制位按位取反 |
– 自減1 | a–/–a | –a,前置–,先自減1再使用 a–,后置–,先使用再自減1 |
++ 自加1 | a++/++a | ++a,前置++,先自加1再使用 a++,后置++,先使用再自加1 |
* 間接訪問操作符 | *a | 又稱為解引用操作符 |
()強制類型轉換 | (類型)a | 將一個變量的或者常量的類型,強制類型轉換為括號內的類型 |
操作符 | 語法 | |
---|---|---|
> | a >b | 判斷a是否大于b,若a大于b返回1,若a不大于b返回0 |
>= | a >= b | 判斷a是否大于等于b,若a大于等于b返回1,若a小于b返回0 |
< | a< b | 判斷a是否小于b,若a小于b返回1,若a不小于b返回0 |
<= | a<= b | 判斷a是否小于等于b,若a小于等于b返回1,若大于b返回0 |
!= | a != b | 判斷a是否不等于b,若a不等于b返回1,若a等于b返回0 |
== | a == b | 判斷a是否等于b,若a等于b返回1,若a不等于b返回0 |
邏輯操作符要注意區(qū)分=和== 一個等號為賦值兩個等號為判斷相等
操作符 | 語法 | |
---|---|---|
&& 邏輯與 | a && b | 如果a和b都不為0,則表達式的結果為1;如果a和b其中一個為0則表達式結果為0 |
|| 邏輯或 | a || b | 如果a和b中有一個不為0,則表達式的結果為1;如果a和b都為0,則表達式結果為0 |
C語言中0表示假,非0表示真
要注意區(qū)分
邏輯與 和 按位與
邏輯或 和 按位或
true
,假為false
看一段C語言源代碼
#define bool _Bool
#define false 0
#define true 1
從上述代碼我們可以知道,布爾類型的本質還是0和1,在編寫代碼時,使用bool
和_bool
都是允許的。
&&
邏輯與操作符,在左操作數的結果為0時,操作符右邊操作數不再進行計算。||
邏輯或操作符,在左操作數的結果不為0時,不再對右邊的操作數進行計算。操作符 | 語法 | |
---|---|---|
exp1 ? exp2 : exp3 | a ? b : c | 計算表達式a,若a不為0,則結果為表達式b的結果;若a為0,則結果為表達式c的結果 |
操作符 | 語法 | |
---|---|---|
exp1,exp2,exp3,…,expN | a,b,c | 從左向右依次執(zhí)行,整個逗號表達式的結果就是最后一個表達式expN的計算結果 |
操作符 | 語法 | |
---|---|---|
[ ] | arr[a] | 訪問數組arr中下標為a的元素 |
操作符 | 語法 | |
---|---|---|
( ) | strlen(“abcdef”) | 調用strlen函數,求abcdef的字符串長度 |
操作符 | 語法 | |
---|---|---|
. | a . b | 表示結構體a中的成員b;a為對象名或者結構體名,b為成員名。 |
-> | a ->b | 用指針訪問結構體a中的成員b;a為結構體指針,b為成員名 |
(*p).m
可以簡寫為p->m
。
表達式求值
.
運算符和->
運算符統(tǒng)稱為訪問運算符。
表達式求值的順序一般是由操作符的優(yōu)先級和結合性決定的。
隱式類型轉換(整型提升)在C語言整型算術運算中,通常至少以整型類型的精度進行計算。為了獲得這一精度,表達式中的字符或者短整型操作數會在使用之前轉換為普通整型,這種轉換稱為整型提升。
當然,如果在同時存在int型和unsigned int型的表達式中,如果int型無法表示出原數據類型的所有數值,就將值轉換為unsigned int型。
整型提升 不會改變符號和數值,char類型是否作為符號類型來處理,需要由編譯器決定,不同的編譯器所運算標準不同。
#includeint main()
{
//int類型內存中占位為4個字節(jié),32個比特位
//char類型內存中占位為1個字節(jié),8個比特位
char a = 3;
//3在內存中的補碼為:00000000000000000000000000000011
//把一個int類型的3存放在char類型的a中需要進行截斷
//00000011 -a
char b = 127;
//127在內存中的補碼為:00000000000000000000000001111111
//01111111 -b
char c = a + b;
//表達式中的字符或轉整型在使用之前需要轉換為普通整型——這種轉換稱為整型提升
//在vs2019中默認char類型為signed char也就是有符號字符類型
//對于有符號類型的整型提升,符號位為什么(0/1),整型提升時的空位就補什么
//00000000000000000000000000000011 -a //符號位為0,空位補0
//00000000000000000000000001111111 -b
//00000000000000000000000010000010 -a+b
//把a+b之后得到的存儲在char類型的c中需要進行截斷
//10000010 -c
printf("%d\n", c);
// %d 打印一個十進制的整型
//c為一個有符號char類型,所以需要進行整型提升
//10000010 -c 符號位為1 整型提升空位補1
//11111111111111111111111110000010 -補碼
//內存中存儲的是二進制補碼形式,打印顯示出來的為原碼表示的十進制值
//11111111111111111111111110000001
//10000000000000000000000001111110 -原碼
return 0;
}
總結:
算術轉換在表達式進行運算之前,編譯器會自動為表達式中的char類型和short類型操作數進行整型提升,然后在進行運算。
當把一個較大類型存儲在一個較小類型中,需要進行截斷
不同的編譯器對于char類型是否有符號是不同的
如果一個雙目操作符,甚至多目操作符的幾個操作數屬于不同的數據類型,那么編譯器會對其做數據類型轉換。數據類型轉換的目的是為了確定通用數據類型,否則不同的數據類型操作數不能將進行運算。這一過程稱為普通算術類型轉換。
類型 | 排名 |
---|---|
long double | 1 |
double | 2 |
float | 3 |
unsigned long int | 4 |
long int | 5 |
unsigned int | 6 |
int | 7 |
操作符屬性上述表格中的類型,如果同時出現在一個操作符的操作數中,在進行算術類型轉換時,通常為排名靠后的向排名靠前的類型轉換。
但是也要注意,轉換需要合理,不然會造成精度的缺失,例如一個浮點型數轉換為int型,小數點后面的數會丟失,造成精度丟失。
復雜表達式的求值具有三個影響的因素:
- 操作符的優(yōu)先級
- 操作符的結合性
- 是否控制求值順序
兩個相鄰的操作符,誰的優(yōu)先級高先執(zhí)行誰。
優(yōu)先級相同,取決于結合性。
注意:如果我們寫出的表達式,不能通過操作符的屬性確定其唯一的計算路徑,那么這個表達式就是存在問題的!?。?/p>
t | 3 |
| unsigned long int | 4 |
| long int | 5 |
| unsigned int | 6 |
| int | 7 |
操作符屬性上述表格中的類型,如果同時出現在一個操作符的操作數中,在進行算術類型轉換時,通常為排名靠后的向排名靠前的類型轉換。
但是也要注意,轉換需要合理,不然會造成精度的缺失,例如一個浮點型數轉換為int型,小數點后面的數會丟失,造成精度丟失。
復雜表達式的求值具有三個影響的因素:
- 操作符的優(yōu)先級
- 操作符的結合性
- 是否控制求值順序
兩個相鄰的操作符,誰的優(yōu)先級高先執(zhí)行誰。
優(yōu)先級相同,取決于結合性。
[外鏈圖片轉存中…(img-xsiyNEIi-1669379888954)]
注意:如果我們寫出的表達式,不能通過操作符的屬性確定其唯一的計算路徑,那么這個表達式就是存在問題的?。?!
你是否還在尋找穩(wěn)定的海外服務器提供商?創(chuàng)新互聯www.cdcxhl.cn海外機房具備T級流量清洗系統(tǒng)配攻擊溯源,準確流量調度確保服務器高可用性,企業(yè)級服務器適合批量采購,新人活動首月15元起,快前往官網查看詳情吧
分享名稱:C語言-操作符是什么?-創(chuàng)新互聯
文章出自:http://aaarwkj.com/article30/ccccso.html
成都網站建設公司_創(chuàng)新互聯,為您提供小程序開發(fā)、網站制作、手機網站建設、軟件開發(fā)、云服務器、自適應網站
聲明:本網站發(fā)布的內容(圖片、視頻和文字)以用戶投稿、用戶轉載內容為主,如果涉及侵權請盡快告知,我們將會在第一時間刪除。文章觀點不代表本網站立場,如需處理請聯系客服。電話:028-86922220;郵箱:631063699@qq.com。內容未經允許不得轉載,或轉載時需注明來源: 創(chuàng)新互聯