文章目錄
1.?大小端模式
2.?大端模式(Big-endian)
3. 小端模式(Little Endian)
4. 判斷和轉換大小端模式
5.?位操作
5.1?移位操作
5.2?取反操作
5.3?位與操作
5.4?位或操作
5.5?置位操作
5.6?清位操作
1.?大小端模式
大小端模式(Endianness)是指計算機系統中多字節數據的存儲方式。不同的計算機系統可能采用不同的大小端模式來存儲數據,這會影響到數據在內存中的排列順序。
大小端模式的影響
-
數據交換: 在不同大小端模式的系統之間交換數據時,數據的解釋方式會有所不同。如果不進行適當的轉換,可能導致數據的錯誤解讀。例如,一個32位整數在大端系統中為0x12345678,在小端系統中可能被解釋為0x78563412。
-
文件格式: 某些文件格式在設計時會指定采用某種字節序。例如,網絡協議通常使用大端模式,也稱為"網絡字節序"(Network Byte Order)。在解析這些文件或網絡數據時,需要注意字節序的轉換。
-
嵌入式系統: 在嵌入式系統開發中,嵌入式設備可能使用不同的處理器架構,不同架構可能采用不同的字節序。在與外設進行數據通信時,必須確保雙方使用一致的字節序。
2.?大端模式(Big-endian)
大端模式是指數據的高字節存儲在內存的低地址中,而數據的低字節存儲在內存的高地址中。這種存儲方式符合我們書寫數字的習慣,即從高位到低位,從左到右存儲。
例如,對于32位整數0x12345678:
- 高字節(0x12)存儲在低地址處
- 低字節(0x78)存儲在高地址處
地址 | 數據 |
---|---|
0x1000 | 0x12 |
0x1001 | 0x34 |
0x1002 | 0x56 |
0x1003 | 0x78 |
?
3. 小端模式(Little Endian)
小端模式是指數據的高字節存儲在內存的高地址中,而數據的低字節存儲在內存的低地址中。這種存儲方式與大端模式相反。
例如,對于32位整數0x12345678:
- 低字節(0x78)存儲在低地址處
- 高字節(0x12)存儲在高地址處
地址 | 數據 |
---|---|
0x1000 | 0x78 |
0x1001 | 0x56 |
0x1002 | 0x34 |
0x1003 | 0x12 |
4. 判斷和轉換大小端模式
可以通過C語言代碼來判斷當前系統的大小端模式:
這段代碼通過檢查整數的最低字節是否存儲在最低地址來判斷系統的字節序。
#include <stdio.h>int main() {unsigned int x = 0x12345678;char *c = (char*)&x;if (*c == 0x78) {printf("Little Endian\n");} else {printf("Big Endian\n");}return 0;
}
大小端模式轉換
如果需要在大小端模式之間進行轉換,可以使用如下方法:
這段代碼實現了32位整數的字節順序交換,可以用于大小端模式的轉換。
#include <stdio.h>
#include <stdint.h>// 交換字節順序
uint32_t swap_endian(uint32_t val) {return ((val >> 24) & 0xff) | // 移動最高字節到最低字節((val << 8) & 0xff0000) | // 移動次高字節到次低字節((val >> 8) & 0xff00) | // 移動次低字節到次高字節((val << 24) & 0xff000000); // 移動最低字節到最高字節
}int main() {uint32_t original = 0x12345678;uint32_t swapped = swap_endian(original);printf("Original: 0x%x\n", original);printf("Swapped: 0x%x\n", swapped);return 0;
}
5.?位操作
位操作是計算機中對二進制位進行直接操作的技術。在編程中,位操作能夠高效地處理數據,通過操作特定位的值來實現一些特定的功能。位操作符直接對整數的二進制表示進行操作,因此通常比其他操作符快。
5.1?移位操作
移位操作通過移動一個數的二進制表示來實現乘法、除法、數據的快速處理等功能。移位操作分為左移和右移兩種,分別用左移操作符(<<
)和右移操作符(>>
)表示。
示例代碼
int a = 0x6; // 二進制是 0b0110
int b = a << 1; //左移操作
int c = a >> 1; //右移操作
左移操作符 <<
將操作數的二進制表示向左移動指定的位數,右邊補0。
a
的二進制表示:0110
- 左移一位:
0110
→1100
- 轉換為十六進制:
1100
→0xC
所以,b
的值為 0xC
。
右移操作符 >>
將操作數的二進制表示向右移動指定的位數,對于有符號整數,左邊根據符號位補0或1,對于無符號整數,左邊補0。
a
的二進制表示:0110
- 右移一位:
0110
→0011
- 轉換為十六進制:
0011
→0x3
所以,c
的值為 0x3
。
5.2?取反操作
取反操作是一種位操作,用來將一個數的二進制表示中的每一位取反,即把 0
變成 1
,把 1
變成 0
。在C語言中,取反操作使用 ~
符號。
示例代碼
int a = 0x6; // 二進制是 0b0110
int b = ~a;
取反操作符 ~
將操作數的二進制表示中的每一位取反。
a
的二進制表示:0110
- 取反后:
0110
→1001
- 轉換為十六進制:
1001
→0x9
所以,b
的值為 0x9
。
5.3?位與操作
位與操作是一種位操作,用來將兩個數的二進制表示中對應位置的位進行與運算。只有對應的兩個二進制位都為 1
時,結果位才為 1
,否則結果位為 0
。在 C 語言中,位與操作使用 &
符號。
示例代碼
int a = 0x6; // 二進制是 0b0110
int b = 0x7; // 二進制是 0b0111
int c = a & b;
位與操作符 &
將操作數的二進制表示中的每一位進行與運算。
a
的二進制表示:0110
b
的二進制表示:0111
- 位與結果:
0110
運算如下:
- 第1位:0 & 0 = 0
- 第2位:1 & 1 = 1
- 第3位:1 & 1 = 1
- 第4位:0 & 1 = 0
所以,結果 c
的值為 0x6
(十六進制),即 0b0110
。
5.4?位或操作
位或操作是一種位操作,用來將兩個數的二進制表示中對應位置的位進行或運算。只要對應的兩個二進制位中有一個為 1
,結果位就為 1
,否則結果位為 0
。在 C 語言中,位或操作使用 |
符號。
int a = 0x6; // 二進制是 0b0110
int b = 0x7; // 二進制是 0b0111
int c = a | b;
位或操作符 |
將操作數的二進制表示中的每一位進行或運算。
a
的二進制表示:0110
b
的二進制表示:0111
- 位或結果:
0111
運算如下:
- 第1位:0 | 0 = 0
- 第2位:1 | 1 = 1
- 第3位:1 | 1 = 1
- 第4位:0 | 1 = 1
所以,結果 c
的值為 0x7
(十六進制),即 0b0111
。
5.5?置位操作
置位操作是一種常見的位操作,用來將某個變量的特定位設置為 1
。在 C 語言中,可以使用位或運算符 |
和左移操作符 <<
來實現置位操作。
int a = 0x6; // 二進制是 0b0110
int a |= (1<<3);
這行代碼使用了位或運算符 |
和左移操作符 <<
來實現置位操作。
1<<3
:將1
左移 3 位,結果是0b1000
(二進制),即十六進制的0x8
。a |= 0b1000
:將a
和0b1000
進行位或運算。
計算過程:
a
的二進制表示:0110
1<<3
的二進制表示:1000
- 位或結果:
1110
運算如下:
- 第1位:0 | 0 = 0
- 第2位:1 | 0 = 1
- 第3位:1 | 0 = 1
- 第4位:0 | 1 = 1
所以,結果 a
的值為 0xE
(十六進制),即 0b1110
。
5.6?清位操作
清位操作是將某個變量的特定位清零的一種操作。通過使用位與運算符 &
和按位取反操作符 ~
可以實現清位操作。
int a = 0x6; // 二進制是 0b0110
int a &= ~(1<<2);
這行代碼使用了位與運算符 &
和按位取反操作符 ~
來實現清位操作。
1<<2
:將1
左移 2 位,結果是0b0100
(二進制),即十六進制的0x4
。~(1<<2)
:對0b0100
進行按位取反,結果是0b1011
。a &= 0b1011
:將a
和0b1011
進行位與運算。
計算過程:
a
的二進制表示:0110
~(1<<2)
的二進制表示:1011
- 位與結果:
0010
運算如下:
- 第1位:0 & 1 = 0
- 第2位:1 & 0 = 0
- 第3位:1 & 1 = 1
- 第4位:0 & 1 = 0
所以,結果 a
的值為 0x2
(十六進制),即 0b0010
。