第一篇:期末復習-語言各章總結(jié)
匯編語言學習筆記 《匯編語言》--王爽 前言
學習匯編目的:充分獲得底層編程體驗;深刻理解機器運行程序的機理。原則:沒有通過監(jiān)測點不要向下學習;沒有完成當前實驗不要向下學習。第一章 基礎知識
有三類指令組成匯編語言:匯編指令;偽指令;其他符號。8bit = 1byte = 一個存儲單元有n根地址線,則可以尋址2的n次方個內(nèi)存單元。1.1節(jié)--1.10節(jié) 小結(jié)
(1)匯編指令是機器指令的助記符,同機器指令一一對應。(2)每一種cpu都有自己的匯編指令集。(3)cpu可以直接使用的信息在存儲器中存放。
(4)在存儲器中指令和數(shù)據(jù)沒有任何區(qū)別,都是二進制信息。(5)存儲單元從零開始順序編號。
(6)一個存儲單元可以存儲8個bit,即八位二進制數(shù)。
(7)每一個cpu芯片都有許多管腳,這些管腳和總線相連。也可以說,這些管腳引出總線。一個cpu可以引出的三種總線的寬度標志了這個cpu不同方面的性能。地址總線的寬度決定了cpu的尋址能力;數(shù)據(jù)總線的寬度決定了cpu與其他器件進行數(shù)據(jù)傳送時的一次數(shù)據(jù)傳送量;控制總線的寬度決定了cpu對系統(tǒng)中其他器件的控制能力。監(jiān)測點:1KB的存儲器有1024個存儲單元?存儲單元的編號從0到1023.內(nèi)存地址空間:
最終運行程序的是cpu,我們用匯編編程時,必須要從cpu的角度思考問題。對cpu來講,系統(tǒng)中的所有存儲器中的存儲單元都處于一個統(tǒng)一的邏輯存儲器中,它的容量受cpu尋址能力的限制。這個邏輯存儲器即是我們所說的內(nèi)存地址空間。第二章 寄存器(cpu的工作原理)mov ax, 2 add ax, ax add ax, ax add ax, ax(1)cpu中的相關部件提供兩個16位的地址,一個稱為段地址,另一個稱為偏移地址;(2)段地址和偏移地址通過內(nèi)部總線送人一個稱為地址加法器的部件;(3)地址加法器將兩個16位地址合成為一個20位的物理地址;(4)地址加法器通過內(nèi)部總線將20位物理地址送人輸入輸出控制電路;(5)輸入輸出控制電路將20位物理地址送上地址總線;(6)20位物理地址被地址總線傳送到存儲器; 段地址*16+偏移地址 = 物理地址 的本質(zhì)含義 內(nèi)存并沒有分段,段的劃分來自cpu。
以后編程時可以根據(jù)需要,將若干地址連續(xù)的內(nèi)存單元看做一個段,用段地址*16定位段的起始地址,用偏移地址定位段的內(nèi)存單元。
一個段的起始地址一定是16的倍數(shù),一個段的最大長度為64kB。當然也沒有辦法定義一個起始地址不是16的倍數(shù)的段。
cpu可以用不同的段地址和偏移地址形成同一物理地址。
在8086cpu加電啟動或復位后cs和ip被設置為cs = f000h,ip = ffffh,即ffff0h單元中的指令是8086pc機開機后執(zhí)行的第一條指令。(??應該是fffffh吧??)cpu將cs:ip指向的內(nèi)存單元看做指令。
在cpu中,程序員能夠用指令讀寫的部件只有寄存器,程序員可以通過改變寄存器中的內(nèi)容實現(xiàn)對cpu的控制。
mov指令稱為傳送指令,cpu中大部分寄存器的值都可以通過mov指令改變。除了cs:ip 8086沒給他這樣的功能。cs:ip可以用轉(zhuǎn)移指令來改變。jmp jmp cs:ip 用指令給出的段地址修改cs,偏移地址修改ip jmp 某一寄存器 的功能為:用寄存器中的值修改ip jmp ax 含義類似于mov ip,ax 段地址在8086pc機的段寄存器存放。當8086cpu要訪問內(nèi)存時,由段寄存器提供內(nèi)存單元的段地址。8086cpu有四個段寄存器,其中cs用來存放指令的段地址。cs存放指令的段地址,ip存放指令的偏移地址。
8086機中,任意時刻,cpu將cs:ip指向的內(nèi)容當作指令執(zhí)行。8086cpu的工作過程:
1.從cs:ip指向內(nèi)存單元讀取指令,讀取的指令進入指令緩沖器; 2.ip指向下一條指令 3.執(zhí)行
8086提供轉(zhuǎn)移指令修改cs:ip的內(nèi)容 debug的使用
查看,修改cpu中寄存器的內(nèi)容:r命令 查看內(nèi)存中的命令:d命令
修改內(nèi)存中的內(nèi)容:e命令(可以寫入數(shù)據(jù),指令,在內(nèi)存中,它們實際上沒有區(qū)別)將內(nèi)存中的命令解釋為機器指令和相應的匯編指令:u命令 執(zhí)行cs:ip指向的內(nèi)存單元處的命令:t命令 以匯編指令的形式向內(nèi)存中寫入指令:a命令 第三章 寄存器(內(nèi)存訪問)3.1內(nèi)存中字的存儲
高八位存放在高字節(jié)中,低八位存放在低字節(jié)中 3.2DS和【address】 3.3字傳送 3.4MOV ADD SUB 3.5數(shù)據(jù)段 3.6棧
棧是一種具有特殊的訪問方式的存儲空間。它的特殊性就在于,最后進入這個空間的數(shù)據(jù),最先出去。
棧有兩個基本的操作:入棧和出棧。
棧的這種操作規(guī)則被稱為:lifo(last in first out,后進先出)。cpu如何知道10000H--1000fH這段空間被當作棧使用?
push pop指令在執(zhí)行時必須知道哪個單元是棧頂單元,可是如何知道呢?
棧頂?shù)亩蔚刂反娣旁趕s中,偏移地址存放在sp中。任意時刻,ss:sp指向棧頂單元。push和pop指令執(zhí)行時,cpu從ss和sp中得到棧頂?shù)牡刂贰H霔r,棧頂從高地址向低地址方向增長。如何定義一個棧的大?。?mov ax, 1000h mov ss, ax mov sp, 0010h;則棧頂為1000f 棧底為 10000 ****************************************** mov ax, 1000h mov ds, ax mov ax, 2266h mov [0], ax ************************ mov ax,1000h mov ss, ax mov sp, 0002h mov ax, 2266h push ax 棧頂?shù)淖兓秶畲鬄椋?--ffffh 棧的綜述
(1)8086cpu提供了棧操作機制,方案如下: 在ss、sp中存放棧頂?shù)亩蔚刂泛推频刂罚?/p>
提供入棧和出棧指令,他們根據(jù)ss、sp指示的地址,按照棧的方式訪問內(nèi)存單元。(2)push指令的執(zhí)行步驟:1)sp=sp-2;2)向ss:sp指向的字單元送人數(shù)據(jù);(3)pop指令的執(zhí)行步驟:1)從ss:sp指向的字單元中讀取數(shù)據(jù);2)sp=sp+2(4)任意時刻,ss:sp指向棧頂元素。
(5)8086cpu只記錄棧頂,??臻g的大小我們要自己管理。
(6)用棧來暫存以后需要恢復的寄存器的內(nèi)容時,寄存器出棧的順序要和入棧的順序相反。(7)push、pop指令實質(zhì)上是一種內(nèi)存?zhèn)魉椭噶睿⒁馑麄兊撵`活運用。一個棧段最大可以設為64k 段的綜述
我們可以將一段內(nèi)存定義為一個段,用一個段地址指示段,用偏移地址訪問段內(nèi)的單元。這完全是我們的安排。用一個段存放代碼,即代碼段 用一個段存放數(shù)據(jù),即數(shù)據(jù)段 用一個段當棧,即棧段
對于數(shù)據(jù)段,把段地址放在ds中,用mov,add,sub等訪問內(nèi)存單元的指令時,cpu就將我們定義的數(shù)據(jù)段內(nèi)容當做數(shù)據(jù)來訪問;
對于代碼段,把段地址放在cs:ip中,用mov,add,sub等訪問內(nèi)存單元的指令時,cpu就將執(zhí)行我們定義的代碼段的指令;
對于棧段,把段地址放在ss:sp中,用push pop 等訪問內(nèi)存單元的指令時,cpu就將其當作堆棧來訪問;
debug的t命令在執(zhí)行修改器ss的指令時,下一條指令也緊接著被執(zhí)行了。3.7棧超界問題
8086cpu不保證我們對棧的操作不會超界。也就是說,8086cpu只知道棧頂在何處而不知道我們安排的??臻g有多大,這點就好像,cpu只知道當前要執(zhí)行的指令在何處,而不知道要執(zhí)行的指令有多少。從這兩點我們可以看出cpu的工作機理,它只考慮當前情況:當前的棧在何處,當前要執(zhí)行的指令是哪一條。對于超界問題我們可以做到就是小心。第五章【bx】和loop指令
我們完整的描述一個內(nèi)存單元,需要兩種信息:(1)內(nèi)存單元的地址;(2)內(nèi)存單元存放數(shù)據(jù)的類型; inc bx的含義是bx中的內(nèi)容加一
[bx]寄存器bx中所包含的地址中存放的內(nèi)容 [bx]表示一個內(nèi)存單元,他的偏移地址在bx中。loop指令執(zhí)行的時候,要進行兩步操作: 1;(cx)=(cx)-1;
2;判斷cx中的值,不為零則轉(zhuǎn)至標號處執(zhí)行。
“通?!蔽覀冇胠oop實現(xiàn)循環(huán)功能,cx中存放循環(huán)次數(shù)。用cx和loop指令相配合實現(xiàn)循環(huán)功能的三個要點:(1)再cx中存放循環(huán)次數(shù);
(2)loop指令中的標號所標識地址要在前面;
(3)要循環(huán)執(zhí)行的程序段,要寫在標號和loop指令的中間。在匯編源程序中,數(shù)據(jù)不能以字母開頭。所以對于大于9fffh的數(shù),均在前面加上0。mov cx,11 s: add ax,ax loop s assume cs:code code segment..mov ax,4c00h int 21h code ends end ffff:6單元是一個字節(jié)單元,ax是一個十六位寄存器,數(shù)據(jù)長度不一樣,如何賦值? 注意我們說的是“賦值”,就是說,讓ax中的數(shù)據(jù)的值(數(shù)據(jù)的大?。┖蚮fff:0006單元中的數(shù)據(jù)的值(數(shù)據(jù)的大小)相等。八位數(shù)據(jù)01h和16位數(shù)據(jù)0001h的數(shù)據(jù)長度不一樣,但他們的值是相等的。
設ffff:0006單元中的的數(shù)據(jù)是xxh,若要ax中的值和ffff:0006單元中的值相等,ax中的數(shù)據(jù)應為00xxh。所以,若實現(xiàn)ffff:0006單元向ax賦值,我們應該令(ah)=0,(al)=(ffff6H).若希望程序能從cs:0012處執(zhí)行,可以用g命令。“g 0012”。他表示程序執(zhí)行到0012處。
若希望程序能跳出循環(huán),用p命令
5.4 debug和匯編編譯器masm對指令的不同處理。
在匯編源程序中,mov al,[0]會被編譯器解釋成為:mov al,0 所以要這樣表達:mov bx,0 mov al,[bx] 或者 mov al,ds:[0] 第一,我們在匯編源程序中,如果用指令訪問一個內(nèi)存單元,則在指令中必須用[...]來表示內(nèi)存單元,如果在[]里用一個常量idata直接給出內(nèi)存單元的偏移地址,就要在[]的前面顯示地給出段地址所在的段寄存器。
第二,如果在[]里用寄存器,比如bx,間接給出內(nèi)存單元的偏移地址,則段寄存器默認在ds中。
第六章 包含多個段的程序 程序取得所需段的方法有兩種:
一是在加載程序的時候為程序分配,再就是程序在執(zhí)行的過程中向系統(tǒng)申請。dw的含義是定義字型數(shù)據(jù)即define word 字型數(shù)據(jù)間以逗號隔開。
程序運行的時候cs存放代碼段的段地址,所以我們可以從cs中得到它們的段地址。dw定義的數(shù)據(jù)處于代碼段的最開始,所以偏移地址為零。dw 0123h,5604h,1234h start :指令 end start 我們在程序的第一條指令的前面加了一個標號start:并在end的后面再次加入。end除了通知編譯器程序結(jié)束外,還可以通知編譯器程序的入口在什么地方。在單任務系統(tǒng)中,可執(zhí)行文件中的程序執(zhí)行如下:
(1)由其他的程序(debug、command或其他程序)將可執(zhí)行文件中的程序加載入內(nèi)存;(2)設置cs:ip指向程序的第一條要執(zhí)行的指令(即程序的入口),從而使程序得以運行;(3)程序運行結(jié)束后,返回到加載者; 描述信息
可執(zhí)行文件由描述信息和程序組成,程序來源于源程序中的匯編指令和定義的數(shù)據(jù);描述信息則主要是編譯連接程序?qū)υ绦蛑邢嚓P偽指令進行處理所得到的信息。6.2 在代碼中使用棧
在程序中通過定義數(shù)據(jù)來取得一段空間,然后將這段空間當作??臻g來使用。
例如將cs:16--cs:31的內(nèi)存空間當作棧來用,初始狀態(tài)下棧為空,所以ss:sp要指向棧底,則設置ss:sp指向cs:32.6.3將數(shù)據(jù)代碼棧放入不同的段
用assume將定義的具有一定用途的段跟寄存器聯(lián)系起來 第七章 更靈活的定位內(nèi)存地址的方法 7.1 and 和 or 指令(1)and指令:邏輯與指令,按位進行與運算。mov al ,01100011B and al ,00111011B 執(zhí)行后:al=00100011B 通過該運算可將操作對象的相應位設為0,其他位不變。(2)or指令:邏輯或指令,按位進行或運算。
通過該運算可將操作對象的相應位設為1,其他位不變。7.2 關于ASCII碼
所謂編碼方案,就是一套規(guī)則,它約定了用什么樣的信息來表示現(xiàn)實對象。小寫字母的ASCII碼值,比大寫字母的ASCII碼值大20H。
就ASCII碼的二進制形式來看,除第五位外,大寫字母和小寫字母的ASCII碼值都一樣。大寫字母第五位為0,小寫字母第五位為1.運用and和or指令的給特定位賦值功能即可實現(xiàn)大小寫字母之間的轉(zhuǎn)換。7.5 [bx+idata] 類似于[bx]的一種更靈活的指明內(nèi)存單元的方式。
[bx+idata]表示一個內(nèi)存單元,它的偏移地址為(bx)+idata(bx中的數(shù)值加上idata。也可以寫成 mov ax,[200+bx] mov ax,200[bx] mov ax,[bx].200 7.6 用[bx+idata]的方式進行數(shù)組的處理 7.7 SI和DI SI和DI是8086cpu中和bx功能相近的寄存器。區(qū)別是SI和DI不能夠分成兩個八位寄存器來使用。codesg segment start: mov ax,datasg mov ds,ax mov si,0 mov di,16 mov cx,8;di si 為16位寄存器只需循環(huán) s: mov ax,[si] mov [di],ax;八次即可將16個字節(jié)傳送完畢 add si,2 add di,2 loop s
mov ax,4c00h int 21h codesg ends end start si = dijmp指令后的第一個字節(jié)的地址(2)short指明此處的位移為八位位移。(3)八位位移的范圍為-128 127,用補碼表示;(4)八位位移由編譯程序在編譯時算出。
還有一種jmp near ptr 標號 實現(xiàn)段內(nèi)近轉(zhuǎn)移(ip)=(ip)+16位位移(1)16位位移 = “標號”處的地址1(DI)=(DI)-1 MOVSW 可以傳送一個字
MOVSB和MOVSW進行的是串傳送操作中的一個步驟,一般都要和rep配合使用,格式如下: rep movsb 相當于: s:movsb loop s rep的作用是根據(jù)cx的值,重復執(zhí)行后面的串傳送指令。8086cpu提供了下面兩條指令對DF位進行設置: CLD:將DF位置0 STD:將DF位置1 1.傳送的原始地址 2.傳送的目的地址 3.傳送的長度 4.傳送的方向 11.11 pushf和popf 壓入/彈出標志寄存器中的數(shù)據(jù) 為訪問標志寄存器提供了一種方法。11.12 標志寄存器在DEBUG中的表示 第十二章 內(nèi)中斷 12.1 內(nèi)中斷的產(chǎn)生
cpu內(nèi)部發(fā)生下面情況時,將產(chǎn)生相應的中斷信息:
(1)除法錯誤(2)單步執(zhí)行(3)執(zhí)行int0命令(4)執(zhí)行int命令 中斷類型碼0 1 4 n 為一個字節(jié)型數(shù)據(jù) 12.2 中斷處理程序
cpu如何通過八位的中斷類型碼得到中斷處理程序的段地址和偏移地址? 12.3 中斷向量表 答:通過中斷向量表
中斷向量表就是中斷處理程序入口地址的列表。保存在內(nèi)存中。cpu如何找到中斷向量表?
對于8086中斷向量表指定存在內(nèi)存地址0處。從0000:0000到0000:03e8單元。共1000個字節(jié)。中斷向量表中一個表項存放一個中斷向量,占兩個字。分別存放段地址和偏移地址。12.4 中斷過程
(1)從中斷信息中取得中斷類型碼(2)標志寄存器的值入棧
(3)設置標志寄存器的第八位TF和第九位IF的值為0(4)CS的內(nèi)容入棧(5)IP的值入棧
(6)從內(nèi)存地址為中斷類型碼*4和中斷類型碼*4 + 2 的兩個字單元中讀取中斷處理程序的入口地址設置IP和CS 12.5 中斷處理程序(1)保存用到的寄存器(2)處理中斷。(3)恢復用到的寄存器(4)用IRET指令返回。12.6 除法錯誤中斷的處理 12.7 編程處理0號中斷 12.8 安裝 第十三章 int指令 13.1 int指令
int指令的最終功能和call指令相似,都是調(diào)用一段程序。13.2 編寫供應用程序調(diào)用的中斷例程
編寫、安裝中斷7ch的中斷例程,功能:求一word型數(shù)據(jù)的平方。(AX)= 要計算的數(shù)據(jù)。
DX,AX存放結(jié)果的高十六位和低十六位。MOV WORD PTR ES:[7CH*4],200H MOV WORD PTR ES:[7CH*4+2],0 MOV CX,OFFSET SQREND-OFFSET SQR CLD REP MOVSB int指令和iret指令配合使用與call指令和ret指令配合使用具有相似的思路。13.3 對int、iret和棧的深入理解 ********************************* 13.4 BIOS和DOS所提供的中斷例程 BIOS主要包含以下內(nèi)容:
1、硬件系統(tǒng)的檢測和初始化程序
2、外部中斷和內(nèi)部中斷的中斷例程
3、用于對硬件設備進行I/O操作的中斷例程
4、其他和硬件系統(tǒng)相關的中斷例程 13.5 BIOS和DOS中斷例程的安裝過程
1.開機后,cpu一加點,初始化(cs)= 0FFFFH,(IP)= 0,自動從FFFF:0單元開始執(zhí)行程序。FFFF:0處有一條跳轉(zhuǎn)指令,cpu執(zhí)行該程序后,轉(zhuǎn)去執(zhí)行BIOS中的硬件檢測和初始化程序。
2.初始化程序?qū)⒔IOS所支持的中斷向量,即將BIOS提供的中斷例程的入口登記在中斷向量表中。注意,對于BIOS所提供的中斷例程,只需將入口地址登記在中斷向量表中即可,因為它們是固化到ROM中的內(nèi)容,一直在內(nèi)存中存在。
3.硬件系統(tǒng)檢測和初始化完成后,調(diào)用int 19h進行操作系統(tǒng)的引導。從此將計算機交給操作系統(tǒng)控制。
4.DOS啟動后,除完成其他工作外,還將它提供的中斷例程裝入內(nèi)存,并建立相應的中斷向量。
13.6 BIOS中斷例程應用
int 10h 中斷例程是BIOS提供的中斷例程,其中包含多個和屏幕輸出有關的子程序。一個供程序員調(diào)用的中斷例程往往包含多個子程序,中斷例程內(nèi)部用傳遞進來的參數(shù)來決定執(zhí)行那一個子程序。BIOS和DOS提供的中斷例程,都用AH來傳遞內(nèi)部參數(shù) 13.7 DOS中斷例程應用
例如 我們一直在使用的4ch號子程序,即程序返回功能。mov ah 4ch mov al 0 int 21h ========================== DOS功能調(diào)用 int 21h(1)鍵盤輸入 1)1號調(diào)用——從鍵盤輸入單個字符 調(diào)用格式: MOV AH,1 INT 21H 功能: 等待從鍵盤輸入一個字符并送入AL。
執(zhí)行時系統(tǒng)將掃描鍵盤,等待有健按下,一旦有健按下,就將其字符的ASCII碼讀
入,先檢查是否Ctrl-Break,若是,退出命令執(zhí)行;否則將ASCII碼送AL,同時將
該字符送顯示器顯示。2)10號調(diào)用——從鍵盤輸入字符串
功能: 從鍵盤接收字符串送入內(nèi)存的輸入緩沖區(qū),同時送顯示器顯示。調(diào)用前要求: 先定義一個輸入緩沖區(qū)
MAXLEN DB 100 ;第1個字節(jié)指出緩沖區(qū)能容納的字符個數(shù),即緩沖區(qū)長度,不能為0 ACLEN DB ? ;第2個字節(jié)保留,以存放實際輸入的字符個數(shù) STRING DB 100 DUP(?);第3個字節(jié)開始存放從鍵盤輸入的字符串。
調(diào)用格式: LEA DX,MAXLEN(緩沖區(qū)首偏移地址)MOV AH,10 INT 21H(2)顯示輸出
1)2號調(diào)用——在顯示器上顯示輸出單個字符 調(diào)用格式: MOV DL,待顯示字符的ASCII碼 MOV AH,2 INT 21H 功能:將DL中的字符送顯示器顯示?!纠匡@示輸出大寫字母A MOV DL,41H ;或?qū)憺?MOV DL,'A' MOV AH,2 INT 21H 2)9號調(diào)用——在顯示器上顯示輸出字符串 調(diào)用格式: LEA DX,字符串首偏移地址 MOV AH,9 INT 21H 功能:將當前數(shù)據(jù)區(qū)中DS:DX所指向的以'$'結(jié)尾的字符串送顯示器顯示?!纠吭陲@示器上顯示字符串“YOU ARE SUCESSFUL!” DATA SEGMENT STRING DB ' YOU ARE SUCESSFUL!$ ' DATA ENDS CODE SEGMENT ? ? MOV AX,DATA MOV DS,AX LEA DX,STRING MOV AH,9 INT 21H ? ? CODE ENDS 說明:若希望顯示字符串后,光標可自動回車換行,可在定義字符串時作如下更改: STRING DB ' YOU ARE SUCESSFUL!',0AH,0DH,' $ ' ;在字符串結(jié)束前加回車換行的ASCII碼0AH,0DH
第二篇:C語言 各章知識點總結(jié)
總體上必須清楚的:
2)讀程序都要從main()入口, 然后從最上面順序往下讀(碰到循環(huán)做循環(huán),碰到選擇做選擇)。
4)bit是位 是指為0 或者1。byte 是指字節(jié), 一個字節(jié) = 八個位.5)一定要記住 二進制 如何劃成 十進制。概念??嫉降模?/p>
1、編譯預處理不是C語言的一部分,不再運行時間。C語言編譯的程序稱為源程序,它以ASCII數(shù)值存放在文本文件中。2、每個C語言程序中main函數(shù)是有且只有一個。3、在函數(shù)中不可以再定義函數(shù)。
4、算法一定要有輸出的,但可以沒有輸入。5、break可用于循環(huán)結(jié)構(gòu)和switch語句。6、逗號運算符的級別最低。第一章
1)合法的用戶標識符考查:
合法的要求是由字母,數(shù)字,下劃線組成。有其它元素就錯了。并且第一個必須為字母或則是下劃線。第一個為數(shù)字就錯了。
關鍵字不可以作為用戶標識符號。main define scanf printf 都不是關鍵字。迷惑你的地方If是可以做為用戶標識符。因為If中的第一個字母大寫了,所以不是關鍵字。
關鍵字有:
auto break case char const continue default do double else enum extern float for goto if int long register return short signed static sizeof struct switch typedef union unsigned void volatile while auto :聲明自動變量
double :聲明雙精度變量或函數(shù)
int: 聲明整型變量或函數(shù)
struct:聲明結(jié)構(gòu)體變量或函數(shù) break:跳出當前循環(huán)
else :條件語句否定分支(與 if 連用)long :聲明長整型變量或函數(shù) switch :用于開關語句 case:開關語句分支 enum :聲明枚舉類型
register:聲明寄存器變量
typedef:用以給數(shù)據(jù)類型取別名 char :聲明字符型變量或函數(shù)
extern:聲明變量是在其他文件正聲明
return :子程序返回語句(可以帶參數(shù),也可不帶參數(shù))union:聲明共用數(shù)據(jù)類型 const :聲明只讀變量
float:聲明浮點型變量或函數(shù) short :聲明短整型變量或函數(shù)
unsigned:聲明無符號類型變量或函數(shù)
continue:結(jié)束當前循環(huán),開始下一輪循環(huán) for:一種循環(huán)語句
signed:聲明有符號類型變量或函數(shù)
void :聲明函數(shù)無返回值或無參數(shù),聲明無類型指針 default:開關語句中的“其他”分支 goto:無條件跳轉(zhuǎn)語句
sizeof:計算數(shù)據(jù)類型長度
volatile:說明變量在程序執(zhí)行中可被隱含地改變 do :循環(huán)語句的循環(huán)體
while :循環(huán)語句的循環(huán)條件
static :聲明靜態(tài)變量
if:條件語句
2)實型數(shù)據(jù)的合法形式:
2.333e-1 就是合法的,且數(shù)據(jù)是2.333×10-1。考試口訣:e前e后必有數(shù),e后必為整數(shù)。.3)字符數(shù)據(jù)的合法形式::
'1' 是字符占一個字節(jié),“1”是字符串占兩個字節(jié)(含有一個結(jié)束符號)。'0' 的ASCII數(shù)值表示為48,'a' 的ASCII數(shù)值是97,'A'的ASCII數(shù)值是65。
4)整型一般是兩個字節(jié), 字符型是一個字節(jié),雙精度一般是4個字節(jié):
考試時候一般會說,在16位編譯系統(tǒng),或者是32位系統(tǒng)。碰到這種情況,不要去管,一樣做題。掌握整型一般是兩個字節(jié), 字符型是一個字節(jié),雙精度一般是4個字節(jié)就可以了。5)轉(zhuǎn)義字符的考查:
在程序中 int a = 0x6d,是把一個十六進制的數(shù)給變量a 注意這里的0x必須存在。
在程序中 int a = 065, 是一個八進制的形式。
6)算術運算符號的優(yōu)先級別:
同級別的有的是從左到右,有的是從右到左。7)強制類型轉(zhuǎn)換:
一定是(int)a 不是 int(a),注意類型上一定有括號的。
注意(int)(a+b)和(int)a+b 的區(qū)別。前是把a+b轉(zhuǎn)型,后是把a轉(zhuǎn)型再加b。8)表達式的考查:
是表達式就一定有數(shù)值。
賦值表達式:表達式數(shù)值是最左邊的數(shù)值,a=b=5;該表達式為5,常量不可以賦值。
自加、自減表達式:假設a=5,++a(是為6),a++(為5);
運行的機理:++a 是先把變量的數(shù)值加上1,然后把得到的數(shù)值放到變量a中,然后再用這
個++a表達式的數(shù)值為6,而a++是先用該表達式的數(shù)值為5,然后再把a的數(shù)值加上1為6,再放到變量a中。進行了++a和a++后在下面的程序中再用到a的話都是變量a中的6了??荚嚳谠E:++在前先加后用,++在后先用后加。
逗號表達式:優(yōu)先級別最低 ;表達式的數(shù)值逗號最右邊的那個表達式的數(shù)值。(2,3,4)的表達式的數(shù)值就是4。9)位運算的考查:
會有一到二題考試題目。
總的處理方法:幾乎所有的位運算的題目都要按這個流程來處理(先把十進制變成二進制再變成十進制)。
一定要記住,在沒有舍去數(shù)據(jù)的時候,<<左移一位表示乘以2;>>右移一位表示除以2。
10)018的數(shù)值是非法的,八進制是沒有8的,逢8進1。
11)%符號兩邊要求是整數(shù)。不是整數(shù)就錯了。12)兩種取整丟小數(shù)的情況:
1、int a =1.6;
2、(int)a;
第二章 1)printf函數(shù)的格式考查:
%d對應整型;%c對應字符;%f對應單精度等等。寬度的,左對齊等修飾。-
%ld對應 long int;%lf 對應double。2)scanf函數(shù)的格式考察:
注意該函數(shù)的第二個部分是&a 這樣的地址,不是a;
Scanf(“%d%d%*d%d”,&a,&b,&c);跳過輸入的第三個數(shù)據(jù)。3)putchar ,getchar 函數(shù)的考查: char a = getchar()是沒有參數(shù)的,從鍵盤得到你輸入的一個字符給變量a。
putchar(‘y’)把字符y輸出到屏幕中。
5)如何實現(xiàn)保留三位小數(shù),第四位四舍五入的程序,(要求背下來)
這個有推廣的意義,注意 x =(int)x 這樣是把小數(shù)部分 去掉。
第三章
特別要注意:c語言中是用非0表示邏輯真的,用0表示邏輯假的。1)關系表達式:
表達式的數(shù)值只能為1(表示為真),或0(表示假)
當關系的表達是為真的時候得到1。如 9>8這個是真的,所以表達式的數(shù)值就是1; 2)邏輯表達式:
只能為1(表示為真),或0(表示假)a)共有&& ||!三種邏輯運算符號。b)!>&&>|| 優(yōu)先的級別。
c)注意短路現(xiàn)象??荚嚤容^喜歡考到。
(表達式1)&&(表達式2)如果表達式1為假,則表達式2不會進行運算,即表達式2“被短路”
(表達式1)||(表達式2)如果表達式1為真,則表達式2不會進行運算,即表達式2“被短路”
3)if 語句
else 是與最接近的if且沒有else的相組合的。4)條件表達式: 表達式1 ?表達式2 :表達式3 5)switch語句:
a)一定要注意 有break 和沒有break的差別,書上(34頁)的兩個例子,沒有break時候,只要有一個case匹配了,剩下的都要執(zhí)行,有break則是直接跳出了swiche語句。
b)switch只可以和break一起用,不可以和continue用。
第四章 1)三種循環(huán)結(jié)構(gòu):
a)for(); while();do-while()三種。b)for循環(huán)當中必須是兩個分號,千萬不要忘記。
c)寫程序的時候一定要注意,循環(huán)一定要有結(jié)束的條件,否則成了死循環(huán)。-
d)do-while()循環(huán)的最后一個while();的分號一定不能夠丟。(當心上機改錯)
2)break 和 continue的差別
記憶方法:
break:是打破的意思,(破了整個循環(huán))所以看見break就退出真?zhèn)€一層循環(huán)。-
continue:是繼續(xù)的意思,(繼續(xù)循環(huán)運算),但是要結(jié)束本次循環(huán),就是循環(huán)體內(nèi)剩下的語句不再執(zhí)行,跳到循環(huán)開始,然后判斷循環(huán)條件,進行新一輪的循環(huán)。3)嵌套循環(huán)
就是有循環(huán)里面還有循環(huán),這種比較復雜,要一層一層一步一步耐心的計算,一般記住兩層是處理二維數(shù)組的。
4)while((c=getchar())!=’n’)和 while(c=getchar()!=’n’)的差別
先看a = 3!= 2 和(a=3)!=2 的區(qū)別:(!= 號的級別高于 = 號 所以第一個先計算 3!=2)第一個a的數(shù)值是得到的1;第二個a的數(shù)值是3??荚囎⒁恻c: 括號在這里的重要性。
第五章
函數(shù):是具有一定功能的一個程序塊; 2)一定要注意參數(shù)之間的傳遞
實參和形參之間 傳數(shù)值,和傳地址的差別。(考試的重點)
傳數(shù)值的話,形參的變化不會改變實參的變化。
傳地址的話,形參的變化就會有可能改變實參的變化。3)函數(shù)聲明的考查:
一定要有:函數(shù)名,函數(shù)的返回類型,函數(shù)的參數(shù)類型。不一定要有:形參的名稱。
第六章
*p++ 和(*p)++的之間的差別:改錯題目中很重要 *p++是 地址會變化。
(*p)++ 是數(shù)值會要變化。
三名主義:(考試的重點)
數(shù)組名:表示第一個元素的地址。數(shù)組名不可以自加,他是地址常量名。了很多次)
函數(shù)名:表示該函數(shù)的入口地址。
字符串常量名:表示第一個字符的地址。
(考第七章
1一維數(shù)組的重要概念: 對a[10]這個數(shù)組的討論。
1、a表示數(shù)組名,是第一個元素的地址。
2、a是地址常量,所以只要出現(xiàn)a++,或者是a=a+2賦值的都是錯誤的。3、a是一維數(shù)組名,所以它是列指針,也就是說a+1是跳一列。
對a[3][3]的討論。
1、a表示數(shù)組名,是第一個元素的地址。
2、a是地址常量,所以只要出現(xiàn)a++,或者是a=a+2賦值的都是錯誤的。3、a是二維數(shù)組名,所以它是行指針,也就是說a+1是跳一行。
4、a[0]、a[1]、a[2]也都是地址常量,不可以對它進行賦值操作,同時它們都是列指針,a[0]+1,a[1]+1,a[2]+1都是跳一列。
5、注意a和a[0]、a[1]、a[2]是不同的,它們的基類型是不同的。前者是一行元素,后三者是一列元素。二維數(shù)組做題目的技巧:
如果有a[3][3]={1,2,3,4,5,6,7,8,9}這樣的題目。
步驟一:把他們寫成:
第一列 第二列 第三列
a[0] 1 2 3 ->第一行 a[1] 4 5 6 —>第二行 a[2] 7 8 9 ->第三行 步驟二:這樣作題目間很簡單:
*(a[0]+1)我們就知道是第一行的第一個元素往后面跳一列,那么這里就是a[0][1]元素,所以是2。
*(a[1]+2)我們就知道是第二行的第一個元素往后面跳二列。那么這里就是a[1][2]元素,所以是6。一定記?。褐灰嵌S數(shù)組的題目,一定是寫成如上的格式,再去做題目,這樣會比較簡單。
數(shù)組的初始化,一維和二維的,一維可以不寫,二維第二個一定要寫
int a[]={1,2} 合法。int a[][4]={2,3,4}合法。但int a[4][]={2,3,4}非法。二維數(shù)組中的行指針 int a[1][2];
其中a現(xiàn)在就是一個行指針,a+1跳一行數(shù)組元素。搭配(*)p[2]指針 a[0],a[1]現(xiàn)在就是一個列指針。a[0]+1 跳一個數(shù)組元素。搭配*p[2]指針數(shù)組使用 無條件等價:
a[2]等價于*(a+2)a[2][3]等價于*(a+2)[3]等價于*(*(a+2)+3)這個思想很重要!
第三篇:c語言期末復習
誰能出線
電視臺舉辦“超級學生”才藝大賽,由于報名人數(shù)狂多,所以要先進行分組預賽。按規(guī)定,每10名學生為一個預賽小組,評委打出分數(shù)(0~100分),各小組第一名可以進入下一輪;如果有多名學生得分相同都是第一名,則可同時進入下一輪。
1.#include
求出 2 到 m 之間(含 m,m<=1000)所有素數(shù)并放在數(shù)組 a 中。輸入:正整數(shù)m 輸出:從小到大的所有素數(shù),及個數(shù)(素數(shù)輸出的時候用%4d來控制)
1.#include
9.i=i+1;10.}
11.cnt=0;
12.for(i=0;i 14.j=2; 15.while(a[i]%j!=0)16.{ 17.j++;18.} 19.if(j==a[i])20.{ 21.printf(“%4d”,j);22.cnt=cnt+1;23.} 24.25.}printf(“n”);26.printf(“%d”,cnt);27.printf(“n”);28.return 0;29.} 1.#include 4.int a[10],i,j,n;5.for(i=0;i<10;i++)6.{ 7.scanf(“%d”,&a[i]);8.} 9.for(j=0;j<10;j++)10.{ 11.12.for(i=0;i<9;i++)13.{ 14.if(a[i+1] 16.n=a[i+1];17.a[i+1]=a[i];18.a[i]=n;19.} 20.} 21.} 22.23.for(i=0;i<10;i++)24.{ 25.printf(“ %d”,a[i]); 冒泡法排序26.} 27.printf(“n”);28.return 0;29.} 插入法排序 1.#include 1.#include 7.do 8.{ 9.a[i]=n%10;10.n=n/10;11.i++;12.k++; 13.}while(n!=0); 14.for(j=0;j 16.for(i=0;i 18.if(a[i+1]>a[i])19.{ 20.m=a[i+1];21.a[i+1]=a[i];22.a[i]=m;23.} 24.} 25.} 26.for(i=0;i 28.printf(“%d”,a[i]);29.} 30.printf(“n”);31.return 0;32.} 數(shù)組逆序輸出 1.#include 4.int a[10],i,j,t;5.for(i=0;i<10;i++)6.{ 7.scanf(“%d”,&a[i]);8.} 9.i=0;10.j=9; 11.while(i 13.t=a[i];14.a[i]=a[j];15.a[j]=t;16.i++;17.j--;18.} 19.for(i=0;i<10;i++)20.{ 21.printf(“%d ”,a[i]);22.} 23.printf(“n”);24.return 0;25.} 求最大值 1.#include 程序定義了 4× 4 的二維數(shù)組,請編寫程序,給二維數(shù)組賦值,并使數(shù)組下半三角元素中的值乘以n。例如: 數(shù)組中的值為 假設n為10,則輸出結(jié)果如下:(輸出的數(shù)按照4位寬度來輸出,即%4d) 1.#include 4.int a[4][4],i,j,n;5.for(i=0;i<4;i++)6.{ 7.for(j=0;j<4;j++)8.{ 9.scanf(“%d”,&a[i][j]);10.} 11.} 12.scanf(“%d”,&n);13.for(i=0;i<4;i++)14.{ 15.for(j=0;j<=i;j++)16.{ 17.a[i][j]=n*(a[i][j]);18.} 19.} 20.for(i=0;i<4;i++)21.{ 22.for(j=0;j<4;j++)23.{ 24.printf(“%4d”,a[i][j]);25.} 26.printf(“n”);27.} 28.return 0;29.} 在屏幕上顯示楊輝三角形 1.#include 6.int a[N][M],i,j,n;7.scanf(“%d”,&n);8.for(i=0;i 10.j=i; 11.a[i][0]=1;12.a[i][j]=1;13.} 14.for(i=2;i 1.#include 28.printf(“ %d”,a[i][j]); 29.} printf(“n”);30.} 31.return 0;32.} 給數(shù)組中的元素按順序編號 對數(shù)組 a[10] 中的十個整數(shù)從小到大進行連續(xù)編號,輸出各個元素的編號。要求不能改變數(shù)組 a 中元素的順序,且相同的整數(shù)要具有相同的編號。例如數(shù)組是: A=(5,3,4,7,3,5,6,8,9,10)則輸出為:(4,1,3,7,1,4,6,8,9,10) 1.#include 4.int a[10],b[10],i,j,t;5.for(i=0;i<10;i++)6.{ 7.scanf(“%d”,&a[i]);8.} 9.for(i=0;i<10;i++)10.{ 11.b[i]=a[i];12.} 13.for(i=0;i<9;i++)14.{ 15.for(j=i+1;j<10;j++)16.{ 17.if(a[i]>a[j])18.{ 19.t=a[i];20.a[i]=a[j];21.a[j]=t;22.} 23.} 24.} 25.for(j=0;j<10;j++)26.{ 27.for(i=0;i<10;i++)28.{ 29.if(b[j]==a[i])30.{ 31.printf(“%3d”,i+1);brea k; 32.} 33.} 34.}printf(“n”);35.return 0;36.} 字符轉(zhuǎn)換 描述 提取一個字符串中的所有數(shù)字字符(‘0’...‘9’)將其轉(zhuǎn)換為一個整數(shù)輸出。輸入 一個以回車符為結(jié)束標志的字符串(少于80個字符)。輸出 把字符串中的所有數(shù)字字符(‘0’...‘9’)轉(zhuǎn)換為一個整數(shù)并輸出。 1.#include