目錄
前言
5.運算符和表達式
5-1-1 加減乘除運算符
1.把變量進行加減乘除運算
2.把常量進行加減乘除運算
3.對于比較大的數(往數軸正方向或者負方向),要注意占位符的選取
4.浮點數的加減乘除?
5-1-2取余/取模運算符
1.基本規則
2.c語言中,取余與除法規則的區分
5-1-3 字符的加減法
1.基本規則和原理
2. 可以輸出一下‘X’,‘Z’對應的ASCII碼值,加以驗證?
3.字符加減法的應用
1.輸入小寫字母,輸出大寫字母
2.輸入大寫字母,輸出小寫字母
5-2遞增遞減運算符
1.前綴自增與后綴自增含義相同的情況
2前綴自增和后綴自增的區別?
3.前綴自減和后綴自減同理
4.++i和i++在循環語句里經常用?
5-3賦值運算符
1.簡單賦值運算符
1-0 賦值語句的寫法與讀法
?1-1把常量賦值給變量
1-2把變量賦值給變量
1-3把計算結果賦值給變量?
2.復合賦值運算符
2-0.復合賦值運算符都有些什么
?2-1.復合賦值運算符的作用
2-2詳細演示
5-4關系運算符/比較運算符(別名)
?1.關系運算符都有什么?
2.實際應用舉例
2-1輸出結果顯示0或1 如果滿足該關系運算符,則輸出1,不滿足該關系運算符 輸出0
5-5邏輯運算符
1.邏輯運算符都有什么?
2.計算機與人腦是不一樣的!下方舉例說明,這也就是為什么要引進邏輯運算符的原因?
3.邏輯運算符具體情況分析?
4.短路原則
5-6逗號運算符
?1.應用1:作為分隔符使用
?補充一個坑點
?編輯?2.應用2,便于記憶變量值的互換
5-7位運算符概覽
鋪墊?1.十進制數與二進制數舉例對比
鋪墊2.如何定義一個二進制數的變量?
?鋪墊3.二進制加減法豎式運算
鋪墊4.二進制與十進制之間的轉化?
1.位運算是什么?
2.位運算符都有什么?
5-7-1位與運算符
1-1.基本原則
1-2基本原則的實際演示
2-1位與運算符應用1——判斷一個數的奇偶?
2-2位與運算符應用2——獲取任意一個二進制數的低4位?
2-3位與運算符應用3——把一個二進制數末尾連續的1變成0
?5-7-2位或運算符
?1-1基本原則
?2-1位或運算符應用1——設置標記位,即把特定位的0變成1,如果原來是1則不變
2-2位或運算符應用2——置空標記位,即把特定位的1變成0,如果原來是0則不變
2-3位或運算符應用3——低位連續的0變成1?
5-7-3異或運算符
?1-1基本原則
?1-2基本原則演示
2-1異或運算符應用1——標記位取反
?2-2異或運算符應用2——變量交換
先回顧利用逗號運算符實現變量交換
?下面利用異或運算符 優點:只需要兩個變量
?5-7-4按位取反運算符
?1-1寫法讀法
1-2利用-1巧妙解釋補碼的概念?
2-1按位取反的應用1——1的按位取反?
2-2按位取反的應用2——0的按位取反?
補充?
2-3按位取反的應用3——求一個數的相反數
?5-7-5左移運算符
?1-1基本原則
1-2基本原則的演示?
2左移的十進制含義?
3-1負數的左移?
?3-2左移負數位,也就是y位負數的情況,同時左移一個很大的數也不行,即y很大
?4-1左移運算符的應用——配合其他位運算符,對標記位進行操作
?5-7-6右移運算符
?1-1基本原則
1-2基本原則演示?
1-3右移運算符的十進制含義?
2-1負數的右移位?
2-2移負數位,是不合法的,不能用
3-1右移運算符的應用——去掉k位
前言
本套筆記是基于英雄哪里出來c語言入門到精通課程整理的筆記
包含代碼,代碼演示結果,以及便于理解的插圖
對于想要c語言入門,嵌入式c語言的入門的朋友來說,這是一套不可多得的教程
此教程分幾篇文章發布,初步計劃更新到函數,未來時間允許會繼續更新
5.運算符和表達式
5-1-1 加減乘除運算符
1.把變量進行加減乘除運算
#include <stdio.h>
int main(){int a=7, b=6;//注意兩個變量的中間用英文的逗號隔開printf("a+b=%d\n",a+b);printf("a-b=%d\n",a-b);printf("a*b=%d\n",a*b);//注意乘號在鍵盤數字8的上面printf("a/b=%d\n",a/b);return 0;
}
?
2.把常量進行加減乘除運算
#include <stdio.h>
int main(){printf("%d\n",7+6);printf("%d\n",7-6);printf("%d\n",7*6);printf("%d\n",7/6);return 0;
}
?
3.對于比較大的數(往數軸正方向或者負方向),要注意占位符的選取
4.浮點數的加減乘除?
#include <stdio.h>
int main(){double a=3.1415, b=6.21;printf("a+b=%lf\n",a+b);printf("a-b=%lf\n",a-b);printf("a*b=%lf\n",a*b);printf("a/b=%lf\n",a/b);return 0;
}
?
5-1-2取余/取模運算符
1.基本規則
#include <stdio.h>
int main(){
/*取余運算符 %
注意事項:
1.被除數和除數都必須為整數
2.取余結果的正負只由被除數決定
*/int a=100,b=9;printf("%d\n",a%b);printf("%d\n",100%9);printf("%d\n",100%-9);printf("%d\n",-100%9);printf("%d\n",-100%-9);return 0;
}
?
2.c語言中,取余與除法規則的區分
1.取余輸出結果為余數,除法輸出結果為商
2.取余只能用于兩個整數,除法可以用于整數和浮點數
3.除法結果的正負由被除數和除數共同決定,也就是和數學中一致;取余結果的正負只由被除數的正負決定
5-1-3 字符的加減法
1.基本規則和原理
#include <stdio.h>
int main(){char ch='Y';printf("%c\n",ch+1);printf("%c\n",ch-1);return 0;
}
?
2. 可以輸出一下‘X’,‘Z’對應的ASCII碼值,加以驗證?
#include <stdio.h>
int main(){char ch='Y';printf("%d\n",ch+1);printf("%d\n",ch-1);return 0;
}
3.字符加減法的應用
1.輸入小寫字母,輸出大寫字母
首先肯定有定義變量ch;并且讓我們可以在黑框輸入一個變量,也就是任意一個小寫字母
char ch;
scanf("%c\n",ch);
?接著分析小寫字母和大寫字母的聯系:
舉例分析,比如b在小寫字母表排第二位,而B在大寫字母表里也排第二位
小寫字母和大寫字母都有26個
所以可以利用排位一致的特點進行方程的構造
設小寫字母為ch(上面已經設了)
設大寫字母為y
到這里還毫無頭緒,沒法把排位的特點用上
下一步就是拆,把變量拆成常量+變量的形式,利于分析關系
任意一個大寫字母都可以寫成 'A'+一個數字
B=A+1 C=A+2.....Z=A+25
1到25其實就是大寫字母在字母表中的排位概念的變形
下一步就是小寫字母也構造出排位,方法也是拆
b=a+1 c=a+2........z=a+25
其中等號左邊是定義的變量ch
等號右邊是‘a’+x
ch='a'+x
而B=A+1 C=A+2.....Z=A+25 等號左邊是定義的變量y,等號右邊是 'A'+x
y='A'+x
下面開始寫代碼看看構造出可解的方程
?
#define _CRT_SECURE_NO_WARNINGS
#include <stdio.h>
int main() {char ch, x, y;scanf("%c", &ch);//這一步不可能馬上想出來,可以先在下面構造方程時用上變量,最后再來補充定義變量的操作x = ch - 'a';y = 'A' + x;printf("%c\n", y);return 0;
}
2.輸入大寫字母,輸出小寫字母
B=A+1 C=A+2.....Z=A+25 ch='a'+x
b=a+1 c=a+2........z=a+25 y='A'+x
按照上面的分析列方程如下
#define _CRT_SECURE_NO_WARNINGS
#include <stdio.h>
int main() {char y,x,ch; scanf("%c",&y);x=y-'A';ch='a'+x;printf("%c\n",ch);return 0;
}
5-2遞增遞減運算符
遞增遞減又叫自增自減
1.前綴自增與后綴自增含義相同的情況
#include <stdio.h>
int main(){int i=1;i++; //后綴自增printf("%d\n",i);++i;//前綴自增printf("%d\n",i);return 0;
}
?
2前綴自增和后綴自增的區別?
#include <stdio.h>
int main() {int a = 1,b = 1;int c = a++;int d = ++b;printf("c = %d , d = %d\n", c,d);printf("a = %d , b = %d\n", a,b);return 0;
}
?
你會發現d加1了,但是c沒有加一
而a和b都加一了
這是因為除了自增自減運算符以外還有賦值符的參與
一般只要沒有其他種類運算符以及賦值符號參與時,前綴和后綴自增(減)沒有區別這時候就得引出i++(后綴自增)和++i(前綴自增)的區別了
后綴自增是 先把a的數值給c用,再自增即a的數值加一(如上圖)
前綴自增是 先把b的數值加一,再把自增后的值給d(如上圖)
3.前綴自減和后綴自減同理
#include <stdio.h>
int main() {int a = 2,b = 2;int c = a--;int d = --b;printf("c = %d , d = %d\n", c,d);printf("a = %d , b = %d\n", a,b);return 0;
}
后綴自減是 先把a的數值給c用,再自減即a的數值減1(如上圖)
前綴自減是 先把b的數值減1,再把自減后的值給d(如上圖)
4.++i和i++在循環語句里經常用?
for(int i=0;i<10;++i ){}
在這里用i++和++i效果一樣,只不過++i運行效率更高一點
5-3賦值運算符
1.簡單賦值運算符
1-0 賦值語句的寫法與讀法
舉例:
寫法:a=6 ? ?從左往右; ? ? ?讀法:把常量6賦值給變量a ? ? ? ?從右往左
寫法:a=b ? ?從左往右; ? ? ?讀法:把變量b賦值給變量a ? ? ? ?從右往左
寫法:a=a+b ?從左往右; ? ? ?讀法:把a+b的計算結果賦值給變量a 從右往左
?1-1把常量賦值給變量
#include <stdio.h>
int main(){int a;a=6;//把常量6賦值給變量aprintf("%d\n",a);return 0;
}
?
1-2把變量賦值給變量
#include <stdio.h>
int main(){int a,b;a=6;b=a;//把變量a的值賦值給變量bprintf("%d\n",b);return 0;
}
?
1-3把計算結果賦值給變量?
#include <stdio.h>
int main() {int a, b;a = 6;b = a; //把變量a的值賦值給變量b b=6a = a + b; //把a+b的計算結果賦值給a a=12printf("%d\n", b);printf("%d\n", a);return 0;
}
?
2.復合賦值運算符
2-0.復合賦值運算符都有些什么
a+=b 加等于 ?a把b的值加上再輸出 等于a的新值 ? ?也就是a=a+b的意思
a-=b 減等于 ?a把b的值減掉再輸出 等于a的新值 ? ?也就是a=a-b的意思
a*=b 乘等于 ?a把b的值乘上再輸出 等于a的新值 ? ?也就是a=a*b的意思
a/=b 除等于 ?a把b的值除掉再輸出 等于a的新值 ? ?也就是a=a/b的意思
a%=b 模等于 ?a除b取模再輸出 ? ?等于a的新值 ? ?也就是a=a%b的意思
?2-1.復合賦值運算符的作用
縮短代碼的長度 增加可讀性 利于理解 特別是當變量名很長的時候
int longlonglongname =6;
longlonglongname +=6 //longlonglongname=longlonglongname+6 也就是12
2-2詳細演示
#include <stdio.h>
int main() {int a, b;a = 6;b = 6;a += b;printf("%d %d\n", a, b); //a=12 b=6a -= b;printf("%d %d\n", a, b); //a=6 b=6a *= b;printf("%d %d\n", a, b); //a=36 b=6a /= b;printf("%d %d\n", a, b); //a=6 b=6a %= b;printf("%d %d\n", a, b); //a=0 b=6 a是6除以6后得到的余數 也就是0return 0;
}
?
5-4關系運算符/比較運算符(別名)
?1.關系運算符都有什么?
a == b ?== 等于
a != b ?!= ?不等于
a > ?b ?> ?大于
a >= b ?>= ? 大于等于 即大于或者等于滿足其一即可
a <= b ?<= ? 小于等于 即小于或者等于滿足其一即可
a < ?b ?< ? ?小于
2.實際應用舉例
2-1輸出結果顯示0或1 如果滿足該關系運算符,則輸出1,不滿足該關系運算符 輸出0
#include <stdio.h>
int main() {int a = 1, b = 2;printf("a==b-->%d\n", a == b);printf("a!=b-->%d\n", a != b);printf("a >b-->%d\n", a > b);printf("a>=b-->%d\n", a >= b);printf("a <b-->%d\n", a < b);printf("a<=b-->%d\n", a <= b);return 0;
}
5-5邏輯運算符
1.邏輯運算符都有什么?
(1)邏輯與 又叫且 ??
寫法: a && b ? ? 讀法:a邏輯與上b ?
原則:只有&&兩邊條件同時滿足,打印時才輸出1?
? ? ?也就是&&兩邊都為真 才輸出1?
?????也就是&&兩邊都為1才輸出1 因為c語言中1為真 0為假
(2)邏輯或?
寫法: a||b ? ? ? 讀法:a邏輯或b
原則: 只要||兩邊條件滿足其一,打印時就輸出1
??????也就是||兩邊只要有一個為真 就輸出1
????? 也就是||兩邊只要有一個1,就輸出1?
(3)邏輯非
寫法 ? !a ? ? ? ?讀法:邏輯非a
原則:只要與a不同就輸出1,反之如果與a相同則輸出0
? ? ?!1輸出0 !0輸出1
2.計算機與人腦是不一樣的!下方舉例說明,這也就是為什么要引進邏輯運算符的原因?
因為計算機是這樣判斷的
先判斷左邊 -10<0顯然正確 為真 所以輸出1 然后1再和10比較 1<10明顯也正確 為真 所以最終輸出1
那么11也同理
先判斷左邊 -10<11 顯然正確 為真 所以輸出1 然后1在與10比較 1<10明顯也正確 為真 所以最終輸出1所以計算機和人腦是不一樣的,因此編程作為給計算機閱讀的語言需要嚴格杜絕這種情況 因此引入了邏輯運算符
3.邏輯運算符具體情況分析?
#include <stdio.h>
int main() {printf("&& %d %d %d %d\n",(1 && 1),(1 && 0),(0 && 1),(0 && 0) );printf("|| %d %d %d %d\n", (1 || 1), (1 || 0), (0 || 1), (0 || 0));printf("! %d %d\n", !0, !1);return 0;
}
?
4.短路原則
為了提高程序運行效率,在是否滿足邏輯運算符條件的判斷中
如果通過計算邏輯運算符左邊的內容就可以判斷是否滿足整個邏輯運算符的話
邏輯運算符右邊的內容電腦則不需要計算
下面舉個例子
5-6逗號運算符
?1.應用1:作為分隔符使用
#include <stdio.h>
int main() {int a = 1, b = 2, c = 3;//逗號用于分隔變量a++;++b;--c;
//如果直接輸出 a=2,b=3,c=2 這里因為自增自減均為獨立語句,
// 沒有其他運算符和賦值符號的參與,
// 所以前綴和后綴自增,前綴自減和后綴自減效果一樣
// 下面我們可以驗證一下printf("a = %d b = %d c = %d\n", a, b, c);return 0;
}
?
?當然
a++;
++b;
--c;?
寫成
a++,++b,--c;
效果一樣
?補充一個坑點
#include <stdio.h>
int main() {int a = 1, b = 2, c = 3;//逗號用于分隔變量printf("%d\n", (a++, ++b, --c));//這樣就只會輸出最后一個--c的值,也就是2return 0;
}
?2.應用2,便于記憶變量值的互換
#include <stdio.h>
int main() {int a = 1, b = 2, r;r = a;//把a的值1轉移給r 現在r=1 a=1a = b;//把b的值2轉移給a 現在a=2 b=2b = r;//把r的值1轉移給b 現在b=1 r=1printf("a = %d b = %d r = %d\n", a, b, r);return 0;
}
?
但是這樣下次在使用這種方法進行變量轉換時,容易想不起來
因此可以利用逗號運算符,寫成下面這樣
#include <stdio.h>
int main() {int a = 1, b = 2, r;r = a, a = b, b = r; //非常的對稱,容易記住printf("a = %d b = %d r = %d\n", a, b, r);return 0;
}
?
?
5-7位運算符概覽
鋪墊?1.十進制數與二進制數舉例對比
十進制數????????????二進制數
????0??????????????????0????????????????????????
????1??????????????????1????????????????????????????????
????2?????????????????10
????3?????????????????11
????4????????????????100
????5????????????????101
????6????????????????110
????7????????????????111
????8???????????????1000
????9???????????????1001
???10???????????????1010????????????????
???11 ? ? ? ? ? ????1011
???12 ? ? ? ? ? ? ? 1100
? ?13 ? ? ? ? ? ? ? 1101
? ?14 ? ? ? ? ? ? ? 1110
前14個可以簡單記憶一下,后面更大的數的十進制和二進制轉化的方法見下面
鋪墊2.如何定義一個二進制數的變量?
#include <stdio.h>
int main() {int a = 0b1110;printf("%d\n", a);return 0;
}
?
?鋪墊3.二進制加減法豎式運算
鋪墊4.二進制與十進制之間的轉化?
?
1.位運算是什么?
位運算可以理解成對二進制數字上的每個位進行操作的運算
2.位運算符都有什么?
布爾位運算符:位與& 位或\| 異或^ 按位取反~
移位位運算符:左移<< 右移>>
5-7-1位與運算符
1-1.基本原則
先介紹基本原則,看不懂沒關系,下面會有實例演示,看完你就懂了
位與運算符 & ?
寫法:a & b
讀法:a位與上b
位與基本原則: ? ? ?
0或者1,位與上1,結果還是他本身
0或者1,位與上0,結果都是0
與邏輯與聯系 ?a與b只有兩個都為1時,結果才為1,否則則為0
兩個相等的二進制數位與,結果和它們兩個數一樣 11101 & 11101 = 11101
1-2基本原則的實際演示
#include <stdio.h>
int main() {int x = 0b1010;//定義二進制數1010 其十進制數是10int y = 0b0110;//定義二進制數0110 其十進制數是6//1010(為了方便下面的計算這里高位要補0與上面的1010對齊)printf("%d\n", (x & y));//我們來列個豎式看看最終會輸出什么結果/*利用前面講的位與的基本原則 0或1,位于上1,結果都是它本身0或1,位與上0,結果都是00b1010& 0b0110----------0b0010 ——>它對應的十進制數是2 所以下面輸出結果為2*/return 0;
}
2-1位與運算符應用1——判斷一個數的奇偶?
#include <stdio.h>
int main() {printf("%d\n", (0 & 1));printf("%d\n", (2 & 1));printf("%d\n", (4 & 1));printf("%d\n", (6 & 1));printf("%d\n", (1 & 1));printf("%d\n", (3 & 1));printf("%d\n", (5 & 1));printf("%d\n", (7 & 1));return 0;
}
?
為什么偶數位與上1,都輸出0;奇數位于上1,都輸出1?
我們可以來任意拿一個偶數和奇數演示一下
6 二進制數是110 1二進制數是001(每一位對齊,那一位沒有數的,補0)
?????110
? ?& 001
?——————————
? ? ?000
你會發現因為1的二進制數的高位都用0補齊了,所有和任何偶數的高位進行位與,結果都是0
而1的二進制數的低位是1,1位與上0或者1,結果都是0或1本身 而偶數的二進制數表示的最低位永遠是0
5的二進制數是101 1二進制數是001????101
?& ?001
?—————————
? ? 001
你會發現因為1的二進制數的高位都用0補齊了,所有和任何偶奇數的高位進行位與,結果都是0
而1的二進制數的低位是1,1位與上0或者1,結果都是0或1本身 而奇數的二進制數表示的最低位永遠是1
所以記住結論:
任意一個偶數位與上1,結果都為0
任意一個奇數位與上1,結果都為1
以此可以判斷一個數的奇偶
2-2位與運算符應用2——獲取任意一個二進制數的低4位?
#include <stdio.h>
int main() {int m = 0b101010101101;//這里是隨便寫的模擬任意一個二進制數變量int k = 0B000000001111;//因為要獲取最低4位數字,所以構造二進制數1111,高位補0//根據位與運算符的基本原則,我們可以知道 (m & k)結剛好是二進制數m的低4位//所以只要我們同時輸出 (m & k)和0b1101 如果結果一樣 則證明我們這種方法是對的printf("%d %d\n", (m & k), 0b1101);return 0;
}
?
2-3位與運算符應用3——把一個二進制數末尾連續的1變成0
#include <stdio.h>
int main() {int z = 0b101101111;//任意構造一個二進制數,結尾4位是1,//來模擬一個結尾有很多1的二進制數//要想最后幾個位變成0,我們想到利用z+1進位變成0來解決這個問題// z+1=0b101110000 從低位開始進位 最后4個1全因為進位變成0,// 第7位變成1,進位完成,前面剩下的高位保持不變// z & z+1 = 0b101100000printf("%d %d\n", (z & (z + 1)), 0b101100000);//如果這兩個數一樣,則證明我們的方法正確return 0;
}
?5-7-2位或運算符
?1-1基本原則
位或 |
寫法:a|b
讀法:a位或b
基本原則:
與邏輯或聯系
只要a或者b其中一個為1,輸出結果為1
如果a和b都為0,輸出結果為0
?2-1位或運算符應用1——設置標記位,即把特定位的0變成1,如果原來是1則不變
以下設置的標記位為從低往高數第三位
#include <stdio.h>
int main() {int x = 0b1011;int y = 0b0100;/*模擬一下輸出結果0b1011| 0b0100---------0b1111*/printf("%d %d\n", (x | y), 0b1111);//如果這兩個的結果相同則證明我們的模擬正確return 0;
}
?
2-2位或運算符應用2——置空標記位,即把特定位的1變成0,如果原來是0則不變
#include <stdio.h>
int main() {int x = 0b1101;int y = 0b0100;//下面我們把從低往高數第三位進行置空,變成0//這里好像只要x-y即可,我們輸出一下printf("%d %d\n", (x - y), 0b1001);printf("%d %d\n", (x | y) - y, 0b1001);//但如果本身第三位就是0呢?這種方法顯然不具有普適性int m = 0b1001;int n = 0b0100;//所以第一步 我們先讓m與n位或 使第三位不管是0或1都變成1 m|n=0b1101//第二步位或以后再與n相減 (m|n)-n=0b1001//上面x,y我們同樣可以用此方法試驗一下printf("%d %d\n", (m | n) - n, 0b1001);return 0;
}
?
2-3位或運算符應用3——低位連續的0變成1?
#include <stdio.h>
int main() {int x = 0b11001100000;//先讓x-1把后面的0都變成1,但是第六位的1因為借位變成了0// x-1=0b11001011111//在讓x和x-1位或 // x|(x-1)=0b11001111111// 前7位x與(x-1)相同,位或了也相同 后面全部變成了1,達到了效果printf("%d %d\n", x | (x - 1), 0b11001111111);return 0;
}
?
5-7-3異或運算符
?1-1基本原則
異或 ^
寫法:a^b
讀法:a異或b
基本原則:
兩個相同的數(0和0,1和1)異或,結果都為0
兩個不同的數(0和1,1和0)異或,結果都為1
任何一個數和0異或,結果是它本身
異或滿足交換律和結合律
?1-2基本原則演示
#include <stdio.h>
int main() {
?? ?int x = 0b1010;
?? ?int y = 0b1101;
?? ?/*模擬一下
?? ??? ?0b1010
?? ??? ?0b1101
?? ?^
?? ? ? ---------
?? ? ? ?0b0111
?? ?*/
?? ?printf("%d %d\n", (x ^ y), 0b0111);
?? ?return 0;
}
?
2-1異或運算符應用1——標記位取反
#include <stdio.h>
int main() {int x = 0b1010;int y = 0b1101;//假設我們現在要讓x的從低往高數第三位取反
//可以異或上0b0100
//結果是 0b1110int a = 0b0100;printf("%d %d\n", x ^ a, 0b1110);
//我們同樣可以讓y異或上a達到從低往高數第三位取反的目的 y第三位取反0b1001printf("%d %d\n", (y ^ a), 0b1001);return 0;
}
?
?2-2異或運算符應用2——變量交換
先回顧利用逗號運算符實現變量交換
#include <stdio.h>
int main() {
//我們先來回顧一下之前講過的利用逗號運算符實現變量的交換int a = 1, b = 2,r;r = a, a = b, b = r;printf("a = %d b = %d\n", a, b);return 0;
}
?
?下面利用異或運算符 優點:只需要兩個變量
#include <stdio.h>
int main() {int x = 1, y = 2;x = x ^ y; //x1 = x ^ yy = x ^ y;// y1 = x1 ^ y = (x ^ y)^y = x^(y ^ y)= x ^ 0 = x x = x ^ y;// x = x1 ^ y1 = (x ^ y)^x=(x ^ x)^y=0^y = y//自此實現變量的交換printf("%d %d\n", x, y);return 0;
}
?
?5-7-4按位取反運算符
?1-1寫法讀法
按位取反 ~
~x 讀作對a按位取反
1-2利用-1巧妙解釋補碼的概念?
2-1按位取反的應用1——1的按位取反?
#include <stdio.h>
int main() {int a = 0b1;//1的按位取反是-2
// 00000000 00000000 00000000 00000001
//~ 11111111 11111111 11111111 11111110 -2printf("%d\n", ~a);return 0;
}
?
2-2按位取反的應用2——0的按位取反?
#include <stdio.h>
int main() {int a = 0b0;printf("%d\n", ~a);return 0;
}
補充?
?
2-3按位取反的應用3——求一個數的相反數
方法1:一個數加負號就是它的相反數
方法2:
x=0b0; ~x=11111111 11111111 11111111 11111111 也就是十進制里的-1
所以x + ~x = 11111111 11111111 11111111 11111111 ? 也就是用unsigned int里的2`32-1 也就是十進制里的-1
所以x + ~x = -1
-x=~x+1
這樣就表示出了x的相反數
?
?5-7-5左移運算符
?1-1基本原則
左移運算符 <<
x<<y 讀作 將x左移y位 其中x和y都是整數
下面是左移3位的演示
0b1110 ——> 0b1110000
1-2基本原則的演示?
2左移的十進制含義?
x<<1 ——> x*2
x<<2 ——> x*4
x<<3 ——> x*8
x<<y ——> x*2`y 2的y次
重要結論
1<<y ——> 1左移y位是2的y次
10 ——> 可以看成1左移1位 2`1=2
100 ——> 可以看成1左移2位 2`2=4
以此類推
3-1負數的左移?
?3-2左移負數位,也就是y位負數的情況,同時左移一個很大的數也不行,即y很大
這樣做和上面一樣 都是未定義行為,也就是c標準里沒有規定的行為,不合法,務必避免這樣瞎搞
?
?4-1左移運算符的應用——配合其他位運算符,對標記位進行操作
其中左移運算符用于生成標記位
我們都知道位與,位或,異或只能對固定的位進行操作
引入左移運算符,可以利用y對任意一位進行操作,只需要scanf一個y即可
具體演示見下面
下面我們來說明一下
printf("%d %d\n", x & (1 << y), 0b00100);
printf("%d %d\n", x | (1 << y), 0b10110);
printf("%d %d\n", x ^ (1 << y), 0b10010);
首先這樣寫是為了看看我們在上面注釋里演示的結果和最后輸出的結果一樣嗎?
?
?
?5-7-6右移運算符
?1-1基本原則
右移運算符 >>
a>>y 讀作:a右移y位
a=0b1110 y=2 a>>y輸出的是0b11 也就是去掉最后兩位
1-2基本原則演示?
1-3右移運算符的十進制含義?
?x>>1 --> x/2`1
?x>>2 --> x/2`2
?x>>y --> x/2`y