狀態機的c語言編程
1. stm32編程問題,狀態機,求大神指導,初學者,主要是switch語句後面的變數取值不明白
完整的流程:
http://www.amobbs.com/thread-5544745-1-1.html裡面是你程序的出處!
int main(void)
{
1.初始化各個模塊
while(1)
{
2.掃描按鍵;
3.給掃描到的按鍵賦值(包括長按鍵、短按鍵、KEY0、KEY1等)即狀態;
4.根據不同的鍵值進行不同的業務(switch case);
}
}
很完美的狀態機,我也是初學,特來膜拜的。
2. C語言狀態機 swtich 按鍵切換問題。連鍵
如果想它停止繼續判斷,在要停止的語句後面加一個break就行了
3. 編寫程序,將一個.cpp文件中的注釋,即以"/*......*/":括起來的文本和以「//」開始的
一、標准文件的讀寫1.文件的打開fopen()文件的打開操作表示將給用戶指定的文件在內存分配一個FILE結構區,並將該結構的指針返回給用戶程序,以後用戶程序就可用此FILE指針來實現對指定文件的存取操作了。當使用打開函數時,必須給出文件名、文件操作方式(讀、寫或讀寫),如果該文件名不存在,就意味著建立(只對寫文件而言,對讀文件則出錯),並將文件指針指向文件開頭。若已有一個同名文件存在,則刪除該文件,若無同名文件,則建立該文件,並將文件指針指向文件開頭。fopen(char*filename,char*type);其中*filename是要打開文件的文件名指針,一般用雙引號括起來的文件名表示,也可使用雙反斜杠隔開的路徑名。而*type參數表示了對打開文件的操作方式。其可採用的操作方式如下:方式含義"r"打開,只讀;"w"打開,文件指針指到頭,只寫;"a"打開,指向文件尾,在已存在文件中追加;"rb"打開一個二進制文件,只讀;"wb"打開一個二進制文件,只寫;"ab"打開一個二進制文件,進行追加;"r+"以讀/寫方式打開一個已存在的文件;"w+"以讀/寫方式建立一個新的文本文件;"a+"以讀/寫方式打開一個文件文件進行追加;"rb+"以讀/寫方式打開一個二進制文件;"wb+"以讀/寫方式建立一個新的二進制文件;"ab+"以讀/寫方式打開一個二進制文件進行追加;當用fopen()成功的打開一個文件時,該函數將返回一個FILE指針,如果文件打開失敗,將返回一個NULL指針。如想打開test文件,進行寫:[cpp]viewplainFILE*fp;if((fp=fopen("test","w"))==NULL){printf("Filecannotbeopened/n");exit();}elseprintf("Fileopenedforwriting/n");……fclose(fp);DOS操作系統對同時打開的文件數目是有限制的,預設值為5,可以通過修改CONFIG.SYS文件改變這個設置。2.關閉文件函數fclose()文件操作完成後,必須要用fclose()函數進行關閉,這是因為對打開的文件進行寫入時,若文件緩沖區的空間未被寫入的內容填滿,這些內容不會寫到打開的文件中去而丟失。只有對打開的文件進行關閉操作時,停留在文件緩沖區的內容才能寫到該文件中去,從而使文件完整。再者一旦關閉了文件,該文件對應的FILE結構將被釋放,從而使關閉的文件得到保護,因為這時對該文件的存取操作將不會進行。文件的關閉也意味著釋放了該文件的緩沖區。intfclose(FILE*stream);它表示該函數將關閉FILE指針對應的文件,並返回一個整數值。若成功地關閉了文件,則返回一個0值,否則返回一個非0值。常用以下方法進行測試:[cpp]viewplainif(fclose(fp)!=0){printf("Filecannotbeclosed/n");exit(1);}elseprintf("Fileisnowclosed/n");當打開多個文件進行操作,而又要同時關閉時,可採用fcloseall()函數,它將關閉所有在程序中打開的文件。intfcloseall();該函數將關閉所有已打開的文件,將各文件緩沖區未裝滿的內容寫到相應的文件中去,接著釋放這些緩沖區,並返回關閉文件的數目。如關閉了4個文件,則當執行:n=fcloseall();時,n應為4。3.文件的讀寫(1).讀寫文件中字元的函數(一次只讀寫文件中的一個字元):intfgetc(FILE*stream);intgetchar(void);intfputc(intch,FILE*stream);intputchar(intch);intgetc(FILE*stream);intputc(intch,FILE*stream);其中fgetc()函數將把由流指針指向的文件中的一個字元讀出,例如:ch=fgetc(fp);將把流指針fp指向的文件中的一個字元讀出,並賦給ch,當執行fgetc()函數時,若當時文件指針指到文件尾,即遇到文件結束標志EOF(其對應值為-1),該函數返回一個-1給ch,在程序中常用檢查該函數返回值是否為-1來判斷是否已讀到文件尾,從而決定是否繼續。[cpp]viewplain#include"stdio.h"#includeintmain(){FILE*fp;charch;if((fp=fopen("myfile.txt","r"))==NULL){printf("filecannotbeopened/n");exit(1);}while((ch=fgetc(fp))!=EOF)fputc(ch,stdout);fclose(fp);}該程序以只讀方式打開myfile.txt文件,在執行while循環時,文件指針每循環一次後移一個字元位置。用fgetc()函數將文件指針指定的字元讀到ch變數中,然後用fputc()函數在屏幕上顯示,當讀到文件結束標志EOF時,關閉該文件。上面的程序用到了fputc()函數,該函數將字元變數ch的值寫到流指針指定的文件中去,由於流指針用的是標准輸出(顯示器)的FILE指針stdout,故讀出的字元將在顯示器上顯示。又比如:fputc(ch,fp);該函數執行結構,將把ch表示的字元送到流指針fp指向的文件中去。在TC中,putc()等價於fputc(),getc()等價於fgetc()。putchar(c)相當於fputc(c,stdout);getchar()相當於fgetc(stdin)。注意,這里使用charch,其實是不科學的,因為最後判斷結束標志時,是看ch!=EOF,而EOF的值為-1,這顯然和char是不能比較的。所以,某些使用,我們都定義成intch。(2).讀寫文件中字元串的函數char*fgets(char*string,intn,FILE*stream);char*gets(char*s);intfprintf(FILE*stream,char*format,variable-list);intfputs(char*string,FILE*stream);intfscanf(FILE*stream,char*format,variable-list);其中fgets()函數將把由流指針指定的文件中n-1個字元,讀到由指針string指向的字元數組中去,例如:fgets(buffer,9,fp);將把fp指向的文件中的8個字元讀到buffer內存區,buffer可以是定義的字元數組,也可以是動態分配的內存區。注意,fgets()函數讀到'/n'就停止,而不管是否達到數目要求。同時在讀取字元串的最後加上'/0'。fgets()函數執行完以後,返回一個指向該串的指針。如果讀到文件尾或出錯,則均返回一個空指針NULL,所以長用feof()函數來測定是否到了文件尾或者是ferror()函數來測試是否出錯,例如下面的程序用fgets()函數讀test.txt文件中的第一行並顯示出來:[cpp]viewplain#include"stdio.h"intmain(){FILE*fp;charstr[128];if((fp=fopen("test.txt","r"))==NULL){printf("cannotopenfile/n");exit(1);}while(!feof(fp)){if(fgets(str,128,fp)!=NULL)printf("%s",str);}fclose(fp);}gets()函數執行時,只要未遇到換行符或文件結束標志,將一直讀下去。因此讀到什麼時候為止,需要用戶進行控制,否則可能造成存儲區的溢出。fputs()函數想指定文件寫入一個由string指向的字元串,'/0'不寫入文件。fprintf()和fscanf()同printf()和scanf()函數類似,不同之處就是printf()函數是想顯示器輸出,fprintf()則是向流指針指向的文件輸出;fscanf()是從文件輸入。下面程序是向文件test.dat里輸入一些字元:[cpp]viewplain#include#includeintmain(){char*s="That'sgoodnews";inti=617;FILE*fp;fp=fopen("test.dat","w");/*建立一個文字文件只寫*/fputs("YourscoreofTOEFLis",fp);/*向所建文件寫入一串字元*/fputc(':',fp);/*向所建文件寫冒號:*/fprintf(fp,"%d/n",i);/*向所建文件寫一整型數*/fprintf(fp,"%s",s);/*向所建文件寫一字元串*/fclose(fp);}用DOS的TYPE命令顯示TEST.DAT的內容如下所示:屏幕顯示YourscoreofTOEFLis:617That'sgoodnews下面的程序是把上面的文件test.dat里的內容在屏幕上顯示出來:[cpp]viewplain#includeintmain(){chars[24],m[20];inti;FILE*fp;fp=fopen("test.dat","r");/*打開文字文件只讀*/fgets(s,24,fp);/*從文件中讀取23個字元*/printf("%s",s);fscanf(fp,"%d",&i);/*讀取整型數*/printf("%d",i);putchar(fgetc(fp));/*讀取一個字元同時輸出*/fgets(m,17,fp);/*讀取16個字元*/puts(m);/*輸出所讀字元串*/fclose(fp);}運行後屏幕顯示:YourscoreofTOEFLis:617That'sgoodnews4.清除和設置文件緩沖區(1).清除文件緩沖區函數:intfflush(FILE*stream);intflushall();fflush()函數將清除由stream指向的文件緩沖區里的內容,常用於寫完一些數據後,立即用該函數清除緩沖區,以免誤操作時,破壞原來的數據。flushall()將清除所有打開文件所對應的文件緩沖區。(2).設置文件緩沖區函數voidsetbuf(FILE*stream,char*buf);voidsetvbuf(FILE*stream,char*buf,inttype,unsignedsize);這兩個函數將使得打開文件後,用戶可建立自己的文件緩沖區,而不使用fopen()函數打開文件設定的默認緩沖區。對於setbuf()函數,buf指出的緩沖區長度由頭文件stdio.h中定義的宏BUFSIZE的值決定,預設值為512位元組。當選定buf為空時,setbuf函數將使的文件I/O不帶緩沖。而對setvbuf函數,則由malloc函數來分配緩沖區。參數size指明了緩沖區的長度(必須大於0),而參數type則表示了緩沖的類型,其值可以取如下值:type值含義_IOFBF文件全部緩沖,即緩沖區裝滿後,才能對文件讀寫_IOLBF文件行緩沖,即緩沖區接收到一個換行符時,才能對文件讀寫_IONBF文件不緩沖,此時忽略buf,size的值,直接讀寫文件,不再經過文件緩沖區緩沖。5.文件的隨機讀寫函數前面介紹的文件的字元/字元串讀寫,均是進行文件的順序讀寫,即總是從文件的開頭開始進行讀寫。這顯然不能滿足我們的要求,C語言提供了移動文件指針和隨機讀寫的函數,它們是:(1).移動文件指針函數:longftell(FILE*stream);intrewind(FILE*stream);fseek(FILE*stream,longoffset,intorigin);函數ftell()用來得到文件指針離文件開頭的偏移量。當返回值是-1時表示出錯。rewind()函數用於文件指針移到文件的開頭,當移動成功時,返回0,否則返回一個非0值。fseek()函數用於把文件指針以origin為起點移動offset個位元組,其中origin指出的位置可有以下幾種:origin數值代表的具體位置SEEK_SET0文件開頭SEEK_CUR1文件指針當前位置SEEK_END2文件尾例如:fseek(fp,10L,0);把文件指針從文件開頭移到第10位元組處,由於offset參數要求是長整型數,故其數後帶L。fseek(fp,-15L,2);把文件指針從文件尾向前移動15位元組。(2).文件隨機讀寫函數intfread(void*ptr,intsize,intnitems,FILE*stream);intfwrite(void*ptr,intsize,intnitems,FILE*stream);fread()函數從流指針指定的文件中讀取nitems個數據項,每個數據項的長度為size個位元組,讀取的nitems數據項存入由ptr指針指向的內存緩沖區中,在執行fread()函數時,文件指針隨著讀取的位元組數而向後移動,最後移動結束的位置等於實際讀出的位元組數。該函數執行結束後,將返回實際讀出的數據項數,這個數據項數不一定等於設置的nitems,因為若文件中沒有足夠的數據項,或讀中間出錯,都會導致返回的數據項數少於設置的nitems。當返回數不等於nitems時,可以用feof()或ferror()函數進行檢查。fwrite()函數從ptr指向的緩沖區中取出長度為size位元組的nitems個數據項,寫入到流指針stream指向的文件中,執行該操作後,文件指針將向後移動,移動的位元組數等於寫入文件的位元組數目。該函數操作完成後,也將返回寫入的數據項數。二、非標准文件的讀寫這類函數最早用於UNIX操作系統,ANSI標准未定義,但有時也經常用到,DOS3.0以上版本支持這些函數。它們的頭文件為io.h。由於我們不常用這些函數,所以在這里就簡單說一下。1.文件的打開和關閉open()函數的作用是打開文件,其調用格式為:intopen(char*filename,intaccess);該函數表示按access的要求打開名為filename的文件,返回值為文件描述字,其中access有兩部分內容:基本模式和修飾符,兩者用""("或")方式連接。修飾符可以有多個,但基本模式只能有一個。access的規定--------------------------------------------------------基本模式含義修飾符含義--------------------------------------------------------O_RDONLY只讀O_APPEND文件指針指向末尾O_WRONLY只寫O_CREAT文件不存在時創建文件,屬性按基本模式屬性O_RDWR讀寫O_TRUNC若文件存在,將其長度縮為0,屬性不變O_BINARY打開一個二進制文件O_TEXT打開一個文字文件---------------------------------------------------------open()函數打開成功,返回值就是文件描述字的值(非負值),否則返回-1。close()函數的作用是關閉由open()函數打開的文件,其調用格式為:intclose(inthandle);該函數關閉文件描述字handle相連的文件。2.讀寫函數intread(inthandle,void*buf,intcount);read()函數從handle(文件描述字)相連的文件中,讀取count個位元組放到buf所指的緩沖區中,返回值為實際所讀位元組數,返回-1表示出錯。返回0表示文件結束。write()函數的調用格式為:intwrite(inthandle,void*buf,intcount);write()函數把count個位元組從buf指向的緩沖區寫入與handle相連的文件中,返回值為實際寫入的位元組數。3.隨機定位函數lseek()函數的調用格式為:intlseek(inthandle,longoffset,intfromwhere);該函數對與handle相連的文件位置指針進行定位,功能和用法與fseek()函數相同。tell()函數的調用格式為:longtell(inthandle);該函數返回與handle相連的文件現生位置指針,功能和用法與ftell()相同5.read函數和write函數來源:螞蟻的C/C++標准編程作者:antigloss1.read#includessize_tread(intfiledes,void*buf,size_tnbytes);返回值:讀取到的位元組數;0(讀到EOF);-1(出錯)read函數從filedes指定的已打開文件中讀取nbytes位元組到buf中。以下幾種情況會導致讀取到的位元組數小於nbytes:A.讀取普通文件時,讀到文件末尾還不夠nbytes位元組。例如:如果文件只有30位元組,而我們想讀取100位元組,那麼實際讀到的只有30位元組,read函數返回30。此時再使用read函數作用於這個文件會導致read返回0。B.從終端設備(terminaldevice)讀取時,一般情況下每次只能讀取一行。C.從網路讀取時,網路緩存可能導致讀取的位元組數小於nbytes位元組。D.讀取pipe或者FIFO時,pipe或FIFO里的位元組數可能小於nbytes。E.從面向記錄(record-oriented)的設備讀取時,某些面向記錄的設備(如磁帶)每次最多隻能返回一個記錄。F.在讀取了部分數據時被信號中斷。讀操作始於cfo。在成功返回之前,cfo增加,增量為實際讀取到的位元組數。2.write#includessize_twrite(intfiledes,constvoid*buf,size_tnbytes);返回值:寫入文件的位元組數(成功);-1(出錯)write函數向filedes中寫入nbytes位元組數據,數據來源為buf。返回值一般總是等於nbytes,否則就是出錯了。常見的出錯原因是磁碟空間滿了或者超過了文件大小限制。對於普通文件,寫操作始於cfo。如果打開文件時使用了O_APPEND,則每次寫操作都將數據寫入文件末尾。成功寫入後,cfo增加,增量為實際寫入的位元組數。
4. 用單片機C語言怎麼寫用狀態機實現按鍵控制LED燈閃爍這個程序
#include<STC12C52.H>
#defineucharunsignedchar
#defineuintunsignedint
sbitkey=P1^2;
sbitp1_6=P1^6;
voiddelay(uchardelay_time)
{
ucharn;
uintm;
for(n=0;n<delay_time;n++)
{
for(m=0;m<10000;m++);
}
}
voidkeyscan()
{
if(key==0)
{
delay(5);
if(key==0)
while(!key)
{
p1_6=0;
delay(20);
p1_6=1;
delay(20);
}
}
}
voidmain()
{
WDT_CONTR=0x3C;
while(1)
{
keyscan();
WDT_CONTR=0x3C;
}
}
這個功能可以用中斷來實現,當然,現在我寫的這個也可以實現。由於你用的晶振頻率不知道,所以你自己修改一下延時時間,再把頭文件改一下,就可以了,我試驗了,可以實現改功能。
5. 怎樣把C語言代碼轉化成有限狀態機(圖)
不懂你的問題?
6. C語言程序設計例如一個信息管理系統(同時保存輸入的信息),如何在完成子版塊後返回到菜單
同鞋,你的描述讓我有點懵逼,不過今天調bug比較郁悶,換換頭腦嘗試解答一下看的懂的部分……
關於return 和 exit 的區別:
exit是一個系統函數,功能是退出當前進程。return 是一個關鍵字,配合函數使用,代表返回,並不一定是退出。
你描述返回主菜單的意思,讓人無法理解,但是菜單之間的切換方法很多,最常見的方法是使用狀態機,具體可以網路搜索一下相關知識。
這里簡單的給個偽代碼:
enumMENU_ITEM
{
EXIT=0,
MAIN,
ITEM1,
ITEM2
};
MENU_ITEMmenu()
{
//一些邏輯
...
//跳轉到1
returnITEM2;
}
MENU_ITEMmenu1()
{
//一些邏輯
...
//跳轉到主菜單
returnMAIN;
}
MENU_ITEMmenu2()
{
//一些邏輯
...
//退出
returnEXIT;
}
voidmain()
{
MENU_ITEMchoose=EXIT;
scanf("%d",&choose);
while(choose)
{
caseMAIN:
//輸出主菜單
choose=menu();
break;
caseITEM1:
//輸出功能1
choose=menu1();
break;
caseITEM2:
//輸出功能2
choose=menu2();
break;
}
}
7. C語言 狀態機代碼 怎麼寫
剛好前段時間寫了一個簡單協議的狀態機,代碼就不寫了,說一下大概吧
1、確定一共有多少種狀態,這里的狀態有開和關,細分還有say thankyou 和警告
2、確定狀態之間的遷移條件
如果按照四種狀態:開、關、說謝謝、警告,那麼這四種狀態之前的遷移條件很明顯了
分兩個函數:1、檢查是否需要遷移狀態;2、遷移狀態。
遍歷各種狀態檢查是否有狀態需要發生遷移。一般用一個switch將各種狀態列出,然後在各種狀態裡面用if檢查是否需要遷移狀態,如果需要遷移,做好標記。
再次遍歷各種狀態,檢查哪些狀態做了標記,遷移到新狀態,並做相應的操作,比如進入關的時候,做關門動作
剛才忘記說了,還有一個運轉狀態機函數,main函數在被觸發的情況下調用運轉函數,觸發條件有:投幣,人進入。
8. C語言作業C/C++數學詞法分析器。最好是用狀態機做的,沒有也沒關系,我給出狀態機的圖,和分析器的線路圖
我記得有個神奇的東西叫做bison&flex
嘛……只是這么一說你可以自己慢慢研究……
用來做作業好像不太道德啊=w=
9. 狀態機:用51單片機實現時鍾、加法的實現。用keil軟體,不能用delay。
這個功能寫出來也太長了
10. 向單片機高手求助,怎樣用C語言編寫歌曲程序和歌曲代碼需要用那些工具怎麼樣編寫的要求詳細解答。謝謝!
首先要懂的音樂基本知識。我用高級語言編過多次,了解編程方法:
1。四分音符、八分音符、十六分音符。。。其實這是相對音長,
發音的時間相對值就可以了。
2. 音的頻率,也是相對值,從某一音(從低音3)開始計算好各個音的頻率:
半音(3與4,7與.1)頻率的倍數(2開12次方),全音的倍數是2開六次方,
這樣一個八度剛好頻率2倍;
你可以先計算好所用到的各個音的頻率,初始頻率自已定,如440Hz;
按上面的兩個相對參數發音,音樂就出來了,掌握了原則就很簡單。