版權(quán)聲明:本文為 gfson
原創(chuàng)文章概疆,轉(zhuǎn)載請注明出處。
注:作者水平有限惨缆,文中如有不恰當(dāng)之處,請予以指正丰捷,萬分感謝坯墨。
1. 進(jìn)制間兩個轉(zhuǎn)化技巧
P62.png
2. int32_t 和 int64_t
P64-1.png
3. 多種形式的聲明
P64-2.png
4. C 語言數(shù)據(jù)類型分配字節(jié)數(shù)
P63.png
5. 大端和小端
P65.png
6. 不同程序?qū)ο蟮淖止?jié)表示
#include <stdio.h>
typedef unsigned char *byte_pointer;
void show_bytes(byte_pointer start, size_t len){
size_t i;
for(i=0;i<len;i++)
printf(" %.2x",start[i]);
printf("\n");
}
void show_int(int x){
show_bytes((byte_pointer) &x, sizeof(int));
}
void show_float(float x){
show_bytes((byte_pointer) &x, sizeof(float));
}
void show_pointer(void *x){
show_bytes((byte_pointer) &x, sizeof(void *));
}
void test_show_bytes(int val){
int ival = val;
float fval = (float) ival;
int *pval = &ival;
show_int(ival);
show_float(fval);
show_pointer(pval);
}
int main(void){
int a = 10;
test_show_bytes(a);
return 0;
}
運(yùn)行結(jié)果如下:
swd1@user-HP-ProDesk-600-G1-TWR:/local/work/test/C$ gcc test.c
swd1@user-HP-ProDesk-600-G1-TWR:/local/work/test/C$ ./a.out
0a 00 00 00
00 00 20 41
40 cb 10 b2 ff 7f 00 00
swd1@user-HP-ProDesk-600-G1-TWR:/local/work/test/C$
從以上結(jié)果可以得出兩個結(jié)論:
- Linux 64 位操作系統(tǒng)使用的是小端法存儲。
- Linux 64 位操作系統(tǒng)的 int 和 float 類型占 4 個字節(jié)病往,指針類型占 8 個字節(jié)捣染。
7. 生成一張 ASCII 表
通過命令 man ascii
生成一張 ASCII 表。
8. 字符串表示
P70.png
9. 布爾環(huán) a^a = 0
P72-1.png
10. 位向量表示有限集合
P72-2.png
- 位向量就是固定長度為 ω停巷,由 0 和1 組成的串耍攘。
- a = [011010101]榕栏,從右往左數(shù),從 0 開始蕾各,第 i 位的數(shù)字是 1扒磁,則 i 為集合的元素。
- 這種位向量表示的集合示损,布爾運(yùn)算 | 和 & 分別對應(yīng)集合的并和交渗磅,而 ~ 對應(yīng)與集合的補(bǔ)。
11. 交換兩個變量的值
P74.png
兩個練習(xí)題的答案如下:
P135.png
函數(shù) inplace_swap(int *x, int *y) 隱含要求 x 和 y 指向不同的地址检访,可以對此函數(shù)進(jìn)行如下修改:
void inplace_swap(int *x, int *y){
if(x != y){
*y = *x ^ *y;
*x = *x ^ *y;
*y = *x ^ *y;
}
}
12. 位運(yùn)算兩個有趣的問題和一些結(jié)論
首先上一張布爾代數(shù)運(yùn)算的圖。
P71.png
然后再來看看下面兩個有趣的問題(練習(xí)題 2.12 和 2.13):
P75-1.png
思考過這個兩個問題后仔掸,我們來看看答案:
P136.png
我們會發(fā)現(xiàn)幾個有趣的結(jié)論:
- 基礎(chǔ)結(jié)論:
- 0 & 0 = 0; 1 & 0 = 0; 即任意位和 0 與為 0脆贵。
- 0 & 1 = 0; 1 & 1 = 1; 即任意位和 1 與為其本身。
- 0 | 1 = 1; 1 | 1 = 1; 即任意位和 1 或為 1起暮。
- 0 | 0 = 0; 1 | 0 = 1; 即任意位和 0 或為其本身卖氨。
- 0 ^ 0 = 0; 1 ^ 0 = 1; 即任意位和 0 異或為其本身。
- 0 ^ 1 = 1; 1 ^ 1 = 0; 即任意位和 1 異或為其取反负懦。
- 練習(xí)題 2.12 的帶來的思考:
- 如果想要字節(jié)位為 0筒捺,可以考慮
& 0
。 - 如果想要字節(jié)位為 1纸厉,可以考慮
| 1
系吭。 - 如果想要字節(jié)位取反,可以考慮
^ 1
颗品。 - 如果想要字節(jié)位保持不變肯尺,可以考慮
& 1
、| 0
躯枢、^ 0
则吟。
- 練習(xí)題 2.13 帶來的思考:
通過文氏圖證明 x ^ y = (x & ~y) | (~x & y) 如下:
-
x ^ y 用文氏圖表示如下:
x^y.png -
~x 用文氏圖表示如下:
~x.png -
(~x & y) 用文氏圖表示如下:
~x & y.png - 同理,(x & ~y) 的文氏圖為左半邊锄蹂,(x & ~y) | (~x & y) 的文氏圖與 x ^ y 的文氏圖相同氓仲。
13. C 語言的邏輯運(yùn)算
P75-2.png
P76-1.png
- 邏輯運(yùn)算中非零的參賽都表示 TRUE,參數(shù) 0 表示 FALSE得糜。
- 邏輯運(yùn)算返回 1 或者 0敬扛,1 表示 TRUE,0 表示 FALSE掀亩。
- 如果第一個參數(shù)的值可以確定整個表達(dá)式的值舔哪,那么不會計算第二個參數(shù)的值。
14. 易混淆 ~ 和 槽棍!
x = 0x66, y = 0x39.
求 x & !y 和 x && ~y 的值捉蚤。
上述問題中抬驴,需要注意 ! 是邏輯運(yùn)算中的非缆巧,~ 是位運(yùn)算中的取反布持。
x & !y = 0x00, x && ~y = 0x01.
15. 移位運(yùn)算
P76-2.png
P77.png
-
邏輯右移和算術(shù)右移
- 邏輯右移:在左端補(bǔ) k 個 0。
- 算術(shù)右移:在左端補(bǔ) k 個最高有效位的值陕悬。
幾乎所有編譯器 / 機(jī)器組合都對有符號數(shù)使用算術(shù)右移题暖,對于無符號數(shù),必須使用邏輯右移捉超。
Java 中
>>
表示算法右移胧卤,>>>
表示邏輯右移。當(dāng)移動的位 k 大于 w 時拼岳,實際位移量通過計算 k mod w 得到枝誊。