第一篇:C語言源程序至可執(zhí)行文件步驟[范文模版]
C/C++程序編譯步驟如何生成可執(zhí)行文件
電子計算機所使用的是由“0”和“1”組成的二進制數(shù),二進制是計算機的語言的基礎。計算機發(fā)明之初,人們只能降貴紆尊,用計算機的語言去命令計算機干這干那,一句話,就是寫出一串串由“0”和“1”組成的指令序列交由計算機執(zhí)行,這種語言,就是機器語言。想象一下老前輩們在打孔機面前數(shù)著一個一個孔的情景,噓,小聲點,你的驚嚇可能使他們錯過了一個孔,結果可能是導致一艘飛船飛離軌道阿。
為了減輕使用機器語言編程的痛苦,人們進行了一種有益的改進:用一些簡潔的英文字母、符號串來替代一個特定的指令的二進制串,比如,用“A D D”代表加法,“MO V”代表數(shù)據(jù)傳遞等等,這樣一來,人們很容易讀懂并理解程序在干什么,糾錯及維護都變得方便了,這種程序設計語言就稱為匯編語言,即第二代計算機語言。然而計算機是不認識這些符號的,這就需要一個專門的程序,專門負責將這些符號翻譯成二進制數(shù)的機器語言,這種翻譯程序被稱為匯編程序。因為匯編指令和機器語言之間有著一一對應的關系,這可比英譯漢或漢譯英簡單多了。
高級語言是偏向人,按照人的思維方式設計的,機器對這些可是莫名奇妙,不知所謂。魚與熊掌的故事在計算機語言中發(fā)生了。于是必須要有一個橋梁來銜接兩者,造橋可不是一件簡單的事情。當你越想方便,那橋就得越復雜。那高級語言是如何變成機器語言的呢,這個過程讓我慢慢道來。
編譯:將源代碼轉換為機器可認識代碼的過程。編譯程序讀取源程序(字符流),對之進行詞法和語法的分析,將高級語言指令轉換為功能等效的匯編代碼,再由匯編程序轉換為機器語言,并且按照操作系統(tǒng)對可執(zhí)行文件格式的要求鏈接生成可執(zhí)行程序。C源程序->編譯預處理->編譯->優(yōu)化程序->匯編程序->鏈接程序->可執(zhí)行文件1.編譯預處理 讀取c源程序,對其中的偽指令(以#開頭的指令)和特殊符號進行處理。偽指令主要包括以下四個方面:(1)宏定義指令,如# define Name TokenString,#undef等。對于前一個偽指令,預編譯所要作得的是將程序中的所有Name用TokenString替換,但作為字符串常量的Name則不被替換。對于后者,則將取消對某個宏的定義,使以后該串的出現(xiàn)不再被替換。
(2)條件編譯指令,如#ifdef,#ifndef,#else,#elif,#endif,等等。這些偽指令的引入使得程序員可以通過定義不同的宏來決定編譯程序對哪些代碼進行處理。預編譯程序將根據(jù)有關的文件,將那些不必要的代碼過濾掉。
(3)頭文件包含指令,如#include “FileName”或者#include
(4)特殊符號,預編譯程序可以識別一些特殊的符號。例如在源程序中出現(xiàn)的LINE標識將被解釋為當前行號(十進制數(shù)),F(xiàn)ILE則被解釋為當前被編譯的C源程序的名稱。預編譯程序對于在源程序中出現(xiàn)的這些串將用合適的值進行替換。預編譯程序所完成的基本上是對源程序的“替代”工作。經(jīng)過此種替代,生成一個沒有宏定義、沒有條件編譯指令、沒有特殊符號的輸出文件。這個文件的含義同沒有經(jīng)過預處理的源文件是相同的,但內(nèi)容有所不同。下一步,此輸出文件將作為編譯程序的輸出而被翻譯成為機器指令。2.編譯階段
經(jīng)過預編譯得到的輸出文件中,將只有常量。如數(shù)字、字符串、變量的定義,以及C語言 的關鍵字,如main,if,else,for,while,{,},+,-,*,,等等。預編譯程序所要作得工作就是通過詞法分析和語法分析,在確認所有的指令都符合語法規(guī)則之后,將其翻譯成等價的中間代碼表示或匯編代碼。3.優(yōu)化階段
優(yōu)化處理是編譯系統(tǒng)中一項比較艱深的技術。它涉及到的問題不僅同編譯技術本身有關,而且同機器的硬件環(huán)境也有很大的關系。優(yōu)化一部分是對中間代碼的優(yōu)化。這種優(yōu)化不依賴于具體的計算機。另一種優(yōu)化則主要針對目標代碼的生成而進行的。上圖中,我們將優(yōu)化階段放在編譯程序的后面,這是一種比較籠統(tǒng)的表示。
對于前一種優(yōu)化,主要的工作是刪除公共表達式、循環(huán)優(yōu)化(代碼外提、強度削弱、變換 循環(huán)控制條件、已知量的合并等)、復寫傳播,以及無用賦值的刪除,等等。后一種類型的優(yōu)化同機器的硬件結構密切相關,最主要的是考慮是如何充分利用機器的各個硬件寄存器存放的有關變量的值,以減少對于內(nèi)存的訪問次數(shù)。另外,如何根據(jù)機器硬件執(zhí)行指令的特點(如流水線、RISC、CISC、VLIW等)而對指令進行一些調整使目標代碼比較短,執(zhí)行的效率比較高,也是一個重要的研究課題。經(jīng)過優(yōu)化得到的匯編代碼必須經(jīng)過匯編程序的匯編轉換成相應的機器指令,方可能被機器執(zhí)行。4.匯編過程
匯編過程實際上指把匯編語言代碼翻譯成目標機器指令的過程。對于被翻譯系統(tǒng)處理的每一個C語言源程序,都將最終經(jīng)過這一處理而得到相應的目標文件。目標文件中所存放的也就是與源程序等效的目標的機器語言代碼。目標文件由段組成。通常一個目標文件中至少有兩個段:
代碼段 該段中所包含的主要是程序的指令。該段一般是可讀和可執(zhí)行的,但一般卻不可寫。數(shù)據(jù)段 主要存放程序中要用到的各種全局變量或靜態(tài)的數(shù)據(jù)。一般數(shù)據(jù)段都是可讀,可寫,可執(zhí)行的。
UNIX環(huán)境下主要有三種類型的目標文件:
(1)可重定位文件 其中包含有適合于其它目標文件鏈接來創(chuàng)建一個可執(zhí)行的或者共享 的目標文件的代碼和數(shù)據(jù)。
(2)共享的目標文件 這種文件存放了適合于在兩種上下文里鏈接的代碼和數(shù)據(jù)。第一 種事鏈接程序可把它與其它可重定位文件及共享的目標文件一起處理來創(chuàng)建另一個目標文 件;第二種是動態(tài)鏈接程序將它與另一個可執(zhí)行文件及其它的共享目標文件結合到一起,創(chuàng)建一個進程映象。
(3)可執(zhí)行文件 它包含了一個可以被操作系統(tǒng)創(chuàng)建一個進程來執(zhí)行之的文件。
匯編程序生成的實際上是第一種類型的目標文件。對于后兩種還需要其他的一些處理方能 得到,這個就是鏈接程序的工作了。5.鏈接程序
由匯編程序生成的目標文件并不能立即就被執(zhí)行,其中可能還有許多沒有解決的問題。例 如,某個源文件中的函數(shù)可能引用了另一個源文件中定義的某個符號(如變量或者函數(shù)調 用等);在程序中可能調用了某個庫文件中的函數(shù),等等。所有的這些問題,都需要經(jīng)鏈 接程序的處理方能得以解決。
鏈接程序的主要工作就是將有關的目標文件彼此相連接,也即將在一個文件中引用的符號 同該符號在另外一個文件中的定義連接起來,使得所有的這些目標文件成為一個能夠被操 作系統(tǒng)裝入執(zhí)行的統(tǒng)一整體。
根據(jù)開發(fā)人員指定的同庫函數(shù)的鏈接方式的不同,鏈接處理可分為兩種:
(1)靜態(tài)鏈接 在這種鏈接方式下,函數(shù)的代碼將從其所在地靜態(tài)鏈接庫中被拷貝到最 終的可執(zhí)行程序中。這樣該程序在被執(zhí)行時這些代碼將被裝入到該進程的虛擬地址空間中。靜態(tài)鏈接庫實際上是一個目標文件的集合,其中的每個文件含有庫中的一個或者一組相 關函數(shù)的代碼。
(2)動態(tài)鏈接 在此種方式下,函數(shù)的代碼被放到稱作是動態(tài)鏈接庫或共享對象的某個 目標文件中。鏈接程序此時所作的只是在最終的可執(zhí)行程序中記錄下共享對象的名字以及 其它少量的登記信息。在此可執(zhí)行文件被執(zhí)行時,動態(tài)鏈接庫的全部內(nèi)容將被映射到運行 時相應進程的虛地址空間。動態(tài)鏈接程序將根據(jù)可執(zhí)行程序中記錄的信息找到相應的函數(shù) 代碼。
對于可執(zhí)行文件中的函數(shù)調用,可分別采用動態(tài)鏈接或靜態(tài)鏈接的方法。使用動態(tài) 鏈接能夠使最終的可執(zhí)行文件比較短小,并且當共享對象被多個進程使用時能節(jié)約一些內(nèi) 存,因為在內(nèi)存中只需要保存一份此共享對象的代碼。但并不是使用動態(tài)鏈接就一定比使 用靜態(tài)鏈接要優(yōu)越。在某些情況下動態(tài)鏈接可能帶來一些性能上損害。
經(jīng)過上述五個過程,C源程序就最終被轉換成可執(zhí)行文件了
上一節(jié)我們介紹了編程語言的種類,其中包括機器語言、匯編語言和高級語言。
C/C++程序編譯步驟詳解
C/C++語言很多人都比較熟悉,這基本上是每位大學生必學的一門編程語言,通常還都是 作為程序設計入門語言學的,并且課程大多安排在大一。剛上大學,孩子們還都很乖,學習也比較認真,用心。所以,C/C++語言掌握地也都不錯,不用說編譯程序,就是寫個上 幾百行的程序都不在話下,但是他們真的知道C/C++程序編譯的步驟么?
我想很多人都不甚清楚,如果他接下來學過“編譯原理”,也許能說個大概。VC的“舒適 ”開發(fā)環(huán)境屏蔽了很多編譯的細節(jié),這無疑降低了初學者的入門門檻,但是也“剝奪”了 他們“知其所以然”的權利,致使很多東西只能死記硬背,遇到相關問題就“丈二”。實 際上,我也是在學習Linux環(huán)境下編程的過程中才逐漸弄清楚C/C++源代碼是如何一步步變 成可執(zhí)行文件的。
總體來說,C/C++源代碼要經(jīng)過:預處理、編譯、匯編和鏈接四步才能變成相應平臺下的 可執(zhí)行文件。大多數(shù)時候,程序員通過一個命令就能完成上述四個步驟。比如下面這段C 的“Hello world!”代碼: File: hw.c #include stdio.h> int main(intargc, char *argv[]){ printf(”Hello World!n“);return 0;} 如果用gcc編譯,只需要一個命令就可以生成可執(zhí)行文件hw: xiaosuo@gentuxhw $ gcc-o hwhw.c xiaosuo@gentuxhw $./hw Hello World!我們可以用-v參數(shù)來看看gcc到底在背后都做了些什么動作: Reading specs from /usr/lib/gcc/i686-pc-linux-gnu/3.4.6/specs Configured with: /var/tmp/portage/sys-devel/gcc-3.4.6-r2/work/gcc-3.4.6/configure--prefix=/usr--bindir=/usr/i686-pc-linux-gnu/gcc-bin/3.4.6-disable-altivec--enable-nls--without-included-gettext--with-system-zlib-enable-shared--enable-threads=posix--enable-__cxa_atexit--enable-clocale=gnu Thread model: posix gcc version 3.4.6(Gentoo 3.4.6-r2, ssp-3.4.6-1.0, pie-8.7.10)/usr/libexec/gcc/i686-pc-linux-gnu/3.4.6/cc1-quiet-v hw.c-quiet-dumpbase hw.c-mtune=pentiumpro-auxbasehw-version-o /tmp/ccYB6UwR.s ignoring nonexistent directory ”/usr/local/include“ ignoring nonexistent directory ”/usr/lib/gcc/i686-pc-linux-gnu/3.4.6/../../../../i686-pc-linux-gnu/include“ #include ”...“ search starts here: #include...> search starts here: /usr/lib/gcc/i686-pc-linux-gnu/3.4.6/include /usr/include End of search list.GNU C version 3.4.6(Gentoo 3.4.6-r2, ssp-3.4.6-1.0, pie-8.7.10)(i686-pc-linux-gnu)compiled by GNU C version 3.4.6(Gentoo 3.4.6-r2, ssp-3.4.6-1.0, pie-8.7.9).GGC heuristics:--paramggc-min-expand=81--paramggc-min-heapsize=97004 /usr/lib/gcc/i686-pc-linux-gnu/3.4.6/../../../../i686-pc-linux-gnu/bin/as-V-Qy-o /tmp/ccq8uGED.o /tmp/ccYB6UwR.s GNU assembler version 2.17(i686-pc-linux-gnu)using BFD version 2.17 /usr/libexec/gcc/i686-pc-linux-gnu/3.4.6/collect2--eh-frame-hdr-m elf_i386-dynamic-linker /lib/ld-linux.so.2-o hw /usr/lib/gcc/i686-pc-linux-gnu/3.4.6/../../../crt1.o /usr/lib/gcc/i686-pc-linux-gnu/3.4.6/../../../crti.o /usr/lib/gcc/i686-pc-linux-gnu/3.4.6/crtbegin.o-L/usr/lib/gcc/i686-pc-linux-gnu/3.4.6-L/usr/lib/gcc/i686-pc-linux-gnu/3.4.6-L/usr/lib/gcc/i686-pc-linux-gnu/3.4.6/../../../../i686-pc-linux-gnu/lib-L/usr/lib/gcc/i686-pc-linux-gnu/3.4.6/../../../tmp/ccq8uGED.o-lgcc--as-needed-lgcc_s--no-as-needed-lc-lgcc--as-needed-lgcc_s--no-as-needed /usr/lib/gcc/i686-pc-linux-gnu/3.4.6/crtend.o /usr/lib/gcc/i686-pc-linux-gnu/3.4.6/../../../crtn.o 稍微整理一下,去掉一些冗余信息后,如下: cc1 hw.c-o /tmp/ccYB6UwR.s as-o /tmp/ccq8uGED.o /tmp/ccYB6UwR.s ld-o hw /tmp/ccq8uGED.o 以上三個命令分別對應于編譯步驟中的預處理+編譯、匯編和連接。預處理和編譯還是放 在了一個命令(cc1)中進行的,可以把它再次拆分為以下兩步: cpp-o hw.ihw.c cc1 hw.i-o /tmp/ccYB6UwR.s 一個精簡過的能編譯以上hw.c文件的Makefile如下:.PHONY: clean all: hw hw: hw.o ld-dynamic-linker /lib/ld-linux.so.2-o hw /usr/lib/crt1.o /usr/lib/crti.o /usr/lib/gcc/i686-pc-linux-gnu/3.4.6/crtbegin.o hw.o-lc /usr/lib/gcc/i686-pc-linux-gnu/3.4.6/crtend.o /usr/lib/crtn.o hw.o: hw.s as-o hw.ohw.s hw.s: hw.i /usr/libexec/gcc/i686-pc-linux-gnu/3.4.6/cc1-o hw.shw.c hw.i: hw.c cpp-o hw.ihw.c clean: rm-rfhw.ihw.shw.o 當然,上面Makefile中的一些路徑是我系統(tǒng)上的具體情況,你的可能與我的不同。接下來我們按照編譯順序看看編譯器每一步都做了什么。首先是預處理,預處理后的文件hw.i: # 1 ”hw.c“ # 1 ”“ # 1 ”“...__extension__ typedef __quad_t __off64_t;__extension__ typedefint __pid_t;__extension__ typedefstruct { int __val[2];} __fsid_t;...extern int remove(__const char *__filename)__attribute__((__nothrow__));extern int rename(__const char *__old, __const char *__new)__attribute__((__nothrow__));...int main(intargc, char *argv[]){ printf(”Hello World!n“);return 0;} 注:由于文件比較大,所以只留下了少部分具有代表性的內(nèi)容。
可以看見預處理器把所有要包含(include)的文件(包括遞歸包含的文件)的內(nèi)容都添 加到了原始的C源文件中,然后把其輸出到輸出文件,除此之外,它還展開了所有的宏定 義,所以在預處理器的輸出文件中你將找不到任何宏。這也提供了一個查看宏展開結果的 簡便方法。
第二步“編譯”,就是把C/C++代碼“翻譯”成匯編代碼:.file ”hw.c“.section.rodata.LC0:.string ”Hello World!n“.text.globl main.type main, @function main: pushl?p movl %esp, ?p subl $8, %esp andl $-16, %esp movl $0, ?x addl $15, ?x addl $15, ?x shrl $4, ?x sall $4, ?x subl?x, %esp subl $12, %esp pushl $.LC0 call printf addl $16, %esp movl $0, ?x leave ret.size main,.-main.section.note.GNU-stack,”“,@progbits.ident ”GCC:(GNU)3.4.6(Gentoo 3.4.6-r2, ssp-3.4.6-1.0, pie-8.7.10)" 這個匯編文件比預處理后的C/C++文件小了很多,去除了很多不必要的東西,比如說沒用 到的類型聲明和函數(shù)聲明等。
第三步“匯編”,將第二步輸出的匯編代碼翻譯成符合一定格式的機器代碼,在Linux上 一般表現(xiàn)為ELF目標文件。xiaosuo@gentuxhw $ file hw.o hw.o: ELF 32-bit LSB relocatable, Intel 80386, version 1(SYSV), not stripped 最后一步“連接”,將上步生成的目標文件和系統(tǒng)庫的目標文件和庫文件連接起來,最終 生成了可以在特定平臺運行的可執(zhí)行文件。為什么還要連接系統(tǒng)庫中的某些目標文件(crt1.o, crti.o等)呢?這些目標文件都是用來初始化或者回收C運行時環(huán)境的,比如
說堆內(nèi)存分配上下文環(huán)境的初始化等,實際上crt也正是C RunTime的縮寫。這也暗示了另 外一點:程序并不是從main函數(shù)開始執(zhí)行的,而是從crt中的某個入口開始的,在Linux上
此入口是_start。以上Makefile生成的是動態(tài)連接的可執(zhí)行文件,如果要生成靜態(tài)連接的 可執(zhí)行文件需要將Makefile中的相應段修改: hw: hw.o ld-m elf_i386-static-o hw /usr/lib/crt1.o /usr/lib/crti.o /usr/lib/gcc/i686-pc-linux-gnu/3.4.6/crtbeginT.o-L/usr/lib/gcc/i686-pc-linux-gnu/3.4.6-L/usr/i686-pc-linux-gnu/lib-L/usr/lib/ hw.o--start-group-lgcc-lgcc_eh-lc--end-group /usr/lib/gcc/i686-pc-linux-gnu/3.4.6/crtend.o /usr/lib/gcc/i686-pc-linux-gnu/3.4.6/../../../crtn.o 至此,一個可執(zhí)行文件才最終創(chuàng)建完成。通常的項目中并不需要把編譯過程分得如此之細,前三步一般是合為一體的,在Makefile中表現(xiàn)如下: hw.o: hw.c gcc-o hw.o-c hw.c 實際上,如果對hw.c進行了什么更改,那么前三步大多數(shù)情況下都是不可避免的。所以把 他們寫在一起也并沒有什么壞處,相反倒可以用--pipe參數(shù)告訴編譯器用管道替代臨時文 件,從而提升編譯的效率。
第二篇:c語言源程序
基于單片機msp430和溫度傳感器ds18b20的水溫度控制系統(tǒng)的c語言源程序(不是測量,要有加熱跟制冷)
我這是用STC做的,應該很容易移植到MPS430上的給你參考一下。#include
sbit scl=P1^3;sbit sda=P1^4;
sbit key1=P1^6;sbit key2=P1^7;sbit key3=P2^0;sbit key4=P2^1;
sbit lcrs=P3^7;//數(shù)據(jù)/命令 sbit lcwr=P3^5;//讀/寫 sbit lcden=P3^4;//使能
sbit DS=P2^2;
/*sbit lcrs=P3^4;//數(shù)據(jù)/命令 sbit lcwr=P3^7;//讀/寫 sbit lcden=P3^5;//使能 */ sbit jrk=P2^2;sbit cyk=P2^3;sbit xhk=P2^4;bit flag=0,rsg=0,not=0,he=0,in=0;int acon=0,bcon=0,dcon=0,econ=0, temp=0,y=0,j=0,l=0,cfj=0,ec=0,dc=0,at;uchar code table[]={48,49,50,51,52,53,54,55,56,57};uchar code ta1[]={“Temperature UP”};uchar code ta2[]={“Temperature DN”};uchar code ta3[]={“Inflator Cycle”};uchar code ta4[]={“Inflator Time ”};uchar code ta5[]={“ Heating UP ”};uchar code ta6[]={“ Inflator ”};uchar code table7[]={“Temperature”};uchar table1[]={0,0,0,'.',0};uchar table3[]={“AptitudeAquarium”};uchar table4[]={0,0,0,0,0};uchar n,c=0;void delay(uchar);void wen_kong();void xh();void rso();void weno();
void Init_Com(void){ TMOD = 0x11;PCON = 0x00;TH1=0x61;TL1=0x99;EA=1;ET1=1;TR1=1;} void delay(uchar count)//delay { uint i;while(count){ i=200;while(i>0)i--;count--;} } ////初始化18B20///////// bit init18b20(void){ uint i;bit no;DS=0;i=103;while(i>0)i--;DS=1;i=4;while(i>0)i--;no=DS;if(no==0){ DS=1;i=100;while(i>0)i--;no=DS;if(no==1)not=0;else not=1;} else not=1;return(not);}
bit tmpread()bit(void)//讀一位
{ uint i;bit dat;DS=0;i++;DS=1;i++;i++;dat=DS;i=8;while(i>0)i--;return(dat);}
uchar tmpread()(void)//讀一個字節(jié) { uchar i,j,dat;dat=0;for(i=1;i<=8;i++){ j=tmpread()bit();dat=(j<<7)|(dat>>1);//讀出的數(shù)據(jù)最低位在最前面,這樣剛好一個字節(jié)在DAT里
} return(dat);}
void tmpwritebyte(uchar dat)//寫一個字節(jié)到 ds18b20 { uint i;uchar j;bit testb;for(j=1;j<=8;j++){ testb=dat&0x01;dat=dat>>1;if(testb)//write 1 { DS=0;i++;i++;DS=1;i=8;while(i>0)i--;} else { DS=0;//write 0 i=8;while(i>0)i--;DS=1;i++;i++;} } }
int tmp()//DS18B20溫度讀取 { float tt;int a,b;if(init18b20()==0){ WDT_CONTR=0x36;/////喂狗 EA=0;delay(1);
tmpwritebyte(0xcc);// 跳過讀ROM操作 tmpwritebyte(0x44);// 啟動溫度轉換 delay(10);init18b20();delay(1);tmpwritebyte(0xcc);tmpwritebyte(0xbe);a=tmpread();b=tmpread();temp=b;temp<<=8;//將高字節(jié)溫度數(shù)據(jù)與低字節(jié)溫度數(shù)據(jù)整合 temp=temp|a;c=b>>4;
tt=temp*0.0625;
temp=tt*10+0.5;//放大10倍輸出并四舍五入 EA=1;return temp;} else not=1;}
//////1062///////// void ydelay(uint x){ uint a,b;for(a=x;a>0;a--)for(b=10;b>0;b--);} void write_com(uchar com){ P0=com;lcwr=0;lcrs=0;lcden=0;ydelay(10);lcden=1;ydelay(10);lcden=0;lcwr=1;}
void write_date(uchar date)//寫數(shù)據(jù) {
P0=date;lcwr=0;lcrs=1;lcden=0;ydelay(10);lcden=1;ydelay(10);lcden=0;lcwr=1;}
void init1602()//初始化 { write_com(0x38);//設置顯示模式 ydelay(20);write_com(0x0c);//開顯示 ydelay(20);write_com(0x06);//指針和光標自動加一 ydelay(20);write_com(0x01);//清屏指令 ydelay(20);}
///////顯示程序////// void display(int num){ uint i,A1,A2;WDT_CONTR=0x35;/////喂狗 if(c!=0)num=~num+1;A1=num/1000;A2=num%1000/100;if(not==0){
if(c!=0){ c=0;table1[0]='-';} else if(A1==0)table1[0]=' ';else
table1[0]=table[A1];if(A1==0)if(A2==0)table1[1]=' ';else table1[1]=table[A2];
table1[2]=table[num%1000%100/10];table1[4]=table[num%1000%100%10];} else { table1[0]='?';table1[1]='?';table1[2]='?';table1[4]='?';}
write_com(0x80);for(i=0;i<11;i++){write_date(table7[i]);delay(2);} write_com(0x8b);for(i=0;i<5;i++){write_date(table1[i]);delay(2);} write_com(0xc0);for(i=0;i<16;i++){ if(he==1)write_date(ta5[i]);else if(in==1)write_date(ta6[i]);else write_date(table3[i]);} c=0;WDT_CONTR=0x35;/////喂狗 } ////顯示2//////////////////// display2(uchar bh,int dat){ uchar a,A,B;WDT_CONTR=0x35;/////喂狗 //write_com(0x01);//清屏指令 y=dat;y=y&0x8000;if(y!=0)dat=~dat+1;A=dat/1000;B=dat%1000/100;if((bh!=4)&&(bh!=5)){ if(A!=0)table4[0]=table[dat/1000];else if((c!=0)||(y!=0)){ c=0;y=0;table4[0]='-';} else table4[0]=' ';if(B!=0)table4[1]=table[B];else table4[1]=' ';table4[2]=table[dat%1000%100/10];table4[3]='.';table4[4]=table[dat%1000%100%10];} else { table4[0]=' ';if((c!=0)||(y!=0)){ c=0;y=0;table4[1]='-';} else table4[1]=' ';table4[2]=' ';table4[3]=table[dat%1000%100/10];table4[4]=table[dat%1000%100%10];}
write_com(0xc4);delay(2);for(a=0;a<5;a++)write_date(table4[a]);delay(2);write_com(0x80);switch(bh){ case 1:for(a=0;a<14;a++)write_date(ta1[a]);break;case 2:for(a=0;a<14;a++)write_date(ta2[a]);break;case 3:for(a=0;a<14;a++)write_date(ta3[a]);break;case 4:for(a=0;a<14;a++)write_date(ta4[a]);break;default:break;} }
///////////x24c02////////////////// void delay24(){;;}
void init24c02()//初始化 { sda=1;delay24();scl=1;delay24();}
void start()//開始信號 { sda=1;delay24();scl=1;delay24();sda=0;delay24();}
void stop()//停止 { sda=0;delay24();scl=1;delay24();sda=1;delay24();}
void respons()//應答 { uchar i;scl=1;delay24();while((sda==1)&&(i<250))i++;scl=0;delay24();}
void write_byte(uchar date)// 寫數(shù)據(jù)子函數(shù) { uchar i,temp;temp=date;
for(i=0;i<8;i++){ temp=temp<<1;scl=0;delay24();sda=CY;delay24();scl=1;delay24();} scl=0;delay24();sda=1;delay24();}
uchar read_byte()// 讀數(shù)據(jù)子函數(shù) { uchar i,k;scl=0;delay24();sda=1;delay24();for(i=0;i<8;i++){ scl=1;delay24();k=(k<<1)|sda;scl=0;delay24();} return k;} ///////寫數(shù)據(jù)函數(shù)/////////////////// void write_add(uchar address,uint date){ start();write_byte(0xa0);respons();write_byte(address);respons();write_byte(date/256);respons();write_byte(date%256);respons();stop();} uchar read_add(uchar address)//讀數(shù)據(jù)函數(shù) { uchar date;start();write_byte(0xa0);respons();write_byte(address);respons();start();write_byte(0xa1);respons();date=read_byte();stop();return date;}
void delay1ms(uchar ms){
uchar i;while(ms--){ for(i = 0;i< 250;i++){ _nop_();_nop_();_nop_();_nop_();} } }
int keyf(int *num,int up,int dn){ uint i;uchar z;for(i=0;i<600;i++){
display2(n,*num);if(key1==0){ delay1ms(30);if(key1==0){ i=0;n++;if(n>=9)n=0;while(!key1)display2(n,*num);break;} } if(key2==0){
delay1ms(10);if(key2==0){ i=0;if(*num>=up)*num=up;else if(n!=4)*num=*num+1;else if(*num<100)*num=*num+5;else
*num=*num+10;for(z=0;z<65;z++){ display2(n,*num);if(key2!=0)break;} while(!key2){ for(z=0;z<2;z++)display2(n,*num);if(*num>=up)*num=up;else if(n!=4)*num=*num+1;else if(*num<100)*num=*num+5;else
*num=*num+10;} } }
if(key3==0){ delay1ms(10);if(key3==0){ i=0;if(*num<=dn)*num=dn;else if(n!=4)*num=*num-1;else if(*num<100)*num=*num-5;else
*num=*num-10;for(z=0;z<65;z++){ display2(n,*num);if(key3!=0)break;} while(!key3){ for(z=0;z<2;z++)display2(n,*num);if(*num<=dn)*num=dn;else if(n!=4)*num=*num-1;else if(*num<100)*num=*num-5;else
*num=*num-10;} } } } return(*num);} void keyjc(){ uchar i=0;if(key1==0){ delay1ms(10);if(key1==0){ EA=0;
for(i=0;i<20;i++){
display(tmp());} if(key1==0){
write_com(0x01);//清屏指令
n++;if(n>=5)n=0;while(!key1){ switch(n){ case 1:display2(n,acon);break;case 0:break;} } if(n==1){ keyf(&acon,1250,-530);if((acon-bcon)<3)bcon=acon-3;} if(n==2){ keyf(&bcon,1240,-550);if((acon-bcon)<3)acon=bcon+3;} write_add(1,acon);//A delay1ms(15);write_add(3,bcon);//B n=0;write_com(0x01);//清屏指令 } EA=1;} } }
key(){ uint i;if(key4==0)delay1ms(50);if(key4==0){ write_com(0x01);//清屏指令
for(i=0;i<500;i++){ if(key4==0){ delay1ms(15);if(key4==0){ i=0;n++;if(n>=5)n=0;while(!key4){ switch(n){ case 1: display2(1,acon);break;case 2: display2(2,bcon);break;default: break;} } } } switch(n){ case 1: display2(1,acon);break;case 2: display2(2,bcon);break;default: break;} } n=0;} }
///////濾波//////// int filter(){ int tm,buf[6];uchar i,j;EA=0;for(i=0;i<6;i++){ buf[i]=tmp();delay1ms(20);WDT_CONTR=0x35;/////喂狗 }
for(j=0;j<5;j++)for(i=0;i<5-j;i++)if(buf[i]>buf[i+1]){ tm=buf[i];buf[i]=buf[i+1];buf[i+1]=tm;} tm=((buf[2]+buf[3])/2);EA=1;return(tm);}
void main(){ uchar b,c;Init_Com();init1602();init24c02();
b=read_add(1);delay1ms(15);c=read_add(2);delay1ms(15);acon=b*256+c;b=read_add(3);delay1ms(15);c=read_add(4);delay1ms(15);bcon=b*256+c;
AUXR=0x01;// 禁止ALE輸出 WDT_CONTR=0x35;//啟動看門狗 write_com(0x01);//清屏指令
while(1){ at=filter();display(at);keyjc();key();
wen_kong();weno();} }
//////溫度控制//////////////
void wen_kong(){ if((flag==0)&&(not==0)){ at=filter();if(at<=bcon)
{ flag=1;jrk=0;xhk=0;he=1;} } }
void weno(){ if(flag){ at=filter();if(at>=acon){ flag=0;jrk=1;if(rsg)xhk=0;else xhk=1;he=0;} } if(not==1){ flag=0;jrk=1;if(rsg)xhk=0;else xhk=1;he=0;} }
第三篇:c語言源程序段
1.有三個整數(shù)a,b,c,由鍵盤輸入,輸出其中最大的數(shù)。#include
scanf(“%d%d%d”,&a,&b,&c);if(a>b&&a>c)
printf(“%dn”,a);else
if(b>a&&b>c)
printf(“%dn”,b);
else
printf(“%dn”,c);} 2.編程輸入整數(shù)a和b,若a2?b2大于100,則輸出a2?b2百位以上的數(shù)字,否則輸出兩數(shù)之和。
#include
printf(“%dn”,(d+e));else
printf(“%dn”,f);} 3.有一函數(shù):
?x(x?1)? y??2x?11(1?x?10)
?3x?11(x?10)?編寫一程序,輸入x,輸出y值。#include
y=x;else
if(x<10&&x>=1)
y=2*x-11;
else
y=3*x-11;
printf(“%dn”,y);} 4.給出一百分制成績,要求輸出成績等級’A’,’B’,’C’,’D’,’E’。90分以上為’A’,80-89分為’B’,70-79分為’C’,60-69分為’D’,60分以下為’E’ #include
printf(“A”);else
if(x<90&&x>=80)
printf(“B”);
else
if(x<80&&x>=70)
printf(“C”);
else
if(x<70&&x>=60)
printf(“D”);
else
printf(“E”);printf(“n”);} 5.提高題:給一個不多于5位的正整數(shù),要求:①求出它是幾位數(shù);②分別打印出每一位數(shù)字;③按逆序打印出各位數(shù)字,例如原數(shù)是321,應輸出123。#include
for(i=0;j>1;i++)
j=j/10;}
printf(“%dnn”,i);{
for(k=1;k<=i;k++){
b=a%10;
a=a/10;
printf(“%d”,b);} } }.求解一元二次方程a*x2+b*x+c=0 #include
int main(){ int a,b,c,m;double x1,x2,n;
//解為double類型
printf(“請輸入ax2+bx+c=0中的a,b,c: n”);scanf(“%d %d %d”,&a,&b,&c);//輸入?yún)?shù)
m=(b*b-4*a*c);if(m<0)
printf(“方程無解”);else
n=sqrt((double)m);
//對m進行強制類型轉換為double,因為接為double
x1=(-b-m)/(2*(double)a);
x2=(-b+m)/(2*(double)a);
printf(“x1=%.2lf x2=%.2lfn”,x1,x2);return 0;}.有一個分數(shù)數(shù)列: 23581321,,,?求出這個數(shù)列前20項之和 1235813#include
double sum(int n){ int i;double part = 0;
for(i = 1.0;i <= n;i++)
part +=(1.0 / i);return 2 * n-part;}
int main(void){ printf(“%.18fn”, sum(20));return 0;} 將從鍵盤輸入的偶數(shù)寫成兩個素數(shù)之和。#include
int a,b,c,d;
scanf(“%d”,&a);
for(b=3;b<=a/2;b+=2)
{
for(c=2;c<=sqrt(b);c++)
if(b%c==0)break;
if(c>sqrt(b))
d=a-b;
else break;
for(c=2;c<=sqrt(d);c++)
if(d%c==0)break;
if(c>sqrt(d))
printf(“%d=%d+%dn”,a,b,d);
} } 1:5位跳水高手參加10米高臺跳水決賽,有好事者讓5人據(jù)實力預測比賽結果.A選手說:B第二,我第三B選手說:我第二,E第四;C選手說:我第一,D第二;D選手說:C最后,我第三;E選手說:我第四,A第一.決賽成績公布之后,每位選手的預測都只說對了一半,即一對一錯.請編程解出比賽的實際名次.
1.#include
#include
} for(i=1;i<=4;i++)
b=a[0];a[0]=a[3];a[3]=b;b=a[1];a[1]=a[2];a[2]=b;for(k=1;k<=4;k++)printf(“%d”,a[k-1]);{ } a[i-1]=(a[i-1]+5)%10;a[4-j]=b%10;b=b/10;}
2、編寫程序,對輸入兩個正整數(shù)m和n,求出它們的最大公約數(shù)和最小公倍數(shù) #include “stdio.h” #include “math.h” void main(){ int n,m,maxgy,mingb,i,p;printf(“please input n and m:”);scanf(“%d%d”,&n,&m);if(n>m){
p=n;n=m;m=p;/*m和n交換*/ } for(i=n;i>=1;i--)
if(m%i==0&&n%i==0)
break;maxgy=i;printf(“nmaxgy=%d mingb=%dn”,maxgy,m*n/maxgy);
}
2、編寫程序,對輸入兩個正整數(shù)m和n,求出它們的最大公約數(shù)和最小公倍數(shù)
#include “stdio.h” #include “math.h” void main(){ int n,m,maxgy,mingb,t,p;printf(“please input n and m:”);scanf(“%d%d”,&n,&m);if(n>m){
p=n;n=m;m=p;/*m和n交換*/ } p=m*n;while(m%n!=0){
t=m%n;
m=n;
n=t;} maxgy=n;printf(“nmaxgy=%d mingb=%dn”,maxgy,p/maxgy);} #include “stdio.h” #include “math.h” void main(){ int n,m,maxgy,p;int maxgy1(int m,int n);printf(“please input n and m:”);scanf(“%d%d”,&n,&m);if(n>m){
p=n;n=m;m=p;/*m和n交換*/ } p=m*n;
maxgy=maxgy1(m,n);printf(“nmaxgy=%d mingb=%dn”,maxgy,p/maxgy);} int maxgy1(int m,int n){ if(n==0)
return m;else return maxgy1(n,m%n);}
3輸入n判斷n是否為素數(shù) #include “stdio.h” void main(){ int n,i,flag;flag=1;printf(“please input n:”);scanf(“%d”,&n);for(i=2;i if(n%i==0) { flag=0; break; } if(flag==1) printf(“n%d is ssn”,n);else printf(“n%d is not ssn”,n);} #include “stdio.h”、求100以內(nèi)的所有素數(shù),并按10個一行進行打印。#include “math.h” void main(){ int n,i,flag,sum;sum=0;for(n=2;n<=100;n++){ flag=1; for(i=2;i<=sqrt(n);i++) if(n%i==0) { flag=0; break; } if(flag==1) { sum++; printf(“%5d”,n); if(sum%10==0) printf(“n”); } } printf(“n”);} 4、用遞歸求1到100的和 #include return 1;else return n+lj(n-1);} 累加法求1到100的和 #include sum=sum+i;printf(“result=%dn”,sum);} #include printf(“result=%dn”,sum);} #include if(i>100) break; sum=sum+i; i++;} printf(“result=%dn”,sum);} 求20到40以及60到80中所有能被3整除數(shù)的和 #include if(i%3==0) sum=sum+i; if(i==40) i=i+19;} //i%3==0&&i>=20&&i<=40||i>=60&&i<=80 printf(“result=%dn”,sum);} A+aa+aaa+….+a…..a #include t=t*10+a; sum=sum+t;} printf(“result=%ldn”,sum);} 1、請從鍵盤上輸入年、月、日,求該年月日是該年的第多少天? #include int year,month,day,sum=0,i;int days(int,int);printf(“please input year month and day:”);scanf(“%d%d%d”,&year,&month,&day);for(i=1;i int day;switch(month){ case 1: case 3: case 5: case 7: case 8: case 10: case 12:day=31;break;case 4: case 6: case 9: case 11:day=30;break;case 2:if(year%4==0&&year%100!=0||year%400==0) } return day; day=29;else day=28;} 2、求3到1000內(nèi)所有尾數(shù)為3的素數(shù)之和。#include } int ss(int n){ int flag=1,i;for(i=2;i<=sqrt(n);i++)if(n%i==0){ flag=0;break;int i,sum=0;int ss(int);for(i=3;i<=1000;i++)if(ss(i)==1) if(i%10==3) sum=sum+i;printf(“result=%dn”,sum); } } return flag; 3、從鍵盤上輸入一個整數(shù),將它拆成質因子的乘積。例如 18=2*3*3 #include } if(n%i==0){ } else i++;printf(“%d*”,i);n=n/i;printf(“b n”);} 4、從鍵盤上輸入一串字符,統(tǒng)計字母、數(shù)字、空格和其它字符的個數(shù)。#include char ch;int c,d,s,o;c=d=s=o=0;while((ch=getchar())!=10){ if(ch>='a'&&ch<='z'||ch>='A'&&ch<='Z') c++;else if(ch>='0'&&ch<='9') d++;else if(ch==' ') s++;else o++;} printf(“c=%dnd=%dns=%dno=%dn”,c,d,s,o);} 5、從鍵盤上輸入10個數(shù),求它們的最大值。#include } int n,i,max;scanf(“%d”,&n);max=n;for(i=1;i<10;i++){ scanf(“%d”,&n);if(max max=n;} printf(“max=%dn”,max);3. 一個數(shù)恰好等于它的因子之和,這個數(shù)就稱為“完數(shù)”。例如,6的因子為1,2,3而6=1+2+3,因此6是完數(shù)。編程找出求1000以內(nèi)的所有完全數(shù)。#include “stdio.h” #include “math.h” void main(){ int n,s,i,k;for(n=1;n<=1000;n++){ s=0; for(i=1;i if(n%i==0) s=s+i; if(n==s) { printf(“%5d its factors is ”,n); for(k=1;k if(n%k==0) printf(“%d,”,k); printf(“b n”); } } printf(“n”);} .打印出楊輝三角形(要求打印出10行如下圖)#include “stdio.h” #include “math.h” void main(){ long i,j,x,y,z,k;long jc(int);for(i=0;i<10;i++){ for(j=0;j<=i;j++) { x=jc(i); y=jc(j); z=jc(i-j); printf(“%4d”,x/(y*z)); } printf(“n”);} } long jc(int n){ long x=1,k;if(n==0) return 1;else for(k=1;k<=n;k++) x=x*k;return x;} #include “stdio.h” #include “math.h” void main(){ long i,j,x,y,z,k;for(i=0;i<10;i++){ for(j=0;j<=i;j++) { x=y=z=1; for(k=1;k<=i;k++) x=x*k; for(k=1;k<=j;k++) y=y*k; for(k=1;k<=i-j;k++) z=z*k; printf(“%4d”,x/(y*z)); } printf(“n”);} } 7.用*打印圖形 #include “stdio.h” void main(){ int i,j,k,n;printf(“please input n:”);scanf(“%d”,&n);for(i=1;i<=n;i++)/**/ { for(j=1;j<=40-i;j++)/**/ printf(“ ”); for(k=1;k<=2*i-1;k++)/**/ printf(“*”); printf(“n”);} for(i=n-1;i>=1;i--)/**/ { for(j=1;j<=40-i;j++)/**/ printf(“ ”); for(k=1;k<=2*i-1;k++)/**/ } } printf(“*”);printf(“n”); #include void main() { int driver,mode; driver=DETECT; mode=0; initgraph(&driver,&mode,“"); setcolor(15); line(66,66,88,88); lineto(100,100); linerel(36,64); getch(); restorecrtmode(); } -------------- #include #include void circlePoint(int x,int y)/*八分法畫圓程序*/ { circle(320 x*20,240 y*20,3); circle(320 y*20,240 x*20,3); circle(320-y*20,240 x*20,3); circle(320-x*20,240 y*20,3); circle(320-x*20,240 y*20,3); circle(320-x*20,240-y*20,3); circle(320-y*20,240-x*20,3); circle(320 y*20,240-x*20,3); circle(320 x*20,240-y*20,3); } void MidBresenhamcircle(int r)/* 中點Bresenham算法畫圓的程序 */ { int x,y,d; x=0;y=r;d=1-r;/* 計算初始值 */ while(x { circlePoint(x,y);/* 繪制點(x,y)及其在八分圓中的另外7個對稱點 */ if(d<0)d =2*x 3;/* 根據(jù)誤差項d的判斷,決定非最大位移方向上是走還是不走 */ else { d =2*(x-y)5; y--; } x; delay(900000); } /* while */ } main() { int i,j,r,graphmode,graphdriver; detectgraph(&graphdriver,&graphmode); initgraph(&graphdriver,&graphmode,” “); printf(”中點Bresenhamcircle算法畫圓的程序n“);/*提示信息*/ printf(”注意 |r|<=11“); printf(”n輸入半徑值 r:“); scanf(”%d“,&r); printf(”按任意鍵顯示圖形...“); getch(); cleardevice(); setbkcolor(BLACK); for(i=20;i<=620;i =20)/*使用雙循環(huán)畫點函數(shù)畫出表格中的縱坐標*/ for(j=20;j<=460;j) putpixel(i,j,2); for(j=20;j<=460;j =20)/*使用雙循環(huán)畫點函數(shù)畫出表格中的橫坐標*/ for(i=20;i<=620;i) putpixel(i,j,2); outtextxy(320,245,”0“);/*原點坐標*/ outtextxy(320-5*20,245,”-5“);circle(320-5*20,240,2);/*橫坐標值*/ outtextxy(320 5*20,245,”5“);circle(320 5*20,240,2); outtextxy(320-10*20,245,”-10“);circle(320-10*20,240,2); outtextxy(320 10*20,245,”10“);circle(320 10*20,240,2); outtextxy(320-15*20,245,”-15“);circle(320-15*20,240,2); outtextxy(320 15*20,245,”15“);circle(320 15*20,240,2); outtextxy(320,240-5*20,”-5“);circle(320,240-5*20,2);/*縱坐標值*/ outtextxy(320,240 5*20,”5“);circle(320,240 5*20,2); outtextxy(320,240-10*20,”-10“);circle(320,240-10*20,2); outtextxy(320,240 10*20,”10“);circle(320,240 10*20,2); outtextxy(20,10,”The center of the circle is(0,0)“);/*坐標軸左上角顯示提示信息*/ setcolor(RED);/*標記坐標軸*/ line(20,240,620,240);outtextxy(320 15*20,230,”X“); line(320,20,320,460);outtextxy(330,20,”Y“); setcolor(YELLOW); MidBresenhamcircle(r); setcolor(BLUE);/*繪制圓*/ circle(320,240,r*20); setcolor(2); getch(); closegraph(); } -------------------------#include void main() { int driver,mode; driver=DETECT; mode=0; initgraph(&driver,&mode,”"); setcolor(15); circle(20,20,20); getch(); } 蘇州科技學院畢業(yè)論文 目錄 第1章 引言............................................................................................................................1 1.1 背景介紹.................................................................................................................1 1.1.1 研究背景簡介..................................................................................................1 1.1.2 C語言簡介......................................................................................................1 第2章 概要設計....................................................................................................................3 2.1 方案設計.................................................................................................................3 2.1.1 開發(fā)環(huán)境..........................................................................................................3 2.1.2 工作方式..........................................................................................................3 2.1.3 系統(tǒng)目標..........................................................................................................3 2.2 系統(tǒng)功能.................................................................................................................3 2.3 需要解決問題.........................................................................................................4 2.4 系統(tǒng)流程.................................................................................................................4 2.4.1 基本流程..........................................................................................................4 2.4.2 具體實現(xiàn)..........................................................................................................5 第3章 詳細設計....................................................................................................................7 3.1 系統(tǒng)模塊化分.........................................................................................................7 3.1.1 添加文件對話框..............................................................................................7 3.1.2 編譯鏈接函數(shù)..................................................................................................8 3.1.3 運行/評判對話框.............................................................................................9 3.2 系統(tǒng)模塊具體實現(xiàn)...............................................................................................10 3.2.1 準備工作........................................................................................................10 3.2.2 實現(xiàn)添加文件對話框....................................................................................11 3.2.3 實現(xiàn)編譯鏈接函數(shù)........................................................................................15 3.2.4 實現(xiàn)運行/評判對話框...................................................................................19 第4章 測試..........................................................................................................................26 4.1 測試方案...............................................................................................................26 4.2 運行界面...............................................................................................................26 4.2.1 準備系統(tǒng)運行................................................................................................26 4.2.2 系統(tǒng)測試........................................................................................................27 結論..........................................................................................................................................30 致謝..........................................................................................................................................32 參考文獻..................................................................................................................................33 附錄A 外文參考文獻(譯文)..........................................................................................34 附錄B 外文參考文獻(原文)..........................................................................................48 I 蘇州科技學院畢業(yè)論文 第1章 引言 1.1 背景介紹 1.1.1 研究背景簡介 C語言是目前國際上廣泛流行的、重要的計算機高級語言之一。它適合作為系統(tǒng)描述語言,即可用來編寫系統(tǒng)軟件,也可用來編寫應用軟件。對于學習計算機專業(yè)的學生來說,學好C語言將為今后學習其他編程語言打下良好的基礎,而隨著計算機應用的普及,更多的其他非計算機專業(yè)也會需要學習編寫簡單的程序,C語言也是一個很不錯的選擇。 學習C語言,首先是要學習理論知識,閱讀編程思想,閱讀源代碼,其次就是動手實踐上機編寫程序了。只有通過自己編寫程序,才能更好的掌握理論知識,發(fā)現(xiàn)不足,取得進步。 傳統(tǒng)的教學方式中,學生采用FTP,Email甚至手寫的方式提交編程作業(yè),老師一般采用逐一檢查并試運行的手工檢查方式,然后給出相應的得分。由于在編程作業(yè)的提交過程中,很多學生可能會把一些有語法錯誤以及結果不正確的程序提交上來,這就需要花費老師很多的精力和時間,效果也不是很好。當前,采用計算機對源程序直接進行評判還不是很普遍。因此,有必要開發(fā)一套簡單易用的C語言源程序的自動評判系統(tǒng),幫助老師檢查學生的編程作業(yè),提高老師工作效率,減輕老師負擔。 1.1.2 C語言簡介 C語言是國際上廣泛流行的、很有發(fā)展前途的計算機高級語言。它適合作為系統(tǒng)描述語言,即可用來編寫系統(tǒng)軟件,也可用來編寫應用軟件。 早期的操作系統(tǒng)等系統(tǒng)軟件主要是用匯編語言編寫的(包括 UNIX操作系統(tǒng)在內(nèi))。由于匯編語言依賴于計算機硬件,程序的可讀性和可移植性都比較差。為了提高可讀性和可移植性,最好改用高級語言,但一般的高級語言難以實現(xiàn)匯編語言的某些功能(匯編語言可以直接對硬件進行操作),例如:對內(nèi)存地址的操作、位操作等)。人們設想能否找到一種既具有一般高級語言特性,又具有低級語言特性的語言,集它們的優(yōu)點于一身。于是,C語言就在這種情況下應運而生了。 C語言是在B語言的基礎上發(fā)展起來的,它的根源可以追溯到ALGOL 60。1960年出現(xiàn)的ALGOL 60是一種面向問題的高級語言,它離硬件比較遠,不宜用來編寫系統(tǒng)程序。1963年英國的劍橋大學推出了CPL語言。1967年英國劍 1 蘇州科技學院畢業(yè)論文 橋大學的Matin Richards對 CPL語言作了簡化,推出了BCPL語言。1970年美國貝爾實驗室的 Ken Thompson以 BCPL語言為基礎,又作了進一步簡化,設計出了很簡單的而且很接近硬件的 B語言,并用 B語言寫第一個UNIX操作系統(tǒng),在PDP-7上實現(xiàn)。1971年在PDP-11/20上實現(xiàn)了B語言,并寫了UNIX操作系統(tǒng)。但B語言過于簡單,功能有限。1972年至 1973年間,貝爾實驗室的 D.M.Ritchie在B語言的基礎上設計出了C語言(取 BCPL的第二個字母)。最初的C語言只是為描述和實現(xiàn)UNIX操作系統(tǒng)提供一種工作語言而設計的。1973年,K.Thom-pson和D.M.ritchie兩人合作把UNIX的90%以上用 C改寫。 后來,C語言多次作了改進,但主要還是在貝爾實驗室內(nèi)部使用。直到1-975年UNIX第6版公布后,C語言的突出優(yōu)點才引起人們普遍注意。1977年出現(xiàn)了不依賴于具體機器的C語言編譯文本《可移植C語言編譯程序》,使C移植到其它機器時所做的工作大大簡化了,這也推動了UNIX操作系統(tǒng)迅速地在各種機器上實現(xiàn)。隨著 UNIX的日益廣泛使用,C語言也迅速得到推廣。C語言和UNIX可以說是一對孿生兄弟,在發(fā)展過程中相輔相成。1978年以后,C語言已先后移植到大、中、小、微型機上,已獨立于UNIX和PDP了。現(xiàn)在C語言已風靡全世界,成為世界上應用最廣泛的幾種計算機語言之一。 C語言主要有以下一些特點:(1)語言表達能力強。(2)語言簡潔、緊湊,使用靈活,易于學習和使用。(3)數(shù)據(jù)類型豐富,具有很強的結構化控制語句。(4)語言生成的代碼質量高。(5)語法限制不嚴格,程序設計自由度大。(6)可移植性好。 蘇州科技學院畢業(yè)論文 第2章 概要設計 2.1 方案設計 本課題的任務是完成一個C源程序的自動評判系統(tǒng)。首先需要解決的問題是確定整個系統(tǒng)的開發(fā)環(huán)境和工作方式,然后是確定系統(tǒng)所要達到的目標,接著分析系統(tǒng)所應完成的功能以及可能遇到的問題,最后給出具體實現(xiàn)的步驟。 2.1.1 開發(fā)環(huán)境 經(jīng)過與指導老師的交流,查閱有關資料,分析系統(tǒng)的整體情況,本系統(tǒng)更加類似于一個應用程序,再結合自己所學知識,決定采用微軟的Visual C++集成開發(fā)環(huán)境來開發(fā)整個程序。Visual C++是Windows環(huán)境下最強大、最流行的程序設計語言之一。Visual C++可以用來開發(fā)各種類型、不同規(guī)模和復雜程度的應用程序,開發(fā)效率很高,生成的應用軟件代碼品質優(yōu)良。 2.1.2 工作方式 分析整個系統(tǒng),最主要的功能是:編譯鏈接源程序,運行目標程序,目標程序輸入輸出的重定向。結合Visual C++開發(fā)環(huán)境來看,有批處理方式、普通應用程序方式、Add-in方式。考慮到Add-in的方式在使用Visual C++編譯器去編譯鏈接C源程序的時候更加方便,并且Add-in的方式也可以利用Visual C++的可視化界面的開發(fā)功能,所以工作方式采用Visual C++下的Add-in方式。Visual C++ Add-In基本上就是實現(xiàn)了IDSAddIn接口的COM對象。通過這個接口,Add-in能夠掌管Visual C++環(huán)境,并且執(zhí)行特定的任務,例如在Visual C++環(huán)境下打開工作空間,編譯工程等等。在使用Add-in方式的時候,首先需要打開Visual C++環(huán)境,然后加載add-in文件(*.dll)。 2.1.3 系統(tǒng)目標 本系統(tǒng)最終目的是為了減輕老師負擔,利用計算機自動評判編程作業(yè),替代手工檢查方式。要求學生將編寫好的作業(yè)交至指定文件夾,然后老師運行本系統(tǒng),編譯鏈接,運行生成目標程序,通過比較程序輸出與標準答案,可以得到每個源程序的評判結果。 2.2 系統(tǒng)功能 詳細的分析整個系統(tǒng)功能應該包括: 1.從文件夾抽取源程序。 2.控制Visual C++編譯器編譯鏈接源程序。 蘇州科技學院畢業(yè)論文 3.以測試數(shù)據(jù)運行生成的目標程序。4.程序輸出與標準輸出比較。5.根據(jù)比較結果得到評判結果。 2.3 需要解決問題 1.存放C源程序的文件夾的組織方式和文件夾中C源程序的命名方式。2.程序通過何種方式提取C源程序。 3.用程序控制Visual C++編譯器去編譯鏈接C源程序。4.如何處理編譯鏈接時出錯,沒有生成目標程序的C源程序。5.通過何種方式運行編譯鏈接之后生成的目標程序。 6.在運行目標程序時,如何自動完成目標程序的輸入和輸出。7.對于運行目標程序時異常情況的處理。 8.采用何種方式比較輸出結果和正確答案,以及如何存儲比較結果。 2.4 系統(tǒng)流程 2.4.1 基本流程 基本上本系統(tǒng)是一個順序執(zhí)行的過程,系統(tǒng)的實現(xiàn)也是一步一步來的。下一個模塊需要用到上一個模塊的數(shù)據(jù)。系統(tǒng)流程圖如圖1-1所示。 1.系統(tǒng)從文件夾提取出所有的C源程序。 2.系統(tǒng)控制Visual C++的編譯器去編譯鏈接提取出的C源程序,得到相應的生成的目標程序(exe)。 3.系統(tǒng)以正確輸入數(shù)據(jù)運行生成的目標程序(exe)。4.系統(tǒng)提取運行目標程序(exe)得到的輸出數(shù)據(jù)。5.系統(tǒng)將輸出數(shù)據(jù)與正確答案進行比較。6.根據(jù)比較結果得到評判結果。 蘇州科技學院畢業(yè)論文 圖1-1 系統(tǒng)流程圖 2.4.2 具體實現(xiàn) 根據(jù)系統(tǒng)應該完成的功能,結合需要解決的問題,系統(tǒng)的具體實現(xiàn)如下: 蘇州科技學院畢業(yè)論文 1.文件夾的組織方式:每一個題目設置一個文件夾,同一題目的所有編程作業(yè)(只交后綴名為*.c的文件)交至對應的唯一文件夾下。 2.每個文件夾中C源程序的命名方式:以學號命名,后綴名為*.c,這樣每個文件夾中的C源程序是唯一的,在評判時能更直觀的得到結果。 3.設置一個基本對話框,通過列表控件來提取選擇的一個文件夾下的所有C源程序。 4.編譯鏈接方面,Visual C++不能直接編譯鏈接后綴名為*.c的C源程序,因此提前新建一個WIN32空白工程文件,然后將C源程序的后綴名改為*.cpp,放至空白工程中,便可以解決不能直接編譯鏈接的問題。通過Add-in接口,控制整個Visual C++環(huán)境,打開已放入改了后綴名的C源程序的空白工程文件,然后便可進行編譯鏈接。在這里要設置循環(huán),對列表框中的每一個C源程序都進行編譯鏈接。 5.循環(huán)過程中,編譯鏈接后生成目標程序的C源程序,從空白工程文件的Debug文件夾中復制其目標程序到暫存的文件夾,并用其學號來命名生成的目標程序。然后循環(huán)繼續(xù)直到所有C源程序都完成編譯鏈接。 6.對于編譯鏈接后沒有生成目標程序的C源程序,視為編譯鏈接錯誤,將此結果先一步存至評判結果處。 7.編譯鏈接全部完成后,設置彈出一個對話框,用于輸入測試數(shù)據(jù)、運行正確的目標程序,得到正確答案。同時通過列表框提取已經(jīng)生成的所有以學號命名的目標程序。 8.對于編譯鏈接正確,已經(jīng)生成的目標程序,設置循環(huán),每次循環(huán)中通過新建一個進程來運行應用程序,如果程序正常結束,則關閉進程,循環(huán)繼續(xù)去運行下一個目標程序。 9.在運行目標程序時,通過管道技術來完成輸入輸出數(shù)據(jù)的重定向問題。10.對于目標程序運行時可能出現(xiàn)的種種異常情況,例如死循環(huán)等,通過設定一個時間,超出這個時間后進程強制結束來處理,進程強制結束后主循環(huán)繼續(xù),同時判定為運行時錯誤。 11.在開始循環(huán)運行所有目標程序之前,需要老師首先運行此題目正確程序生成的應用程序,并且輸入運行數(shù)據(jù)(如無需數(shù)據(jù)輸入則省略此步驟),得到正確的輸出數(shù)據(jù),存入一個編輯框。然后每次運行生成的目標程序得到輸出時與編輯框中字符串比較,來得到比較結果。結果是相同或是不同。 12.最后的評判結果:沒有生成目標程序,判為編譯鏈接出錯-50分;生成了目標程序,但是輸出與正確答案不同,判為運行錯誤-60分;生成了目標程序,并且輸出結果與正確答案相同,判為程序正確-100分。 蘇州科技學院畢業(yè)論文 第3章 詳細設計 3.1 系統(tǒng)模塊化分 根據(jù)系統(tǒng)所應該完成的功能,以及考慮到使用的方便性,將系統(tǒng)劃分為三個模塊,其中包括兩個基本對話框和一個函數(shù)。 3.1.1 添加文件對話框 此對話框需要完成的功能、遇到的問題及解決辦法: 1.初始化:在系統(tǒng)運行之前刪除空白工程文件中不需要的文件,清空相關的文件夾。此功能通過對話框上的一個“初始化”按鈕完成。 在系統(tǒng)運行選擇C源程序文之前,需要對相關文件夾和文件進行處理,有刪除文件夾、清空文件夾、刪除文件。而在Visual C++中是不能直接刪除非空的文件夾的,也沒有清空文件夾的函數(shù),文件是可以通過庫函數(shù)DeleteFile()直接刪除的。因此這里需要自己添加函數(shù)來清空文件夾,在清空文件夾之后調用庫函數(shù)RemoveDirectory()來刪除已空文件夾。 2.添加文件:初始化之后,從相應的存放相同題目的文件夾中提取所有的C源程序文件(過濾器設置為只能選取后綴名為*.c的文件),將所有的文件添加至對話框的一個列表控件中,列表控件的每一行項目為C源程序文件的絕對路徑。完成添加C源程序后,取得項目總數(shù)的信息存入注冊表,并且以項目總數(shù)設置循環(huán),將每個C源程序文件的絕對路徑信息存入注冊表,然后調用編譯鏈接函數(shù)。此功能通過對話框的一個“添加文件”按鈕和一個列表控件完成。 在添加文件時選擇用列表控件的方式,這樣在之后設置循環(huán)對每個C源程序文件進行操作時比較方便。同時每個項目中取的是C源程序文件的絕對路徑(包括文件名),因為之后的好多操作需要文件的路徑,取得學號信息時也比較方便。因為在Add-in方式下,對話框類和Add-in類之間的數(shù)據(jù)傳遞比較特殊,所以采用將列表控件中的相關信息存至注冊表的方式,以便今后在編譯鏈接時調用。 3.確認:新建對話框時,默認的代碼,無實際功能。通過點擊此按鈕,得到“OK”按鈕按下的消息,調用編譯鏈接函數(shù)。通過對話框的“OK”按鈕完成。 此對話框的數(shù)據(jù)輸入是:文件夾中選取的所有后綴名為(*.c)的C源程序文件。 蘇州科技學院畢業(yè)論文 此對話框的數(shù)據(jù)輸出是:列表控件中的項目總數(shù)和列表控件每個項目中C源程序文件的絕對路徑。 3.1.2 編譯鏈接函數(shù) 此函數(shù)需要完成的功能、遇到的問題及解決辦法: 編譯鏈接:從注冊表提取出添加文件對話框中列表控件的項目總數(shù),以此設置循環(huán)。在每次循環(huán)中,首先進行初始化操作,刪除空白工程文件夾中相關不用的文件和文件夾,然后通過從注冊表提取出添加文件對話框列表控件的項目中的C源程序文件的絕對路徑,將后綴名為*.c的C源程序文件改名為與建立空白工程時建立的關聯(lián)的*.cpp文件。通過Add-in的接口,在Visual C++工作空間打開空白工程文件,此時它已經(jīng)成為C源程序文件的工程文件,進行編譯鏈接。編譯鏈接完成之后如果在空白工程文件的Debug文件夾中找到生成的目標程序,則以此C源程序文件中的學號信息來命名此目標程序(即,此時目標程序改名為學號.exe)并且將改名后的目標程序復制到暫存所有生成的目標程序的文件夾中,以備運行時使用。而如果編譯鏈接完成之后在空白工程文件的Debug文件夾中沒有找到生成的目標程序,則視為編譯鏈接錯誤,直接在結果文件夾中以學號為信息給出評判結果。處理結束后進行下一個循環(huán)直到循環(huán)結束,給出編譯鏈接已完成的信息提示框。 首先編譯鏈接時取用的數(shù)據(jù)是剛才添加文件對話框中列表控件中添加入注冊表的信息。在每次循環(huán)開始前,都需要對test文件夾進行處理,刪除Debug文件夾,刪除0.cpp文件,清空result、outcome文件夾,這些問題同添加文件對話框問題中的初始化一樣,都需要自己編寫函數(shù)來清空文件夾和刪除非空文件夾。然后因為是將C源程序文件加入空白工程文件中編譯,且空白的關聯(lián)cpp文件已經(jīng)命名為0.cpp,所以C源程序文件在編譯鏈接前都需要改名為0.cpp文件。之后通過Add-in,控制整個Visual C++的開發(fā)環(huán)境,首先打開工作空間,然后載入工程,之后編譯鏈接,當然這些都是Visual C++自動完成的,相當于按下了Build按鈕,這也就是使用Add-in方式的關鍵所在。編譯鏈接結束后,如果在Debug文件夾中生成0.exe文件,則視為編譯鏈接成功,且此時需要將此文件轉移出來,因為如不轉移,編譯鏈接下一個C源程序文件時會覆蓋此0.exe文件。 此函數(shù)的數(shù)據(jù)輸入是:列表控件中的項目總數(shù)和列表控件每個項目中C源程序文件的絕對路徑。 此函數(shù)的數(shù)據(jù)輸出是:編譯鏈接成功后以學號命名的存至相同文件夾下的目標程序;編譯鏈接錯誤后以學號為區(qū)分信息的存至結果文件夾下的評判結果。 蘇州科技學院畢業(yè)論文 3.1.3 運行/評判對話框 此對話框需要完成的功能及其解決辦法: 1.輸入數(shù)據(jù)、運行正確程序:彈出此對話框后,進入運行目標程序,評判階段,首先運行此題目正確程序編譯鏈接后生成的exe程序,如果需要輸入數(shù)據(jù)才能運行的,先輸入數(shù)據(jù),得到此題目正確的輸出。此功能通過“選擇正確程序”按鈕來選擇此題目正確程序生成的exe文件,通過一個編輯框顯示運行的正確exe文件路徑,通過另一個編輯框來實現(xiàn)數(shù)據(jù)輸入,通過第三個編輯框來得到運行正確exe文件后得到的數(shù)據(jù)輸出,即標準答案。 在編譯鏈接結束后,進入運行/評判階段,首先需要運行正確的程序,這是老師之前通過編譯鏈接正確題目程序得到的正確的exe程序。如果程序需要輸入數(shù)據(jù)之后運行的,在“正確輸入”編輯框中輸入正確數(shù)據(jù)。通過編輯框的方式輸入數(shù)據(jù)方便直觀。因為這里是老師輸入正確程序的正確數(shù)據(jù)輸入,所以老師會確保輸入數(shù)據(jù)的正確性。而如果不需輸入數(shù)據(jù)即可得到輸出數(shù)據(jù)的話就不用輸入數(shù)據(jù)即可。之后通過CreateProcess()函數(shù)運行正確程序,這里通過重定向技術使用管道來完成自動的使用輸入數(shù)據(jù)運行程序并且自動的將輸出數(shù)據(jù)送入編輯框而不是在顯示屏顯示。在正確輸出編輯框中會顯示出正確的結果,這樣子也便于觀察。 2.選擇目標文件:輸入正確數(shù)據(jù),以此數(shù)據(jù)運行正確的exe文件后,得到正確輸出,即標準答案。選取暫存文件夾中所有C源程序文件編譯鏈接正確后生成的所有以學號命名的目標程序至列表控件,列表控件項目為選取的目標程序的絕對路徑。此功能通過一個“添加文件”完成選取所有目標程序,通過一個列表控件來完成添加所有目標文件。 這里也是通過列表控件來完成選擇文件的工作,因為知道生成的所有目標程序在test文件夾下的result文件夾中,所以在打開文件時直接定位到此程序所在的文件夾。每個項目中同樣也是放的目標程序的絕對路徑(包括文件名),因為之后使用函數(shù)運行程序是需要使用程序的絕對路徑。 3.運行目標文件、進行評判:完成選取所有目標程序后,以列表控件的項目總數(shù)即目標程序總數(shù)設置循環(huán)。在每次循環(huán)中,以運行正確程序的exe文件時的數(shù)據(jù)輸入作為運行目標程序的數(shù)據(jù)輸入,即使用正確輸入編輯框中的輸入數(shù)據(jù),去運行目標程序,得到輸出數(shù)據(jù),將此輸出數(shù)據(jù)與正確輸出編輯框中的數(shù)據(jù)比較,這兩個數(shù)據(jù)都是CString類型的。如果比較結果相同,則視為運行正確,將此結果以學號信息為區(qū)別存至結果文件夾中作為評判結果;如果比較結果不同,則視為運行時錯誤,也將此結果以學號信息為區(qū)別存至結果文件夾作 9 蘇州科技學院畢業(yè)論文 為評判結果。完成一個目標程序的運行、評判之后,循環(huán)繼續(xù),去運行、評判下一個C源程序。直到處理完所有的目標程序,至此運行、評判結束。此功能通過一個“開始”按鈕完成。 在這里運行程序時的原理和運行正確程序時的一樣,正確的數(shù)據(jù)輸入就采用正確輸入編輯框中的數(shù)據(jù),這樣可以確保程序正確時得到的輸出與正確輸出相同,方便評判。一個問題是需要考慮到這里運行的是學生的程序而不是老師的正確程序,所以可能出現(xiàn)運行異常、死循環(huán)的進程不結束的問題,那么就會出現(xiàn)死機的情況,主程序運行不下去,所以這里需要設置進程運行超時的處理。因為是教學中的C源程序文件作業(yè),相對較為簡單,所以設置運行時間為4秒,如果進程運行超時還沒有自動結束,則強制結束,判為運行時錯誤。若果進程自動結束,則于正確結果比較得到評判結果。 此對話框的數(shù)據(jù)輸入是:題目正確源程序生成的exe文件,正確的測試數(shù)據(jù)輸入,所有C源程序文件編譯鏈接正確后生成的目標程序。 此對話框的數(shù)據(jù)輸出是:以輸入的正確測試數(shù)據(jù)運行正確程序后的正確數(shù)據(jù)輸出;比較運行目標程序后的數(shù)據(jù)輸出與正確數(shù)據(jù)輸出,結果相同后得到的以學號信息區(qū)別的存至結果文件夾的運行正確的評判結果;比較運行目標程序后的數(shù)據(jù)輸出與正確數(shù)據(jù)輸出,結果不同后得到的以學號信息區(qū)別的存至結果文件夾的運行錯誤的評判結果。 3.2 系統(tǒng)模塊具體實現(xiàn) 在這一節(jié)中,將會對各個模塊中系統(tǒng)那個實現(xiàn)的難點、遇到的問題、解決的方法、重點技術問題的給出詳細的說明。 3.2.1 準備工作 在開始系統(tǒng)設計之前,在Visual C++中新建一個Win32空白工程,這里工程名為test,然后在此空白工程中新建一個C++文件,文件名為0.cpp。以后編譯鏈接選取的C源程序文件時則將C源程序文件改名為0.cpp并替換空白工程中的0.cpp文件即可。為防止編譯鏈接時編譯鏈接兩次,選擇組件->配置,移除Win32 Release只保留Win32 Debug。在此空白工程文件夾test中,新建一個文件夾result用于保存編譯鏈接成功后生成的以學號命名的目標程序,新建一個文件夾outcome用于存放最后的評判信息,新建一個空白文本文件file.txt。 在每次開始使用系統(tǒng)之前,進行的初始化操作就包括刪除Debug文件夾、刪除0.cpp文件,清空result和outcome文件夾。 接著開始系統(tǒng)的具體功能實現(xiàn)階段。首先Visual C++中新建一個DevStudio Add-in Wizard工程,工程名稱為Auto,并且在CCommands->ICommands中自動 10 蘇州科技學院畢業(yè)論文 添加一個函數(shù)AutoCommandMethod()。這個函數(shù)是系統(tǒng)的切入點。這時編譯鏈接工程之后,生成DLL文件,加載此文件后,工具欄會添加一個按鈕,此按鈕實現(xiàn)的是AutoCommandMethod()的函數(shù)功能。系統(tǒng)的使用從點擊這個按鈕開始。 3.2.2 實現(xiàn)添加文件對話框 建立起DevStudio Add-in Wizard工程后,在工作空間,右擊Auto Classes添加一個對話框類AddFile,即添加文件對話框。編輯此對話框,添加“初始化”、“添加文件”按鈕和一個列表控件,保留默認的“OK”、“Cancle”按鈕。 1.“初始化”按鈕:此按鈕完成的功能是刪除Debug文件夾、刪除0.cpp文件,清空result和outcome文件夾。在Visual C++中可以通過庫函數(shù)DeleteFile()刪除一個文件。 (1).在此遇見的問題是在Visual C++中不能直接刪除一個不為空的文件夾以及沒有現(xiàn)成的庫函數(shù)來清空一個文件夾,因此自己添加兩個函數(shù)DeleteFolder和ClearFolder,分別用于刪除文件夾(不管其是否為空)和清空文件夾(清空其中的文件而保留文件夾),函數(shù)代碼如下: a.DeleteFolder函數(shù) void AddFile::DeleteFolder(CString sPath){ CFileFind ff; BOOL bFound; bFound = ff.FindFile(sPath + “*.*”); while(bFound) { bFound = ff.FindNextFile(); CString sFilePath = ff.GetFilePath(); if(ff.IsDirectory()) { if(!ff.IsDots()) DeleteFolder(sFilePath); } else { if(ff.IsReadOnly()) 蘇州科技學院畢業(yè)論文 { SetFileAttributes(sFilePath,F(xiàn)ILE_ATTRIBUTE_NORMAL); } DeleteFile(sFilePath); } } ff.Close(); SetFileAttributes(sPath,F(xiàn)ILE_ATTRIBUTE_NORMAL); RemoveDirectory(sPath); } b.ClearFolder函數(shù) void AddFile::ClearFolder(CString sPath){ CFileFind ff; BOOL bFound; bFound = ff.FindFile(sPath + “*.*”); while(bFound) { bFound = ff.FindNextFile(); CString sFilePath = ff.GetFilePath(); if(ff.IsDirectory()) { if(!ff.IsDots()) DeleteFolder(sFilePath); } else { if(ff.IsReadOnly()) { SetFileAttributes(sFilePath,F(xiàn)ILE_ATTRIBUTE_NORMAL); } DeleteFile(sFilePath); 蘇州科技學院畢業(yè)論文 } } ff.Close(); SetFileAttributes(sPath,F(xiàn)ILE_ATTRIBUTE_NORMAL);}(2).完整的“初始化”按鈕代碼如下: { CString StrDestFile=“D: est
主站蜘蛛池模板:
亚洲国产精品第一区二区|
品色堂免费论坛|
久久人妻精品国产|
日韩欧美成人免费观看|
国产内射老熟女aaaa|
波多野结衣av一区二区全免费观看|
美女视频黄的全免费视频网站|
国内精品久久久久久不卡影院|
美女裸奶100%无遮挡免费网站|
无码高清视频|
曰韩内射六十七十老熟女影视|
日本一道人妻无码一区在线|
久久中文骚妇内射|
成 人 在 线 免费观看|
国产亚洲精品久久久久久小说|
久久久久国产精品嫩草影院|
黑人巨大精品欧美视频一区|
西欧free性满足hd老熟妇|
亚洲色欲久久久综合网东京热|
亚洲国产精品久久久久秋霞小说|
5级做人爱c视版免费视频|
欧美色综合天天久久综合精品|
国产顶级熟妇高潮xxxxx|
无遮挡激情视频国产在线观看|
国产亚洲精品无码专区|
一区二区三区在线 | 日本|
日韩人妻无码精品二专区|
色噜噜狠狠色综合av|
午夜毛片不卡免费观看视频|
国产精品毛片久久久久久久|
久久久99无码一区|
精品国产三级a在线观看|
久久精品国产免费观看|
亚洲精品毛片一区二区三区|
久久久无码精品亚洲日韩蜜桃|
国产美女牲交视频|
色综合久久无码中文字幕app|
国产精品久久久久久久久ktv|
日本欧美一区二区三区高清|
色橹橹欧美在线观看视频高清|
狠狠躁天天躁夜夜躁婷婷|
第四篇:C語言編程 “畫圓”源程序
第五篇:C語言源程序的自動評判畢業(yè)設計論文