當前位置:首頁 » 編程軟體 » 通知編譯器程序結束的指令

通知編譯器程序結束的指令

發布時間: 2022-06-23 16:39:46

『壹』 匯編程序結尾 為什麼要先結束代碼段 code ends 最後才結束 程序段 end start

也許你看的那個程序剛好只有一個start標簽,所以誤以為END start就是用來結束start的.其實並不是這樣.一個程序中可以有很多個標簽.有一個start,下面,或者上面還會有otherstart標簽等等....標簽是沒有結束的.執行完這個標簽繼續往下執行,END start標簽只是告訴編譯器,從程序從這里結束,並且開始標簽是start.

『貳』 常見的存儲器有哪些有哪些使用注意事項

只要把匯編指令都寫出來了,你就可以到指令表中找到每一條指令所對應的機器碼,然後你只要在機器碼後面加上操作數即可,比如,把一個30H單元送入A累加器;指令是這樣的:MOV A , 30H .那麼你可以在指令表中查到執行這條指的機器碼是1110 0101,但是由於這條指令後面的那個30H單元的數是根據你的要求在不斷的變的,機器沒規定你只能用30H單元,所以這個30的操作數必須由你填,它們和在一塊兒,這條指令的機器碼是:1110 0101 0011 0000用十六進制來表示:E530,很明顯前兩位E5是機器指定的,而後兩位30是你自己加進去的。共是十六位,佔用兩個位元組……。
你說的LED燈閃爍,不知是指的流水燈還是一隻發光二極體在不停地閃爍?但不管是哪一種,有一點很重要。你在編寫此程序時必須要考慮延時,因為51單片機的晶體振盪器最低頻率可能是6M(具體數值我已記不清了)。也就是說單片機的每一個機器周期所佔用的時間僅2微秒,如果你不考慮延時的話,那麼你設計的那盞燈,它閃爍的結果是;亮2微秒,熄2微秒,也就是說每一秒鍾要亮暗50萬次,肉眼看這盞燈根本就不會有熄滅的時候,只是比不閃的燈暗了一半。我們生活中用的白熾燈,每秒鍾亮暗100次,你能感覺出燈泡有熄滅的時候嗎?更何況那是50萬次啊!
比如設計流水燈的程序,不妨可以這樣考慮它的演算法。計數寄存器的高八位加上低八位,合起來也只有十六位,它能數的數最大也就是65535,就算單片機用的是最低的6M的晶體振盪器,一個機器周期是12個機器節拍,所以,每一個機器周期佔用2微秒時間,從0數到65535,僅用了131070微秒就數完了,約130毫秒,如果就按這個延時去改變燈的亮暗時間,那麼這盞燈每秒鍾要亮暗3、4次,肉眼雖然能夠看到燈有熄滅的時間了。但是眼睛看這樣的燈總不會那麼舒服,所以至少應讓它延時到1秒鍾亮暗一次。為了計算方便,就讓計數器數100毫秒的時間吧!等計數器數到100毫秒後,就讓它再數一次,然後再數一次……,等它數滿5次後,這就是500毫秒(半秒鍾),然後,我們再去改變燈的亮暗狀態。
這個程序可以這樣來編:
MOV A ,#0FEH ;最低位設為0
MOV P1, A ;點亮最低位燈
MOV TCON,#10H ;T1為方式1,定時
BEGIN: MOV R7 ,#05H ;設循環5次
STAR: MOV TH1 #3CH ;計數器數100毫秒
MOV TL1 #AFH
SETB TR1 ;開始計數
ROU: JBC TF1 SE ;100毫秒到否?
SJMP ROU ;等待到100毫秒
SE: CLR TR1 ;關閉計數器
DJNZ R7 STAR ;5次循環到否? RL A ;把0向左移一位
MOV P1 ,A ;改下一隻燈亮
SJMP BEGIN
51的單片機

ORG 0000H
MAIN:MOV R2,#2
L1:MOV R3,#200
L2:MOV R4,#200
L3:NOP
NOP
DJNZ R4,L3
DJNZ R3,L2
DJNZ R2,L1
CPL P1.7
JMP MAIN
END

Medwin編寫C51匯編

八隻LED燈做流水燈實驗
單片機在上電初始後,其各埠輸出為高電平。如果我們現在想讓接在P1.0口的LED1亮,那麼我們只要把P1.0口的電平變為低電平就可以了。想讓LED1滅,LED0亮,只需將P1.0升高,P1.1變低,LED1就熄滅LED2隨後既點亮!依始類推如下所示8隻LED變會一亮一暗的做流水燈了.
P1.0低、P1.0高、P1.1低、P1.1高、P1.2低、P1.2高、P1.3低、P1.3高、P1.4低、P1.4高、P1.5低、P1.5高、P1.6低、P1.6高、P1.7低、P1.7高、返回到開始、程序結束。
我們不能說P1.1你變低,它就變低了。因為單片機聽不懂我們的漢語的,只能接受二進制的「1、0......」代碼。我們又怎樣來用二進制語議論使單片機按我們的意思去工作呢?為了讓單片機工作,只能將程序寫為二進制代碼交給其執行;早期單片機開發人員就是使用人工編寫的二進制代碼交給單片機去工作的。今天,我們不必用煩人的二進制去編寫程序,完全可以將我們容易理解的「程序語言」通過「翻譯」軟體「翻譯」成單片機所需的二進制代碼,然後交給單片機去執行。這里的「程序語言」目前主要有匯編和C兩種;在這里我們所說的「翻譯」軟體,同行們都叫它為「編譯器」,將「程序語言」通過編譯器產生單片機的二進制代碼的過程叫編譯。前面說到,要想使LED1變亮,只需將對應的單片機引腳電平變為低電平就可以了。現在讓我們將上面提到的8隻LED流水燈實驗寫為匯編語言程序。

「漢語」語言 匯編語言
開始: star:
P1.0低 clr p1.0
P1.0高 setb p1.0
P1.1低 clr p1.1
P1.1高 setb p1.1
P1.2低 clr p1.2
P1.2高 setb p1.2
P1.3低 clr p1.3
P1.3高 setb p1.3
P1.4低 clr p1.4
P1.4高 setb p1.4
P1.5低 clr p1.5
P1.5高 setb p1.5
P1.6低 clr p1.6
P1.6高 setb p1.6
P1.7低 clr p1.7
P1.7高 setb p1.7
返回到開始 ljmp star
結束 end

這里用到了四條匯編指令:clr、 setb、 ljmp 、end;

clr:是將其後面指定的位清為0;
setb:是將其後面指定的位置成1;
ljmp:是無條件跳轉指令,意思是:跳轉到指定的標號處繼續運行。
end:是一條告訴編譯器:程序到此結束的偽指令。偽指令只告訴編譯器此程序到此有何 要求或條件,它不參與和影響程序的執行。這里需要說明的是,按匯編語法要求,所編制的程序(下稱源程序)之格式和書寫要求必須依下列原則:
1、源程序必須為純文本格式文件,如用Windows「附件」中的「記事本」編寫的文本文件;2、源程序的擴展名應是 *.ASM; 3、一行只能寫一條語句,以回車作為本句的結束,每一語句行長度應少於80個字元(即40個漢字)。 4、每行的格式應為:標號: 命令 參數 ;注釋
即一行由四部份組成,各部份的順序不能搞錯,依實際要求可以預設其中的一部份或幾部份,甚至全部省去,即空白行。需要使用標號時標號後面必須有「:」(冒號),而命令語句和參數之間必須用空格分開,如果命令有多個參數,則參數與參數之間必須用「,」(逗號)分開,需要注釋時注釋前必須用「;」(分號),「;」後面的語句可以寫任何字元,包括漢字用於解釋前面的匯編語句,它將不參與匯編,不生成代碼。由於匯編程序對我們還不直觀,所以在編寫源程序時,應當養成多寫注釋的習慣,這樣有助於今後源程序的閱讀和維護。
標號是標志程序中某一行的符號名,編譯後標號的數值就是標號所在行代碼的地址。在宏匯編ASM51中標號的長度不受限制,但標號中不能包含『:』或其它的一些特殊符號,也不能用漢字,可以用數字作標號,但必須用字母開頭。當標號作參數用(如標號作轉移地址),在命令後面出現時,必須捨去『:』(如上面程序中的 LJMP STAR中的 STAR 是不能再有:)。
每行只能有一個標號,一個標號只能用在一處,如果有兩行用了同一個標號,則匯編時就會出錯。由於標號的長度沒有限制,可以用有意義的英文或漢語拼音來說明行,使源程序讀起來更方便。
源程序中的字母不區分大小寫,也就是說 star 和 STAR 是一樣的,請不要用大小寫方式去區分不同的標號

流水燈實驗詳解二
上一節的實驗最後沒有得到「流水」顯示的效果,主要是單片機執行每條指令的時間很短,我們肉眼無法看到LED的熄滅與點亮。單片機內部能按部就班的自動工作,正是在系統時鍾的作用下,內部各邏輯硬體產生各種所需脈沖信號而實現的。這個時鍾信號(既晶體振盪信號)的周期稱「振盪周期」。我們這個實驗中晶體使用的是12MHZ. 在單片機中,要處理最短周期的一條指令需要由12個振盪周期(既晶振振盪周期)組成的,這個叫「機器周期」。 8051核的單片機,大多數指令只用一個機器周期(既單周期),也有雙周期和四周期的指令。本實驗中用到的SETB P.x和CLR P.x均屬於單周期指令,也就是說,執行一句 SETB P.x 用時僅1uS(微秒),CLR P.x 也是1uS;難怪我們前面的程序不能看到流水效果。 現在,將程序改動一下,在每點亮一個LED後,讓程序干點別的事,也就是讓它等一會再將該LED熄滅,繼續執行下面的程序:
DDW: ;程序開始
CLR P1.0 ;LED1亮
ACALL DELAY ;調用延時子程序
SETB P1.0 ;LED1滅
CLR P1.1 ;換燈,同上
ACALL DELAY
SETB P1.1
CLR P1.2
ACALL DELAY
SETB P1.2
CLR P1.3
ACALL DELAY
SETB P1.3
CLR P1.4
ACALL DELAY
SETB P1.4
CLR P1.5
ACALL DELAY
SETB P1.5
CLR P1.6
ACALL DELAY
SETB P1.6
CLR P1.7
ACALL DELAY
SETB P1.7
LJMP DDW ;返回到開始循環
DELAY: ;延時子程序
MOV R1,#50
AD10:
MOV R2,#100
AD11:
MOV R3,#100
DJNZ R3,$
DJNZ R2,AD11
DJNZ R1,AD10
RET ;延時子程序結束,返回到調用處的下一句
END
請將上面的程序保存為 1LED.asm,進行編譯,並燒寫到AT89S51中,之後將89S51安裝到套件的實驗部份插座上實驗,這回顯示的就是「流水燈」的效果了!?回過頭,讓我們看看延時子程序是怎樣工作的:單片機內部有不少寄存器,這些寄存器在單片機通電時,你可以給他寫入數據(是單片機按你程序要求寫的數據,而不是編程器寫的),當第二次給他寫入新數據時,前次的數據就被新數據覆蓋;當然也可以從寄存器中讀取數據。當單片機沒有電源供給時,寄存器內部的數據也隨即消失;這些寄存器人們叫他RAM,而用編程器將我們編寫的程序燒寫到單片機中的存儲器叫ROM;現在,我們應該清楚:RAM是讓程序去使用的,ROM是我們編寫的程序存放的地方! 前面說過,單片機內部有不少RAM,本實驗用的AT89C51有多少寄存器?我們現在不必關心,現在只須知道單片機內部有名叫R0~R7 的這8個寄存器。這8個寄存器每個都由8個單獨的位寄存器組成,最大存放數據為二進制的 1111 1111,十六進制 = FF,十進制 = 255。在使用時注意不要大於其有效范圍。上面延時程序中,先用到 MOV R1,#50 ,MOV是移動的意思,該句是將50這個十進制數放到R1中;50是立即數,按匯編語言要求前面要加「#」號,匯編語言還規定,十六進制數後面要加「?H」,十六進制數的高位是字母時在字母前面還要加「0」,例如:#0F8H;二進制數後面加「B」,例如:#11110000B。十進制不加,例如:#100。延時程序的第二、三句為: MOV R2,#100 ;MOV R3,#100 ;這兩句意思同前。第四句中DJNZ R3,$ 的意思是將 R3 裡面的數減 1 後如果 R3 不等於 0 則跳到後面指定的程序位置,這里的「$」既要跳轉的程序位置,「$」代表當前語句處,也就是說,R3不等於 0,程序返回再次執行本句。如果R3 減 1 後等於0,程序結束本句,繼續執行下面的語句。延時程序的最後一句是RET ,意思是退出本子程序,返回到調用本子程序處的下一句。根據上面的解釋,一進入延時子程序首先為R1, R2, R3 寄存器裝入我們需要的數據,然後先對R3 進行減數,每次減 1 ,R3 減完後減R2 ,減R2 時就費事啦,因為R2 每減 1 後不為 0 需要跳轉到AD11 標號處執行下面的語句,此時R3 再次裝入數據100,並且還要再次對R3 進行減數......,R2 減完後減R1,減R1的過程你研究研究看看。 每執行 DJNZ ?Rn,rel (Rn 指 R0~R7,rel 指轉移地址)指令一次,需要2個機器周期,單片機需耗時2uS(指本實驗),若忽略裝數等語句,延時子程序從開始到結束,單片機共耗時100*100*50*2nS,既1000000uS=1秒!若加上裝數等語句的耗時,延時時間大於1秒。 到此,我們做的流水燈已成功,原理大致也明白啦,若你自認為這一課你完全明白了,那請你將「流水燈」的流向改變一下,也可以改為兩邊向內流,內部向外流......,我想你一定能用前面學到的方法實現這些功能。可能有些高手說,前面的編程方法是最最笨的!,不錯!但玩單片機初期不必講究語言的簡練,只要能完成預先要求就好,這是初學者要知道的。那麼還有更好的編程思路嗎?有!請繼續學習下節課

做流水燈實驗詳解三

在上節課中讓 LED 流水是去逐個控制P1埠的每個位來實現的,那麼我們在程序一開始就給P1口送一個數,這個數本身就讓P1.0先低,其他位為高,然後讓這個數據向高位移動不就實現「流水」效果啦?的確如此!可惜,8051沒有讓P1數據移動的指令,但有對累加器ACC中數據左移或右移的指令,ACC是8051單片機內部算術邏輯單元中的一個「寄存器」(這里叫他寄存器是不正確的,但你可以先這樣理解,ACC在指令中常寫為A),他在數據傳輸和數據處理過程中作用十分重要,ACC為8位。他可與片內所有單位元組寄存器交換數據,實際上P1和其他埠在單片機中也是一個寄存器。這樣我們可以將需移動的數據先放到ACC中,讓其移動,然後將ACC移動後的數據再轉送到P1口,這樣同樣可以實現「流水」效果。

程序如下:DDW: ;開始
MOV ACC,#0FEH ;ACC中先裝入LED1熄滅的數據(即二進制的 1111 1110)
MOV P1,ACC ;將ACC的數據送P1口
MOV R0,#7 ;因上句送到?p1口的數據就熄滅了一位,所以將數據再移動7次就完成一個8位流水過程
LOOP: ;數據移動循環
Rl A ;將ACC中的數據左移一位
MOV P1,A ;把ACC移動過的數據送p1口顯示
ACALL DELAY ;調用延時
DJNZ R0,LOOP ;沒有移動夠7次繼續移動
LJMP DDW ;移動完7次後跳到開始重來,以達到循環流動效果
DELAY: ;延時子程序,就是上節課中的延時子程序
MOV R1,#50
ADl0:
MOV R2,#100
ADl1:
MOV R3,#100
DJNZ R3,$
DJNZ R2,AD11
DJNZ R1,AD10
RET ;延時子程序結束,返回到調用處的下一句
END ;本匯編程序到此結束

接下來,將上述程序編譯,並燒寫到前面我們的實驗晶元中,流水效果與第二節課的一樣。 其實8051單片機有111條指令,這111條指令好比以前我們使用數字傳呼機時的「短語代碼」一樣,可以用幾個「短語代碼」去表示一句完整、通順的語句段落。有的指令常用,有的指令不常用,只要遵守語法規則,你可以用這些指令「組合」成你想像到的任何程序。當然,有時一條指令可以替代很多條指令,這樣會使程序簡捷,費碼減少,在編寫較大程序時可以讓程序存儲器放得下你需要的代碼。這也是單片機高手所追求的。當然,在程序存儲器空間不成問題時,你不這樣做但也可以達到預期的功能,這也不算錯。 單片機內部還有很多「部件」我們只是用到什麼說什麼,很不系統。但是我也不想系統的介紹這些,因系統介紹單片機結構和指令的書很多,何況寫的遠比我好,因此,希望你在看本講座的過程中,還要結合正規的教材學習其更多的指令和「部件」。

這是我在別的地方找過來的,希望對你有所幫助。

我用的是WAVE6000編譯的。

其他回答 按時間排序 按投票數排序
0
wsdx888 2009-9-3 10:25:17 124.128.36.* 舉報 單片機的內部結構

單片機是把微型計算機的主要組成部分CPU、存儲器、輸入/輸出介面等集成在一塊超大規模集成電路晶元上。
它是由CPU系統、程序存儲器、數據存儲器、各種I/O埠、基本功能單元(定時器/計數器等)組成。
1.CPU系統
CPU系統包括有CPU、時鍾系統、復位、匯流排(BUS,即信號的公共通道)控制邏輯。
(1)CPU
單片機中的CPU與微型計算機中的CPU有所不同,它的特點是,面向控制、面向嵌入系統、面向單晶元化。
(2)時鍾系統
時鍾系統用於產生單片機工作所需的時鍾信號。它必須滿足CPU及單片機內各單元電路對時鍾的要求。時鍾振盪器的工作頻率一般在1.2~12MHz。
(3)復位電路
復位電路應滿足上電復位、信號控制復位的要求。
(4)匯流排控制邏輯
匯流排控制邏輯應滿足CPU對內部匯流排和外部匯流排的控制要求。
2.程序存儲器
程序存儲器是一種只讀存儲器ROM(Read Only Memory),用它來固化單片機的應用程序和一些表格常數。單片機生產廠家按單片機內部程序存儲器的不同結構,形成單片機的不同結構類型,計有:
(1)Mask ROM型 (2)EPROM型 (3)ROM less型 (4)OTP ROM (5)Flash ROM(MTP ROM)型
前三種程序存儲器的單片機是早期的產品,目前EPROM、ROM Less型已較少使用。
3.數據存儲器RAM
RAM是一種可讀寫的存儲器,也叫隨機存儲器。單片機內部的RAM除了作為工作寄存器、位標志和堆棧區以外的單元都可以作為數據緩沖器使用,存放輸入的數據或運算的結果。
由於單片機主要是面向測控系統,所以單片機內部的數據存儲器容量較小,通常不多於256位元組,而且都使用靜態隨機存儲器SRAM(Static Random Access Memory)。
4.各種I/O埠
I/O埠是計算機的輸入、輸出介面(T是輸入,O是輸出之意)。單片機中的I/O埠都是晶元的輔入/輸出引腳。這些I/O埠,可分為以下幾種類型:
(1)匯流排輸入/輸出埠
(2)用戶I/O埠。由用戶用於外部電路的輸入/輸出控制。
(3)單片機內部功能的輸入/輸出埠。例如,定時器/計數器的計數輔入、外部中斷源輔入等。
為減少單片機引腳數量,一般I/O口都有復式功能。例如不使用外部匯流排時,匯流排埠可出讓給用戶做輔入/輔出埠用。
從I/O口的結構上還可以分為並行I/O口,即多位數據一起輸出或輸入,這種形式傳送數據速度快但使用的引腳多。另—種I/O口稱為串列I/O口,即傳送數據是順序輸出或輸入,這種形式可大大減少I/O口的引腳數,但傳送數據較慢。
5.基本功能單元
基本功能單元是為滿足單片機測控功能而設置的一些電路,是用來完善和擴大計算機功能的一些基本電路,如定時器/計數器,中斷系統等。定時器/計數器在實際應用中作用非常大,如精確的定時,或者對外部事件進行計數等。

『叄』 完成一個簡單程序所需要的最後一條指令是什麼指令

mov ax,stackcode segment和start是給編譯器看的,二進制可執行文件沒有這些標示,第一條指令是mov ax,stack對應的機器code

『肆』 程序結束指令有幾個彼此之間有什麼區別

摘要 任務管理-後台運行與終止

『伍』 偽指令DB和EQU的作用是什麼

偽指令DB和EQU的作用:主要用於告訴匯編程序如何進行匯編,它既不控制機器的操作也不被匯編成機器代碼,只能為匯編程序所識別並指導匯編如何進行。

DB,指示在程序存儲器中以標號為起始地址的單元里存放的數為位元組數據。

EQU,表示EQU兩邊的量等值,用於為標號或標識符賦值。

偽指令,顧名思義,它不是真正的指令,也就是不是最終的指令,是用於指示匯編程序如何匯編源程序,所以這種語句又叫命令語句。

例如偽指令告訴匯編程序,該源程序如何分段,有哪些邏輯段在程序段中,哪些是當前段等等,偽指令語句的這些命令功能是由匯編程序在匯編源程序時,通過執行另外一段程序來完成的,而不是在運行目標程序時實現的。

就好像召開新聞發布會,主持人用中文講話,由一個翻譯,現場翻譯成英文,講給外國記者聽。

主持人說的中文,大部分都是要翻譯成英文的;少數幾句,是說給翻譯聽得,告訴他如何翻譯。

END 是編譯結束偽指令,用於通知編譯器已經到了源程序的結尾,每個完整的匯編語言源程序中都必須有一個 END 偽指令定義源程序結尾。編譯程序檢測到這個偽指令後,不再對後面的程序編譯。

『陸』 預處理類型

1. 預處理程序

按照ANSI標準的定義,預處理程序應該處理以下指令:

#if #ifdef #ifndef #else #elif

#endif

#define

#undef

#line

#error

#pragma

#include

顯然,上述所有的12個預處理指令都以符號#開始,,每條預處理指令必須獨佔一行。

2. #define

#define指令定義一個標識符和一個串(也就是字元集),在源程序中發現該標識符時,都用該串替換之。這種標識符稱為宏名字,相應的替換稱為宏代換。一般形式如下:

#define macro-name char-sequence

這種語句不用分號結尾。宏名字和串之間可以有多個空白符,但串開始後只能以新行終止。

例如:我們使用LEFT代表1,用RIGHT代表0,我們使用兩個#define指令:

#define LEFT 1

#define RIGHT 0

每當在源程序中遇到LEFT或RIGHT時,編譯程序都用1或0替換。

定義一個宏名字之後,可以在其他宏定義中使用,例如:

#define ONE 1

#define TWO ONE+ONE

#define THREE ONE+TWO

宏代換就是用相關的串替代標識符。因此,如果希望定義一條標准錯誤信息時,可以如下定義:

#define ERROR_MS 「Standard error on input \n」

如果一個串長於一行,可在行尾用反斜線」\」續行,如下:

#define LONG_STRING 「This is a very very long \

String that is used as an example」

3. #error

#error指令強制編譯程序停止編譯,它主要用於程序調試。#error指令的一般形式是:

#error error-message

注意,宏串error-message不用雙引號包圍。遇到#error指令時,錯誤信息被顯示,可能同時還顯示編譯程序作者預先定義的其他內容。

4. #include

程序中的#include指令要求編譯程序讀入另一個源文件。被讀入文件的名字必須用雙引號(「」)或一對尖括弧(<>)包圍,例如:

#include 「stdio.h」

#include 都使C編譯程序讀入並編譯頭文件以用於I/O系統庫函數。

包含文件中可以包含其他#include指令,稱為嵌套包含。允許的最大嵌套深度隨編譯器而變。

文件名被雙括弧或尖括弧包圍決定了對指定文件的搜索方式。文件名被尖括弧包圍時,搜索按編譯程序作者的定義進行,一般用於搜索某些專門放置包含文件的特殊目錄。當文件名被雙括弧包圍時,搜索按編譯程序實時的規定進行,一般搜索當前目錄。如未發現,再按尖括弧包圍時的辦法重新搜索一次。

通常,絕大多數程序員使用尖括弧包圍標準的頭文件,雙引號用於包圍與當前程序相關的文件名。

5. 條件編譯指令

若干編譯指令允許程序員有選擇的編譯程序源代碼的不同部分,這種過程稱為條件編譯。

5.1#if、#else、#elif #endif

條件編譯指令中最常用的或許是#if,#else,#elif和#endif。這些指令允許程序員根據常數表達式的結果有條件的包圍部分代碼。

#if的一般形式是:

#if constant-expression

Statement sequence

#endif

如#if後的常數表達式為真,則#if和#endif中間的代碼被編譯,否則忽略該代碼段。#endif標記#if塊的結束。

#else指令的作用與C語言的else相似,#if指令失敗時它可以作為備選指令。例如:

#include #define MAX 100

Int main(void)

{
#if MAX>99

printf(「Compiled for array greater than 99.\n」);

#else

printf(「Complied for small array.\n」);

#endif

return 0;

}

注意,#else既是標記#if塊的結束,也標記#else塊的開始。因為每個#if只能寫一個#endif匹配。

#elif指令的意思是「否則,如果」,為多重編譯選擇建立一條if-else-if(如果-否則-如果鏈)。如果#if表達式為真,該代碼塊被編譯,不測試其他#elif表達式。否則,序列中的下一塊被測試,如果成功則編譯之。一般形式如下:

#if expression

Statement sequence

#elif expression1

Statement sequence

#elif expression2

Statement sequence

.

.

.

#elif expression

Statement sequence

#endif

5.2#ifdef和#ifndef

條件編譯的另一個方法是使用編譯指令#ifdef和#ifndef,分別表示「如果已定義」和「如果未定義」。#ifdef的一般形式如下:

#ifdef macro-name

Statement sequence

#endif

如果macro-name原先已經被一個#define語句定義,則編譯其中的代碼塊。

#ifndef的一般形式是:

#ifndef macro-name

Statement sequence

#endif

如果macro-name當前未被#define語句定義,則編譯其中的代碼塊。

我認為,用這種,可以很方便的開啟/關閉整個程序的某項特定功能。

#ifdef和#ifndef都可以使用#else或#elif語句。

#inlucde #define T 10

Int main(void)

{
#ifdef t

Printf(「Hi T\n」);

#else

Printf(「Hi anyone\n」);

#endif

#ifndef M

Printf(「M Not Defined\n」);

#endif

Return 0;

}

6. #undef

#undef指令刪除前面定義的宏名字。也就是說,它「不定義」宏。一般形式為:

#undef macro-name

7. 使用defined

除#ifdef之外,還有另外一種確定是否定義宏名字的方法,即可以將#if指令與defined編譯時操作符一起使用。defined操作符的一般形式如下:

defined macro-name

如果macro-name是當前定義的,則表達式為真,否則為假。

例如,確定宏MY是否定義,可以使用下列兩種預處理命令之一:

#if defined MY



#ifdef MY

也可以在defined之前加上感嘆號」!」來反轉相應的條件。例如,只有在DEBUG未定義的情況下才編譯。

#if !defined DEBUG

Printf(「Final Version!\n」);

#endif

使用defined的一個原因是,它允許由#elif語句確定的宏名字存在。

8. #line

#line指令改變__LINE__和__FILE__的內容。__LINE__和__FILE__都是編譯程序中預定義的標識符。標識符__LINE__的內容是當前被編譯代碼行的行號,__FILE__的內容是當前被編譯源文件的文件名。#line的一般形式是:

#line number 「filename」

其中,number是正整數並變成__LINE__的新值;可選的「filename」是合法文件標識符並變成__FILE__的新值。#line主要用於調試和特殊應用。

9. #pragma

#pragma是編譯程序實現時定義的指令,它允許由此向編譯程序傳入各種指令。例如,一個編譯程序可能具有支持跟蹤程序執行的選項,此時可以用#pragma語句選擇該功能。編譯程序忽略其不支持的#pragma選項。#pragma提高C源程序對編譯程序的可移植性。

10. 預處理操作符#和##

有兩個預處理操作符:#和##,它們可以在#define中使用。

操作符#通常稱為字元串化的操作符,它把其後的串變成用雙引號包圍的串。例如:

#include #define mkstr(s) #s

int main(void)

{
Printf(mkstr(I like C));

Return 0;

}

預處理程序把以下的語句:

Printf(mkstr(I like C));

變成

Printf(「I like C」);

操作符##把兩個標記拼在一起,形成一個新標記。例如:

#include #define concat(a,a) a##b

int main(void)

{
Int xy = 10;

Printf(「%d」,concat(x,y));

Return 0;

}

預處理程序把以下語句:

Printf(「%d」,concat(x,y));

變成

Printf(「%d」,xy);

操作符#和##主要作用是允許預處理程序對付某些特殊情況,多數程序中並不需要。

11. 預定義宏

C規范了5個固有的預定義宏,它們是:

__LINE__

__FILE__

__DATE__

__TIME__

__STDC__

__LINE__和__FILE__包含正在編譯的程序的行號和文件名。

__DATE__和內容形如month/day/year(月/日/年)的串,代表源文件翻譯成目標碼的日期。

__TIME__中的串代表源代碼編譯成目標碼的時間,形如hour:minute:second(時:分:秒)

如果__STDC__的內容是十進制常數1,則表示編譯程序的實現符合標准C。

『柒』 單片機,的結束只指今是

准確的說是偽指令,為END,目的是「告訴」編譯器,「程序結束,到此為止,不用往下編譯了。」

熱點內容
低次配有哪些配置 發布:2022-07-05 15:34:04 瀏覽:486
golang編譯二進制文件保護 發布:2022-07-05 15:33:56 瀏覽:227
vs選擇文件夾 發布:2022-07-05 15:33:05 瀏覽:507
寫php代碼 發布:2022-07-05 15:32:50 瀏覽:245
安卓10如何找開發者選項 發布:2022-07-05 15:31:11 瀏覽:348
2g換卡服務密碼為什麼不正確 發布:2022-07-05 15:29:31 瀏覽:29
vsstudio編譯和生成 發布:2022-07-05 15:29:24 瀏覽:164
手機微信多應該有個什麼配置 發布:2022-07-05 15:29:15 瀏覽:787
如何查找郵箱伺服器地址 發布:2022-07-05 15:29:02 瀏覽:728
雲服務密碼是什麼密碼是什麼樣的 發布:2022-07-05 15:27:53 瀏覽:439