王和平的《程序是怎樣跑起來的》學習筆記

第1章 對程序員來說,CPU意味着什麼
問題:
1程序是什麼?
2程序是有什麼組成的?
3什麼是機器語言
4正在運行的程序存儲在什麼位置?
5什麼是內存地址
6計算機的構成元件中,負責程序解釋和運行的哪一個?
答案
1指示計算機每一步動作的一組指令
2指令和數據
3CPU可以直接識別並使用的語言
4內存
5內存中,用來表示命令和數據存儲位置的數值
6CPU
1.1.CPU的內部結構解析
1.2CPU是寄存器的集合體
程序是把寄存器作爲對象來描述的
1.3決定程序流程的程序計數器
1.4條件分支和循環機制
1.5函數的調用機制
1.6通過地址和索引實現數組
1.7CPU的處理其實很簡單
第2章 數據是用二進制數表示的
問題
1 32位是幾個字節
2二進制數01011100轉成十進制數是幾?
3二進制數00001111左移兩位後,會變成原數的幾倍?
4補碼形式表示的8位二進制數11111111,用十進制數表示的話是多少?
5補碼形式表示的8位二進制數10101010,用十六位的二進制數表示的話是多少?
6反轉部分圖形模型時,使用的是什麼邏輯運算?
答案
1 4字節
2 92
3 4倍
4 -1
5 1111111110101010
6 XOR
2.1用二進制數表示計算機的原因
2.2什麼是二進制數
2.3移位運算和乘除運算的關係
2.4便於計算機處理的“補數”
2.5邏輯右移和算數右移的區別
2.6掌握邏輯運算的竅門
第3章 計算機進行小數運算時出錯的原因
問題
1二進制數0.1,用十進制數是多少?
2用小數點後的3位的二進制數,能表示0.625嗎?
3將小數分爲符號、尾數、基數、指數4個部分進行表現的形式成爲什麼?
4二進制數的基數是什麼?
5通過把0作爲數值範圍的中間值,從而在不使用符號位的情況下來表示負數的表示方法成爲什麼?
6 10101100.01010011這個二進制數,用十六進制數字表示的話是什麼?
答案
1 0.5
2能
3浮點數
4 2
5EXCESS系統表現
6AC.53

3.1將0.1累加100次也得不到10
3.2用二進制數表示小數
3.3計算機運算出錯的原因
3.4什麼是浮點數
3.5正則表達式和EXCESS系統
3.6在實際的程序中進行確認
3.7如何避免計算機計算出錯
3.8二進制數和十六進制數

4熟練使用有棱有角的內存
問題
1有十個地址引號引腳的內存IC可以指定的地址範圍是多少?
2高級編程語言中的數據類型表示的什麼?
3在32位內存地址環境中,指針變量的長度是多少位?
4與物理內存有着相同構造的數組的數據類型長度是多少?
5用後進先出方式進行數據讀寫的數據結構稱爲什麼?
6根據數據的大小鏈表分叉成兩個方向的數據結構稱爲什麼?
答案
1 00000000001111111111(相當於十進制數01023)
2佔據內存區域大小和存儲在該內存區域的數據類型
3 32位
4 1字節
5棧
6二叉樹

4.1內存的物理機制很簡單
4.2內存的邏輯模型是樓房
4.3簡單的指針
4.4數組是高效使用內存的基礎
4.5棧、隊列以及環形緩衝區
4.6鏈表使元素的追加和刪除更容易
4.7二叉樹使數據搜索更有效

第5章 內存和磁盤的親密關係
問題
1存儲程序方式指的是什麼?
2通過使用內存來提高磁盤訪問速度的機制稱爲什麼?
3把磁盤的一部分作爲假想內存來使用的機制是什麼?
4windows中,在程序運行時,存儲着可以動態加載調用的函數和數據的文件稱爲什麼?
5在EXE程序文件中,靜態加載函數的方式稱爲什麼?
6在windows計算機中,一般磁盤的一個扇區是多少字節?
答案
1在存儲裝置中保存程序,並逐一運行的方式
2磁盤緩存
3虛擬內存
4DLL文件
5靜態鏈接
6 512字節

5.1不讀入內存就無法運行
5.2磁盤緩存加快了磁盤訪問速度
5.3虛擬內存把磁盤作爲部分內存來使用
5.4節約內存的編程方法
(1)通過DLL文件實現函數共有
(2)通過調用_stdcall來減少程序文件的大小
5.5磁盤的物理結構

第6章 親自嘗試壓縮數據
問題
1文件存儲的基本單位是什麼?
2DOC\LZH\TXT這些擴展名中,哪一個是壓縮文件的擴展名?
3文件內容用“數據的值*循環次數”來表示的壓縮方法是RLE算法還是哈夫曼算法
4在windows計算機經常使用shift jis字符編碼中,1個半角英數是用幾個字節的數據來表示的?
5位圖格式的圖像,是壓縮過的嗎?
6可逆壓縮和不可逆壓縮不同之處是什麼?
答案
1 1個字節(8位)
2LZH
3RLE算法
4 1個字節(8位)
5沒有壓縮過
6壓縮過的數據能復原的是可逆壓縮,不能復原的是不可逆壓縮
6.1文件以字節爲單位保存
6.2RLE算法
6.3RLE算法的缺點
6.4通過摩爾斯編碼來看哈夫曼算法的基礎
6.5用二叉樹實現哈夫曼編碼
6.6哈夫曼算法能夠大幅度提升壓縮比率
6.7可逆壓縮與不可逆壓縮

第7章 程序是在何種環境下運行
問題
1應用的運行環境,指的是什麼?
2macintosh用的操作系統macOS,在AT兼容機上能運行嗎?
3windows上的應用,在macOS上能運行嗎?
4FreeBSD提供的ports,指的是什麼?
5在macintosh上可以利用的windows環境模擬器稱爲什麼?
6java虛擬機的功能是什麼?
答案
1操作系統和計算機硬件本身的種類
2無法運行
3無法運行
4通過使用源代碼來提供應用,並根據運行環境進行整合編譯,從而得以在該環境下運行的機制
5virtual PC for mac
6運行JAVA應用的字節代碼

7.1運行環境=操作系統+硬件
7.2windows克服了CPU以外的硬件差異
7.3不同操作系統的API不同
7.4freebsd port幫你輕鬆使用源代碼
7.5利用虛擬機獲得其他操作系統環境
7.6提供相同運行環境的JAVA虛擬機
7.7BIOS和引導

第8章 從源文件到可執行文件
問題
1CPU可以解析和運行的程序形式稱爲什麼代碼?
2將多個目標文件結合生成EXE文件的工具稱爲什麼?
3擴展名爲.obj的目標文件內容,是源代碼還是本地代碼?
4把多個目標文件收錄在一起的文件稱爲什麼?
5僅包含windows的DLL文件中存儲的函數信息的文件稱爲什麼?
6程序運行時,用來動態申請分配的數據和對象的內存區域形式稱爲什麼?
答案
1本地代碼(機器語言代碼)
2鏈接器
3本地代碼
4庫文件
5導入庫
6堆

8.1計算機只能運行本地代碼
8.2本地代碼的內容
8.3編譯器負責轉換源代碼
8.4僅僅靠編譯器是無法得到可執行文件的
8.5啓動以及庫文件
8.6DLL文件以及導入庫
8.7可執行文件的必要條件
8.8程序加載時會生成堆棧
8.9有點難度的Q&A

第9章 操作系統和應用的關係
問題
1監控程序的主要功能是什麼?
2在操作系統上運行的程序稱爲什麼?
3調用操作系統功能稱爲什麼?
4windows vista是多少位的操作系統?
5GUI是什麼的縮寫?
6WYSIWYG是什麼的縮寫?
答案
1程序的加載和運行
2應用或者應用程序
3系統調用
4 32位(也有64位的)
5 graphic user interface
6 what you see is what you get

9.1操作系統功能的歷史
9.2要意識到操作系統的存在
9.3系統調用和高級編程語言的移植性
9.4操作系統和高級編程語言使硬件抽象化
9.5windows操作系統的特徵
(1)32位操作系統
(2)通過API函數集來提供系統調用
(3)提供採用了GUI的用戶界面
(4)通過wysiwyg實現打印輸出
(5)提供多功能任務
(6)提供網絡功能以及數據庫功能
(7)通過即插即用實現設備驅動的自動設定
第10章 通過彙編語言瞭解程序的實際構成
問題
1本地代碼的指令中,表示其功能的英語縮寫稱爲什麼?
2彙編語言的源代碼轉換成本地代碼的方式稱爲什麼?
3本地代碼轉換成彙編語言的源代碼的方式稱爲什麼?
4彙編語言的源文件的擴展名,通常是什麼格式?
5彙編語言程序中的段定義指的是什麼?
6彙編語言的跳轉指令,是在何種情況下使用的?
答案
1助記符
2彙編
3反彙編
4.asm
5構成程序的命令和數據的集合組
6將程序流程跳轉到其他地址時需要用到該指令

10.1彙編語言和本地代碼是一一對應的
10.2通過編譯器輸出彙編語言的源代碼
代碼清單10-1

int AddNum(int a,int b)
{
return a+b;
}
void MyFunc()
{
int c;
c=AddNum(123,456);
}

代碼清單10-2

_TEXT segment dword public use32 'CODE'
_TEXT ends
_DATA segment dword public use32 'DATA'
_DATA ends
_BSS  segment dword public use32 'BSS'
_BSS  ends
Dgroup group _BSS,_DATA
_TEXT segment dword public use32 'CODE'
_AddNum proc near
push ebp
mov  ebp,esp
mov  eax,dword ptr[ebp+8]
add  eax,dword ptr[ebp+12]
pop  ebp
ret
_AddNum  endp
_MyFunc   proc near
push ebp
mov  ebp,esp
push  456
push  123
call  _AddNum
add  esp,8
pop  ebp
ret
_MyFunc  endp
_TEXT  ends
       end

10.3不會轉換成本地代碼的僞指令
代碼清單10-3

_TEXT segment dword public use32 'CODE'
_TEXT ends
_DATA segment dword public use32 'DATA'
_DATA ends
_BSS  segment dword public use32 'BSS'
_BSS  ends
Dgroup group _BSS,_DATA
_TEXT segment dword public use32 'CODE'
_AddNum proc near
push ebp
mov  ebp,esp
mov  eax,dword ptr[ebp+8]
add  eax,dword ptr[ebp+12]
pop  ebp
ret
_AddNum  endp
_MyFunc   proc near
push ebp
mov  ebp,esp
push  456
push  123
call  _AddNum
add  esp,8
pop  ebp
ret
_MyFunc  endp
_TEXT  ends
       end

10.4彙編語言的語法是“操作碼+操作數”
10.5最常用的mov指令
10.6對棧進行push和pop
10.7函數調用機制
代碼清單10-4

_MyFunc proc near
push  ebp
mov   ebp,esp
push  456
push  123
call  _AddNum
add   ebp,8
pop   ebp
ret 
_MyFunc endp

10.8函數的內部處理
代碼清單10-5

_AddNum  proc near
push  ebp
mov   ebp,esp
mov   eax,dword ptr[ebp+8]
add   eax,dword ptr[ebp+12]
pop   ebp
ret
_AddNum  endp

10.9始終確保全局變量用的內存空間
代碼清單10-6

int a1=1;
int a2=2;
int a3=3;
int a4=4;
int a5=5;
int b1,b2,b3,b4,b5;
void MyFunc()
{
int c1,c2,c3,c4,c5,c6,c7,c8,c9,c10;
c1=1;
c2=2;
c3=3;
c4=4;
c5=5;
c6=6;
c7=7;
c8=8;
c9=9;
c10=10;
a1=c1;
a2=c2;
a3=c3;
a4=c4;
a5=c5;
b1=c6;
b2=c7;
b3=c8;
b4=c9;
b5=c10;
}

代碼清單10-7

_DATA segment dword public use32 'DATA'
_a1   label  dword 
      dd     1
_a2   label  dword 
      dd     2
_a3   label  dword 
      dd     3
_a4   label  dword 
      dd     4
_a5   label  dword 
      dd     5
_DATA ends
_BSS segment dword public use32 'BSS'
_b1   label  dword 
      db     4dup(?)
_b2   label  dword 
      db     4dup(?)
_b3   label  dword 
      db     4dup(?)
_b4   label  dword 
      db     4dup(?)
_b5   label  dword 
      db     4dup(?)
_BSS ends
_DATA segment dword public use32 'CODE'
_MyFunc  proc  near
push   ebp
mov    ebp,esp
add    esp,-20
push   ebx
push   esi
mov    eax,1
mov    ebx,2
mov    ecx,3
mov    edx,4
mov    esi,5
mov    dword ptr[ebp-4],6
mov    dword ptr[ebp-8],7
mov    dword ptr[ebp-12],8
mov    dword ptr[ebp-16],9
mov    dword ptr[ebp-20],10
mov    dword ptr[_a1],eax
mov    dword ptr[_a2],ebx
mov    dword ptr[_a3],ecx
mov    dword ptr[_a4],edx
mov    dword ptr[_a5],esi
mov    eax,dword ptr[ebp-4]
mov    dword ptr[_b1],eax
mov    ebx,dword ptr[ebp-8]
mov    dword ptr[_b2],ebx
mov    ecx,dword ptr[ebp-12]
mov    dword ptr[_b3],ecx
mov    edx,dword ptr[ebp-16]
mov    dword ptr[_b4],edx
mov    esi,dword ptr[ebp-20]
mov    dword ptr[_b5],esi
pop    esi
pop    ebx
mov    esp,ebp
pop    ebp
ret
_MyFunc  endp
_DATA ends

10.10臨時確保局部變量用的內存空間
10.11循環處理的實現方法
代碼清單10-8

void MySub
{
}
void MyFunc()
{
int i;
for(i=0;i<10;i++)
{
   MySub();
}
}

代碼清單10-9

xor  ebx,ebx
@4 call _MySub
inc ebx
cmp ebx,10
jl  short @4
代碼清單10-10
i^=i;
L4:MySub();
i++;
if(i<10) goto  L4;

10.12條件分支的實現方法
代碼清單10-11

void  MySub1()
{

}
void  MySub2()
{

}
void  MySub3()
{

}
void MyFunc()
{
	int a=123;
	if(a>100){MySub1();}
	else if(a>50){MySub2();}
	else{MySub3();}
}
代碼清單10-12
_MyFunc  proc  near
push  ebp
mov   ebp,esp
mov   eax,123
cmp   eax,100
jle   short @8
call  _MySub1
jmp   short @11
@8:cmp  eax,50
   jge short @10
   call _MySub2
   jmp short @11
@10:call _MySub3
@11:pop ebp
    ret
_MyFunc  endp

10.13瞭解程序運行方式的必要性
代碼清單10-13

int counter=100;
void MyFunc1()
{
counter=counter*2;
}
void MyFunc2()
{
counter=counter*2;
}

代碼清單10-14

mov eax,dwrod ptr[_counter]
add eax,ead
mov dword ptr[_counter],eax

第11章 硬件控制方法
問題
1在彙編語言中,使用什麼指令來同外圍設備進行輸入輸出操作的?
2IO是什麼的縮寫
3用來識別外部識別的編號稱爲什麼?
4IRQ是什麼的縮寫?
5DMA是什麼的縮寫
6用來識別具有DMA功能的外圍設備的編號成爲什麼?

答案
1IN指令和OUT指令
2input/output
3IO地址或者IO端口號
4interrupt request
5direct memory access
6DMA通道

11.1應用和硬件無關?
11.2支撐硬件輸入輸出的IN指令和OUT指令
11.3編寫測試用的輸入輸出程序
11.4外圍設備的中斷請求
11.5用中斷來實現實時處理
11.6DMA可以實現短時間內傳送大量數據
11.7文字以及圖片的顯示機制

第12章 讓計算機“思考”
問題
1用計算機進行模擬實驗稱爲什麼?
2僞隨機數指的是什麼?
3隨機數的種子是什麼?
4計算機有思考功能嗎?
5計算機有記憶功能嗎?
6AI是什麼的縮寫

答案
1計算機模擬
2通過公式產生的僞隨機數
3生成僞隨機數的公式中使用的參數
4沒有
5有
6人工智能

12.1作爲“工具”的程序和爲了“思考”的程序
12.2用程序來表示人類的思考的方式
代碼清單12-1

#include <stdio.h>
#include <stdlib.h>

void Main
{
int computer;

printf("石頭剪刀。。。。。。");
getchar();
printf("布!\n");

srand(time(NULL));
computer=rand()%3;

if(computer==0)
{
	printf("計算機的出拳是:石頭\n");
}else if(computer==1)
{
	printf("計算機的出拳是:剪刀\n");
}
else
{
	printf("計算機的出拳是:布\n");
}
}

12.3用程序來表示人類的思考習慣
代碼清單12-2

#include <stdio.h>
#include <stdlib.h>

void Main
{
int computer;

printf("石頭剪刀。。。。。。");
getchar();
printf("布!\n");

srand(time(NULL));
computer=rand()%10;

if(computer>=0&&computer<=4)
{
	printf("計算機的出拳是:石頭\n");
}else if(computer>=5&&computer<=7)
{
	printf("計算機的出拳是:剪刀\n");
}
else
{
	printf("計算機的出拳是:布\n");
}
}

12.4程序生成隨機數的方法
12.5活用記憶功能以達到更接近人類的判斷
代碼清單12-3

#include <stdio.h>
#include <stdlib.h>
void Main()
{
int human;
int prev=0;
int memory[][]={{0,0,0},{0,0,0},{0,0,0}};
int max;
int counter=0;
int computer;
srand(time(NULL));
while(-1)
{
	printf("石頭剪刀(0=石頭,1=剪刀,2=布,其他=退出遊戲)。。。");
	scanf("%d",&human);
	printf("布\n");

	if(human<0&&human>2){break;}

	counter++;

	if(counter<10)
	{
		computer=rand()%3;
	}else
	{
		max=0;
		if(memory[prev][max]<memory[prev][1]){max=1;}
		if(memory[prev][max]<memory[prev][2]){max=2;}
		computer =(max+2)%3;
	}

	if(computer==0)
	{
		printf("計算機的出拳是:石頭\n");
	}else if(computer==1)
	{
		printf("計算機的出拳是:剪刀\n");
	}
	else
	{
		printf("計算機的出拳是:布\n");
	}
	printf("\n");

	memory[prev][human]++;
	prev=human;

}
}

12.6用程序來表示人類的思考方式
代碼清單12-4

#include <stdio.h>
#include <stdlib.h>
void Main()
{
int pattern[2][4]={{0,0,2,1},{1,0,0,2}};
int lose=0;
int p=0;
int n=0;
int human;
int computer;
srand(time(NULL));
while(-1)
{
	printf("石頭剪刀(0=石頭,1=剪刀,2=布,其他=退出遊戲)。。。");
	scanf("%d",&human);
	printf("布\n");

	if(human<0&&human>2){break;}

	computer=patter[p][n];
	n=(n+1)%4;

	if(computer==0)
	{
		printf("計算機的出拳是:石頭\n");
	}else if(computer==1)
	{
		printf("計算機的出拳是:剪刀\n");
	}
	else
	{
		printf("計算機的出拳是:布\n");
	}
	printf("\n");

	if(
	(human==0&&computer==1)
	||(human==1&&computer==2)
	||(human==2&&computer==3)
	)
	{
		lose++;
	}else{losee=0;}

	if(lose>2){
		p=(p+1)%2;
		n=0;
	}

}
}

附錄 讓我們開始C語言之旅
C語言的特點
變量和函數
數據類型
代碼清單A-1

int a;
a=123;

標準函數庫
代碼清單A-2

int a,b,ave;
scanf("%d",&a);
scanf("%d",&b);
ave=(a+b)/2;
printf("%d",&ave);

函數調用
代碼清單A-3

#include <stdio.h>

void Main(void)
{
int a,b,ave;
scanf("%d",&a);
scanf("%d",&b);
ave=(a+b)/2;
printf("%d",&ave);
}

代碼清單A-4

#include <stdio.h>

int average(int ,int);

void Main(void)
{
int a,b,ave;
scanf("%d",&a);
scanf("%d",&b);
ave=average(a,b);
printf("%d",&ave);
}

int average(int a, int b){
 return  (a+b)/2;
}

局部變量和全局變量
代碼清單A-5

#include <stdio.h>

int average(void);
int a,b;

void Main(void)
{
int a,b,ave;
scanf("%d",&a);
scanf("%d",&b);
ave=average();
printf("%d",&ave);
}

int average(void){
 return  (a+b)/2;
}

數組和循環

#include <stdio.h>

void Main(void)
{
	int data[10];
	int sum,ave,i;
	sum=0;
	for(i=0;i<10;i++)
	{
		scanf("%d",&data[i]);
		sum+=data[i];
	}

	ave=sum/10;
	printf("%d",&ave);
}

其他語法結構

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章