C語言各類操作符全面講解
1 算術(shù)操作符
+ - * / %
+,-和*操作數(shù)我就不多說了,這里我們重點來 / 和%
/操作數(shù)
作用:就是求商
注意點:
1 二邊的操作數(shù)都是整形,商的結(jié)果就為整數(shù)
2 二邊的操作數(shù)有一個是浮點型結(jié)果就為小數(shù)
%操作數(shù)
作用:求余數(shù)
注意點:. % 操作符的兩個操作數(shù)必須為整數(shù)。返回的是整除之后的余數(shù)。
2 移位操作符
<< 左移操作符
>> 右移操作符
注意:移位操作符移的是二進(jìn)制位,且操作數(shù)只能是整數(shù)
<< 左移操作符
規(guī)則:左邊拋棄、右邊補(bǔ)0
代碼舉例:
#include<stdio.h> int main() { int a = -5; //正數(shù)的原碼,反碼和補(bǔ)碼都相同 //這是負(fù)數(shù)的規(guī)則: //10000000000000000000000000000101原碼 //11111111111111111111111111111010反碼(原碼的符號位不變,其他位按位取反) //11111111111111111111111111111011補(bǔ)碼(反碼+1就是補(bǔ)碼) int b = a << 1; //11111111111111111111111111110110補(bǔ)碼 //11111111111111111111111111110101反碼 //10000000000000000000000000001010原碼 printf("a = %d\n", a); printf("b = %d\n", b); return 0; }
當(dāng)a<<1時
當(dāng)a<<2時
當(dāng)a<<3時
總結(jié):
1 操作數(shù)被移位操作符操作后其值仍然不變
2 計算機(jī)存儲的都是補(bǔ)碼,而打印出來的是原碼所對應(yīng)的值
3 b=a<<n時,b的值位a*2^n,也就是說當(dāng)我們左移1位時相當(dāng)與乘了個2倍
>> 右移操作符
移位規(guī)則: 首先右移運(yùn)算分兩種:
1. 邏輯移位 左邊用0填充,右邊丟棄
2. 算術(shù)移位 左邊用原該值的符號位填充,右邊丟棄
代碼舉例:
#define _CRT_SECURE_NO_WARNINGS #include<stdio.h> int main() { int a = -64; int b = a >> 1; printf("a = %d\n", a); printf("b = %d\n", b); return 0; }
當(dāng)a>>1時
當(dāng)a>>2時
當(dāng)a>>3時
總結(jié):
1 右移操作和左移操作是本質(zhì)都是對補(bǔ)碼的二進(jìn)制位進(jìn)行操作
2 b=a>>n時,b的值位a/2^n,也就是說當(dāng)我們左移1位時相當(dāng)與除了個2倍
注意:
對于移位運(yùn)算符,不要移動負(fù)數(shù)位,這個是標(biāo)準(zhǔn)未定義的。
3 位操作符
& //按位與
| //按位或
^ //按位異或
注:他們的操作數(shù)必須是整數(shù)。
我們這些位操作符都是針對操作數(shù)的補(bǔ)碼進(jìn)行操作的
&操作符
作用:對于二進(jìn)制數(shù),都為0才為0都為1才為1
代碼舉例:
#include<stdio.h> int main() { int a = 5; //00000000000000000000000000000101 5的補(bǔ)碼 int b = -3; //10000000000000000000000000000011 3的原碼 //11111111111111111111111111111100 3的反碼 //11111111111111111111111111111101 3的補(bǔ)碼 int c = a & b; //00000000000000000000000000000101 5的補(bǔ)碼 //11111111111111111111111111111101 3的補(bǔ)碼 // &的作用是二進(jìn)制數(shù),都為0才為0都為1才為1 //00000000000000000000000000000101 c的補(bǔ)碼 printf("a = %d\n", a); printf("b = %d\n", b); printf("c = %d\n", c); return 0; }
|按位或
作用:二進(jìn)制位中有一個為1就為1,
^按位異或
作用:二進(jìn)制位中相異置1,相同為置0
大家知道這些操作符的作用了,我們來做到題目來實戰(zhàn)一下吧。
題目1:不能創(chuàng)建臨時變量(第三個變量),實現(xiàn)兩個數(shù)的交換
代碼實現(xiàn):
#include<stdio.h> int main() { int a = 2; //0010 int b = 3; //0011 printf("交換前a = %d,b = %d \n", a, b); a = a ^ b; //a的值0001 b = a ^ b; //b的值0010(2) a = a ^ b; //a的值0011(3) printf("交換后a = %d,b = %d\n", a, b); return 0; }
題目2:編寫代碼實現(xiàn):求一個整數(shù)存儲在內(nèi)存中的二進(jìn)制中1的個數(shù)。
代碼實現(xiàn):
//num&1便會找到二進(jìn)制最低位是否為1 #include<stdio.h> int main() { int num = -1; int i = 0; int count = 0;//計數(shù) for (i = 0;i < 32;i++) { if (num & (1 << i)) { count++; } } printf("二進(jìn)制數(shù)中1的個數(shù):count = %d\n", count); return 0; }
總結(jié):
我們要想看二進(jìn)制中的最低位是1還0,我們就可以通過&1來實現(xiàn)。
4 賦值操作符
=
這個操作符是用來賦值的,我們要于‘==’區(qū)分,這個是用來表示相等的,大家是否在編程的時候會弄錯呢?下面教大家一種寫法可以在很大程度上避免這種錯誤。
#define _CRT_SECURE_NO_WARNINGS #include<stdio.h> int main() { int a = 1; if (1 == a) { printf("可以避免錯誤\n"); } }
要是我們寫成1=a,就會報下面的錯誤,這樣我們就能夠及時的改正自己的錯誤,是不是很好呢。
復(fù)合賦值符
+=
-=
*=
/=
%=
>>=
<<=
&=
|=
^=
這些都是=操作符的復(fù)合形式,舉個例子。
a+=10;就相當(dāng)于a=a+10;
a-=10;就相當(dāng)于a=a-10;
5 單目操作符
! 邏輯反操作
- 負(fù)值
+ 正值
& 取地址
sizeof 操作數(shù)的類型長度(以字節(jié)為單位)
~ 對一個數(shù)的二進(jìn)制按位取反
-- 前置、后置--
++ 前置、后置++
* 間接訪問操作符(解引用操作符)
(類型) 強(qiáng)制類型轉(zhuǎn)換
單目操作符的操作對像是1個,下面我們來一一細(xì)說。
5.1 ! 邏輯反操作
就是讓真變假,假變真
代碼舉例:
#include<stdio.h> int main() { int a = 0; int b = 1; int c = !a; int d = !b; printf("c = %d,d = %d\n", c, d); return 0; }
5.2 sizeof 和數(shù)組
sizeof是用來求操作數(shù)的類型長度(以字節(jié)為單位)
下面我們來看到這段代碼
#include <stdio.h> void test1(int arr[]) { printf("%d\n", sizeof(arr));//(2) } void test2(char ch[]) { printf("%d\n", sizeof(ch));//(4) } int main() { int arr[10] = { 0 }; char ch[10] = { 0 }; printf("%d\n", sizeof(arr));//(1) printf("%d\n", sizeof(ch));//(3) test1(arr); test2(ch); return 0; }
他們的結(jié)果分別是 40 10 4 4,為什么呢?
第一個我們求的是整的數(shù)組的大小,arr有10個元素,每個元素都是整形,所有數(shù)組的大小為40個字節(jié)。
第二個ch有10個元素,每給個元素為char 類型,所以ch數(shù)組大小為10字節(jié)
第三個和第四個傳的是數(shù)組名(本質(zhì)上都是首元素地址),那么對于test1和test2應(yīng)該用指針來接收,所以在test1和test2其實求的是指針的大小,在32平臺,指針的大小應(yīng)該為4個字節(jié)。
6 關(guān)系操作符
>
>=
< <=
!= 用于測試“不相等”
== 用于測試“相等”
7 邏輯操作符
&& 邏輯與
|| 邏輯或
用一道例題來說明邏輯操作符
#include <stdio.h> int main() { int i = 0, a = 0, b = 2, c = 3, d = 4; i = a++ && ++b && d++; //i = a++||++b||d++; printf("a = %d\n b = %d\n c = %d\nd = %d\n", a, b, c, d); return 0; }
為什么b= 2,c= 3,d =4呢?我們不是進(jìn)行來對bcd進(jìn)行了前置++或者后置++的操作嗎?
這是因為對于&&來說只要他的左表達(dá)式為假了,后面就不在執(zhí)行。
而對于||來說只要左表達(dá)式為真,后面就不在執(zhí)行了
8 條件操作符
xp1 ? exp2 : exp3
這個意思就是如果xp1為真,就執(zhí)行exp2,否則就執(zhí)行exp3。
9 逗號表達(dá)式
exp1, exp2, exp3,.......expN
逗號表達(dá)式,就是用逗號隔開的多個表達(dá)式。
逗號表達(dá)式,從左向右依次執(zhí)行。整個表達(dá)式的結(jié)果是最后一個表達(dá)式的結(jié)果。
10 下標(biāo)引用函數(shù)調(diào)用和結(jié)構(gòu)成員
10.1 [ ]下標(biāo)引用操作符
操作數(shù):一個數(shù)組名 + 一個索引值
對于一個已經(jīng)初始化的數(shù)組來說,arr[7]和7[arr]及*(arr+7)都是等價的。
#include<stdio.h> int main() { int arr[10] = { 0 }; arr[7] = 5; printf("arr[7] = %d\n", arr[7]); 7[arr] = 6; printf("arr[7] = %d\n", arr[7]); *(arr + 7) = 7; printf("arr[7] = %d\n", arr[7]); return 0; }
10.2 ()函數(shù)調(diào)用操作符
接受一個或者多個操作數(shù):第一個操作數(shù)是函數(shù)名,剩余的操作數(shù)就是傳遞給函數(shù)的參數(shù)。
10.3 訪問一個結(jié)構(gòu)的成員
. 結(jié)構(gòu)體.成員名
-> 結(jié)構(gòu)體指針->成員名
11 表達(dá)式求值
對于一給表達(dá)式我們一般要考慮它的計算操作符的優(yōu)先級和結(jié)合性,當(dāng)表達(dá)式進(jìn)行求值的時候還可能會發(fā)生整形提升。
11.1 整形提升
什么是整形提升呢?就是在計算的計算的過程中都是默認(rèn)以整形的方式進(jìn)行計算的,當(dāng)我是char類型參與計算時候就要發(fā)生整形提升。
整形提升規(guī)則:
負(fù)數(shù)的整形提升
char c1 = -1;
變量c1的二進(jìn)制位(補(bǔ)碼)中只有8個比特位:
1111111
因為 char 為有符號的 char
所以整形提升的時候,高位補(bǔ)充符號位,即為1
提升之后的結(jié)果是: 11111111111111111111111111111111
正數(shù)的整形提升
char c2 = 1;
變量c2的二進(jìn)制位(補(bǔ)碼)中只有8個比特位:
00000001
因為 char 為有符號的 char 所以整形提升的時候,高位補(bǔ)充符號位,即為0
提升之后的結(jié)果是: 00000000000000000000000000000001
無符號整形提升,高位補(bǔ)0
11.2 優(yōu)先級和結(jié)合性
對于應(yīng)該復(fù)雜表達(dá)式的求值有三個影響的因素。
1. 操作符的優(yōu)先級
2. 操作符的結(jié)合性
3. 是否控制求值順序。
兩個相鄰的操作符先執(zhí)行哪個?取決于他們的優(yōu)先級。如果兩者的優(yōu)先級相同,取決于他們的結(jié)合性。
那么我們知道了解復(fù)雜表達(dá)式的3個元素,那么表達(dá)式求數(shù)的結(jié)果一定說唯一的嗎?
下面我們來看到問題表達(dá)式:
int c = 1;
int b = c+ --c;
請問b中的值是什么?
b=1?b=0?為什么二個結(jié)果呢?
對--操作符的優(yōu)先級是比+高的,但是并沒有規(guī)定系統(tǒng)是怎么給C準(zhǔn)備空間的,如果開始為就表達(dá)中的c開辟了空間,那么結(jié)果就為1,如果是在--c之后在開辟空間的,那么結(jié)果就為0。
這些問題表達(dá)式我們要謹(jǐn)防在我們的代碼中出現(xiàn)。
總結(jié)
對于這些操作符,不是看完這篇博客將能掌握的,大家還是要在寫代碼多練習(xí)。
到此這篇關(guān)于C語言各類操作符全面講解的文章就介紹到這了,更多相關(guān)C語言操作符內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
C++ 靜態(tài)成員的類內(nèi)初始化詳解及實例代碼
這篇文章主要介紹了C++ 靜態(tài)成員的類內(nèi)初始化詳解及實例代碼的相關(guān)資料,需要的朋友可以參考下2017-02-02C++操作MySQL大量數(shù)據(jù)插入效率低下的解決方法
這篇文章主要介紹了C++操作MySQL大量數(shù)據(jù)插入效率低下的解決方法,需要的朋友可以參考下2014-07-07makefile如何調(diào)用靜態(tài)庫的方法實現(xiàn)
這篇文章主要介紹了makefile如何調(diào)用靜態(tài)庫的方法實現(xiàn),文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧2020-12-12