C語言學習第8篇---位運算子使用探究
知識來源主要是陳正衝老師的《C語言深度解剖》及Delphi Tang老師的《C語言剖析》,有興趣的朋友可以看我置頂文章獲取
很多新手都對位運算子理解的都不是很深刻,但是位運算在實際程式設計中使用的卻很普遍,因為位運算是直接對bit的操作,效率最高。
與 &
- 計算
- 取特定位
或 |
1.計算
2.要將某幾位置一,就用與這幾位是1的書進行 或
取反 ~
1.按位取反(變成二進位制取反)
異或 ^
兩個數不同時為1,否則為0
1.使特定的位翻轉,要將後七位翻轉,就與後七位是1的數異或
2.在不使用臨時變數的情況下實現倆個變數的互換
3.經常用在簡單的加密演算法上
左移 << 雙目運算子
左運算元必須為整型
char 和 short 被隱式轉換為int後進行移位操作
右運算元的範圍必須為 :【0,31】
左移運算子<<將運算子的二進位制位左移
規則:高位丟棄,低位補0
右移運算子>>把運算子的二進位制位右移
規則:高位補符號位,低位丟棄
迴圈移位:
left(unsigned value, int n) /*自定義左移函式*/
{
unsigned z;
z = (value >> (32-n)) | (value << n); /*迴圈左移的實現過程*/
return z;
}
迴圈右移
right(unsigned value, int n) /*自定義右移函式*/
{
unsigned z;
z = (value << (32-n)) | (value >> n); /*迴圈右移的實現過程*/
return z;
}
位運算
#include <stdio.h>
int main()
{
printf("%d\n", 3 << 2);
printf("%d\n", 3 >> 1);
printf("%d\n", -1 >> 1);
printf("%d\n", 0x01 << 2 + 3);
printf("%d\n", 3 << -1); // oops!
return 0;
}
小提示:
防錯的方法:
~避免位運算子,邏輯運算子和數學運算子同時出現在一個表示式中
~當位運算子,邏輯運算子合數學運算子需要同時參與運算子時,儘量使用括號()來表達計算次序
小技巧:
左移n位相當於乘以2的n次方,但效率比數學運算子高
右移n位相當於除以2的n次方,但效率比數學運算子高
實驗2:交換兩個整型變數的值
#include <stdio.h>
#define SWAP1(a, b) \
{ \
int t = a; \
a = b; \
b = t; \
}
#define SWAP2(a, b) \
{ \
a = a + b; \
b = a - b; \
a = a - b; \
}
#define SWAP3(a, b) \
{ \
a = a ^ b; \
b = a ^ b; \
a = a ^ b; \
}
int main()
{
int a = 1;
int b = 2;
printf("a = %d\n", a);
printf("b = %d\n", b);
SWAP3(a ,b);
printf("a = %d\n", a);
printf("b = %d\n", b);
return 0;
}
實驗三:混淆概念的判斷條件
#include <stdio.h>
int main()
{
int i = 0;
int j = 0;
int k = 0;
if( ++i | ++j & ++k )
{
printf("Run here...\n");
}
return 0;
}
位段
位段型別是一種特殊的結構型別,其所有成員的長度均是以二進位制位為單位定義的,結構中的成員被稱為位段。位段定義的一般形式為:
結構 結構名
{
型別 變數名1:長度;
型別 變數名2:長度;
……
型別 變數名n:長度;
}
一個位段必須被說明是int、unsigned或signed中的一種
迴圈移動例子:
#include <stdio.h>
left(unsigned value, int n) /*自定義左移函式*/
{
unsigned z;
z = (value >> (32-n)) | (value << n); /*迴圈左移的實現過程*/
return z;
}
right(unsigned value, int n) /*自定義右移函式*/
{
unsigned z;
z = (value << (32-n)) | (value >> n); /*迴圈右移的實現過程*/
return z;
}
main()
{
unsigned a;
int n;
printf("please input a number:\n");
scanf("%o", &a); /*輸入一個八進位制數*/
printf("please input the number of displacement(>0):\n");
scanf("%d", &n); /*輸入要移位的位數*/
printf("the result is %o:\n", left(a, n)); /*將左移後的結果輸出*/
printf("the result is %o:\n", right(a, n)); /*將右移後的結果輸出*/
}
運算子總結:
算數運算子:
+ - * / %(取餘數)
關係運算子
> >= < <= !=(不等於) =(等於)
邏輯運算子
! &&(並且) ||(或)
C語言對真假判斷:非零是真
零是假
&&左邊的表示式為假,右邊的肯定是不會執行的
|| 左邊的表示式為真 ,右邊的表示式肯定不會執行
賦值運算子:
= += *= /= -=
優先順序別: 算數>關係>邏輯>賦值
相關文章
- C語言學習筆記--C運算子C語言筆記
- 關於C語言的位運算子C語言
- 逍遙自在學C語言 | 位運算子的基礎用法C語言
- 逍遙自在學C語言 | 位運算子&的高階用法C語言
- 逍遙自在學C語言 | 位運算子^的高階用法C語言
- C語言運算子C語言
- C語言位運算子及常見用法C語言
- Go語言學習(7) - 運算子Go
- C語言學習筆記——位運算C語言筆記
- 逍遙自在學C語言 位運算子 "|" 的5種高階用法C語言
- 逍遙自在學C語言 | 算數運算子C語言
- 逍遙自在學C語言 | 關係運算子C語言
- 逍遙自在學C語言 | 邏輯運算子C語言
- c語言運算子詳解C語言
- 07-C語言運算子-指趣學院C語言
- C語言位運算子知識總結和例項分析C語言
- C語言位運算C語言
- 《手把手教你學C語言》學習筆記(8)--- 運算子和表示式C語言筆記
- C 語言運算子優先順序
- c語言-運算子,陣列,指標C語言陣列指標
- C語言運算子優先順序C語言
- C++位運算子C++
- Go語言運算子Go
- Go 語言運算子Go
- Solidity語言學習筆記————14、左值運算子Solid筆記
- Solidity語言學習筆記————9、左值運算子Solid筆記
- C語言運算子深度解析--超詳細C語言
- C語言學習方法,怎麼學習C語言?C語言
- Solidity語言學習筆記————8、運算子優先順序Solid筆記
- 【C進階】16、位運算子
- C# ~按位取反運算子C#
- Swift 語言的基本運算子Swift
- day_07C語言運算子及流程控制C語言
- C語言學習筆記之指標的運算C語言筆記指標
- Shell學習【運算子】
- C語言第五篇:位運算C語言
- C語言運算子優先順序列表(超詳細)C語言
- C語言常被搞錯的運算子優先順序C語言