久久99精品久久久久久琪琪,久久人人爽人人爽人人片亞洲,熟妇人妻无码中文字幕,亚洲精品无码久久久久久久

《C專家編程》總結

時間:2019-05-12 00:04:02下載本文作者:會員上傳
簡介:寫寫幫文庫小編為你整理了多篇相關的《《C專家編程》總結》,但愿對你工作學習有幫助,當然你在寫寫幫文庫還可以找到更多《《C專家編程》總結》。

第一篇:《C專家編程》總結

《C專家編程》總結

開始讀《C專家編程》之前,有一個很擔心的問題:94年出的講語言的書,在現在(2012)還有多少是適用的。因此,一邊讀,一邊用VS2010做實驗。最后發現大部分內容都還在用。讀完后,覺得最精彩的部分有二:一是講解如何理解聲明,二是深入地講解數組名與指針。下文是將看書過程中所做的筆記進行的整理。

p.s: 以下代碼均在VS2010測試過

1.使用無符號數時要特別注意(不推薦使用無符號數)當無符號數與有符號數在同一條表達式中出現時,有符號數會被轉換為無符號數。e.g:

int feng =-1;unsigned int yan = 5;bool result =(feng < yan)? true : false;//最后的結果會是false 原因是C語言在計算含有不同類型的表達式時,會將類型向上提升。在本例中,int被提升了unsigned int,從而使-1的補碼被解析為很大的整數 2.相鄰的字符串常量會被自動合并成一個字符串 e.g:

char *str[] = {“feng” “yan”, “zero”};//“feng”和“yan”被合并成一個了:“fengyan” 3.易出錯的優先級

.高于* e.g: *p.f 正確的理解:*(p.f)

[]高于* e.g: int *ap[] 正確的理解:int *(ap[])ap是個數組,其元素為int* 函數()高于* e.g: int *fp()正確的理解:int* fp()fp是返回int*的函數

==和!=高于位操作符 e.g: val & mask!= 0 正確的理解:val &(mask!= 0)==和!=高于賦值符 e.g: c = getchar()!= EOF 正確的理解:c =(getchar()!= EOF)

算術運算高于移位運算 e.g: msb<<4 + lsb 正確的理解:msb <<(4 + lsb)逗號運算符優先級最低 e.g: i = 1, 2 正確的理解:(i = 1), 2 4.理解聲明,定義,typedef語句的步驟

a.找標識符

b.找被括號括起來的部分

c.找后綴操作符,如果是(),則表示是函數;如果是[],則表示是數組 d.找前綴操作符,如果是*,則表示“指向XX的指針”

e.找const和volatile,如果const,volatile后面緊跟類型(如int,long),那么它作用于類型,其它情況下,作用于它左邊緊鄰的項 e.g:

int const * zero;//zero是一個指針,指向一個常量整形

char(*zero)[20];//zero是一個指針,指向一個有20個char元素的數組

typedef void(*ptr_to_func)(int);//ptr_to_func是新類型名,這種類型是一個函數指針,指向接收一個int參數,并返回void的函數

char* const *(*zero)();//zero是一個函數指針,該函數無參數,并返回一個指針,返回的指針指向一個常量指針

char*(*zero[10])(int **p);//zero是一個數組,元素是函數指針,其指向的函數授受一個二維指針,并返回一個指向char的指針 void(*signal(int sig, void(*func)(int)))(int);//signal是一個函數,該函數接收一個int,一個函數指針,并返回一個函數指針

5.左值與右值

左值通常表示存儲結果的地方(地址),其值在編譯時可知 右值通常表示地址的內容,其值通常要到運行時才知道

6.指針與數組名不等同的情況(定義為數組,卻聲明為指針,或者反過來)前提知識(假設有定義:int array[10], *ptr;):

a.使用數組名下標訪問(如:array[1]),會直接將數組名的地址加上偏移值作為變量的地址(即array[1]的地址)

b.使用指針下標訪問(如:ptr[1]),會先取指針指向的內容,然后將這個內容加上偏移值作為變量的地址(即ptr[1]的地址)

不等同的原因:

當定義為數組,卻聲明為指針時,相當于用指針下標訪問的方法來解析一個數組名下標,即先取數組第0號元素的內容,然后將這個內容加上偏移值作為變量的地址,從而訪問了不該訪問的東西。反之亦然。7.指針與數組等同的情況

a.編譯器將表達式中的數組名當作指向該數組第0號元素的指針,下標當作指針的偏移量,即array[i]會被當作*(array + i)

b.編譯器將函數參數聲明中的數組名當作指向該數組第0號元素的指針,即在函數內部得到的是指針,而不是數組名

基于a情況,可知這條謠言是假的(至少在一維數組中一定不成立): 用指針迭代數組比用下標迭代數組更快

基于b情況,可解釋為什么在傳遞數組后,不能用以下方法計算數組長度

int ArrayLength(int arr[]){ return sizeof(arr)/ sizeof(arr[0]);//返回值必定是1,因為此時的arr是一個指針,而不是數組名 } 注意b情況的將數組改寫為指針并不是遞歸定義的,e.g:

實參 char zero[10][10] 被改寫為 char(*zero)[10],這里將數組的數組改寫為數組的指針

實參 char *zero[10] 被改寫為 char **zero,這里將指針數組改寫為指針的指針

實參 cahr(*zero)[10] 不改變,因為此時的zero是指針,而不是數組 8.interposition interposition指用戶定義的函數取代庫中聲明完全相同的函數,注意這不是指重載,而是指下面這種:

void zero();//user defined function void zero();//library function 出現interposition時,要特別注意以下情況:

void zero();//user defined function int main(){ zero();//調用用戶定義的函數zero,而不是庫函數zero

FengYan();//假設這是另一個庫函數,并且函數內調用庫函數zero,此時由于interposition,變成調用用戶定義的zero return 0;} 備注:

出現interposition時,在VS2010會出現warning: inconsistent dll linkage 9.堆棧段作用

a.存儲局部變量

b.函數調用時,存儲有關的維護信息

c.用作暫時存儲區。e.g: 計算一個很長的表達式時,會把部分結果先壓到堆棧中

第二篇:編程知識總結C難點總結

《編程知識總結》—C#難點總結

1.編寫菜單中對應子菜單項的消息響應函數,考慮的方面很多,例 如,當前打開一個文件,此文件已經被修改,如果用戶需要新建 或者打開另外一個文件,程序要詢問用戶是否保存當前的文件。

問題的解決:先用紙張寫一份詳細的業務流程圖,在之后的編寫 過程中,按照業務流程的規定進行功能的逐步實現。

2.編寫判斷是否要提醒用戶保存的程序,判斷是否提醒保存的根據 是什么。我的判斷根據驗證文件內容是否被修改,如果被修改,提醒用戶保存。如果被保存的文件沒有文件路徑,調用另存為的 響應函數進行執行。

3.無法關閉窗體,當我響應文件菜單下退出菜單項的時候,如果使 用 Close()函數的話,可以就直接退出,但是當我需要以同樣的 方式響應右上角關閉按鈕的話,事件信息就會進入死循環,而且 永遠不會結束。所以,在關閉窗體的時候,目前我用的就是 Application.exit();這個函數,強制性終結這個窗口

4.保存文件,我們打開文件和直接輸入信息的文件的情況,對于保 存來說是不一樣的,因為打開的時候,應該是直接保存到指定的 文件中,而直接輸入的應該提示保存,通過另存為的方式保存。5.文件的刪除。C#的 textBox 沒有直接為我們提供文本刪除的函數,我弄了許久,后來,無意間突然發現通過已經選擇的字符串的下 標來操作,就可以刪除文件了,具體操作就是,先獲取被選擇文 件的前半部分,在獲取后半部分,而略過中間被選中的部分即可。6.開始的時候沒有使用 Using System.IO,系統報錯;

7.由于在 MessageBox.Show 后沒有寫 return 導致錯誤;

8.初步創建簡易記事本后點擊打開文件選項并不顯示文件的內容,且編譯器報錯了,是由于沒有判斷文件名為空,且文件的完整路 徑名獲取的不準確,將文件名為空的情況及其文件的完整路徑名 獲取之后,讀取文件正確;

9.首先,我在添加單擊“新建”響應的代碼時,單擊進去,結果代 碼全部不能運行,必須是雙擊。

10.獲取文件名時,文件名不需要特別處理,程序內部直接處理好的,我在這里畫蛇添足了。

11.操作對象必須指代明確,不如要出錯。

12.在用 WinForm 做文本文檔的時候,在“新建文本文檔”項的代碼 中,需要在項目中新建一個 new 窗體作為“新建文本文檔”,在 form1 的代碼中寫如下代碼: Form frm = new NewForm();frm.Show();this.Hide();然后在 Form2 中下如同樣的代碼即可。

13.還發現“保存”與“另存為”項的代碼編寫沒有任何差異,考慮 并修改程序無果。代碼如下: private void 保存SToolStripMenuItem_Click(object sender, EventArgs e)// { DialogResult save = saveFileD

ialog1.ShowDialog();

if

(save

== DialogResult.OK){ string filepath = saveFileDialog1.FileName;//FileInfo fi = new FileInfo(filepath);string content = richTextBox1.Text;File.WriteAllText(filepath, content, Encoding.Default);} } 14.在保存的時候必須輸入保存路徑才能正常執行,沒有實現文本文 檔的基本保存功能。并且在打開一個原本有內容的文本文檔之后,加以修改再保存就不能保存新的內容。

15.獲取 TextBox 中獲取一行的值,使用 TextBox 的 Lines 屬性來獲 取

16.做刪除操作時,由 MessageBoxv.show 來彈出一個確認窗體,把返 回的值賦給一個 DialogResult 類型的變量

17.在復制文件時,CopyTo 函數將第二個參數置為 TRUE 則在復制時,如果文件存在會被覆蓋掉。

18.在向文件寫入數據時,使用 Encoding 的 Default 的屬性可避免輸 入中文亂碼問題。19.關于上午的文件編程,剛開始對程序要執行的具體操作不夠明確,在編程時,功能實現的矛盾性問題很多,其問題在于編程前分析 不夠到位;

20.文件編程中起先將打開文件定位為文件夾,導致彈出對話框顯示 “不存在此文件”; 21.File.WriteAllLines(),無法將臨時修改后的文件信息進行正 確保存,文本沒有實現正確的回車換行;File.WriteAllText()能實現;

22.this.Close()無法實現程序的結束 Close()方法是關閉 Form 23.當創建了控件的響應事件后,修改控件的 name 屬性,響應事件 名為改變,但并不影響進程的進行,要修改方法名應刪除該響應 方法,雙擊控件,重新獲得響應事件。

24.代碼經常會出現命名不規范的情況,同時沒有寫注釋的習慣

25.經常會丟掉方法后的括號,如 savedialog1.showdialog()26.一 些 方 法 中 的 細 微 差 別 如 File.Write.AllLine 27.對于異常的處理經常忽略,導致程序的容錯處理比較差。

28.當編輯框改變時有兩種情況,一種是打開,一種是編輯,當打開 時不應該記錄改變標志。解決的辦法:做一個打開標志,當打開操作時,賦值為 true,在 文本框的改變函數中判斷,如果是打開操作,將打開操作之位 false,同時文本改變標志值為 false

29.此處如何把長整形變量賦值給一個 string 類型? 使用 ToString()30.如何在文本框上添加滾動條。設置 TextBox.ScrollBars

31.textbox 控件大小跟窗體一起變化:剛開始想通過相應窗體大小 改變事件的辦法解決,后來通過其他同學得知可以通過更改 textbox 的 Dock 屬性(改為 Fill)來解決。

32.當 textbox 空間的文本改變時,進行新建、打開、退出等操作時 應提示用戶是否保存更改,通過設置文件更改標志(flag)并相 File.WriteAllText 和 響 textbox 的 textchanged 事件來解決。

33.由于需要提示用戶保存更改,剛

開始時代碼控制結構寫的很復雜,連自己也有點難理解。后來用調用“保存”事件的響應函數(剛 開始一位不能這樣)后才解決這一問題。

34.由于剛開始做,命名方面不是很規范,導致了變量、方法和類的 名字不易區分,不能一目了然,間接增加了編寫程序所需的時間。解決方法是在編寫程序中時刻遵守命名規范。

35.在對文件操作時,文件的路徑經常出錯,原因是少了轉換為絕對 路徑的@。

36.對文件注釋太少,經常導致前面編過的代碼過一段時間就完全看 不懂了,所以,在編程中也要養成隨時加注釋的習慣,其實這樣 做表面上是增加了時間,統籌來看,這樣做既方便了自己日后修 改程序,又為閱讀我們程序的人提供了便利。

37.文件操作經常出錯,程序無法運行,要因此要異常處理,比如說 用 try,catch 對異常處理。

38.在昨天上午的文件操作中,第一個問題就是路徑的合法性檢測。由于不知道 c#是否存在像 c++ access()一樣的方法。最后使用 OpenFileDialog 來限定用戶輸入。可以使用正則表達式驗證 39.再有就是文件操作異常處理。C#的異常處理還是很方便的,昨天 的經驗是只要使用 try catch 語句,在 catch 中不作任何處理程 序也不會當掉。

40.MessageBox.Show(“你還沒有保存上次的修改,是否保存修改?”, “保存”, MessageBoxButtons.YesNoCancel);選項的判斷 問 同 學 得 : 返 回 值 為 DialogResult.No DialogResult.Yes DialogResult.Cancel 41.2 . private

void

Form1_FormClosing(object

sender, FormClosingEventArgs e)中如何取消關閉 問同學得:e.Cancel = true;42.如何實現修改后 “新建”“打開”等提示保存 點打開保存后記 錄存儲路徑

43.新建 2 個成員記錄:private string Pathname;private bool savetxt=true;

44.如何在兩個窗體間傳遞值。通過向同學和老師詢問,知道傳值有 很多種方法,我用的就是調用構造函數,可是老師也說了如果值 比較多的時候,這種方法還是有缺陷的。使用構造函數可以,只是也用對象會好一些。

45.當漢字改成英文時,函數中仍然是漢字,如果直接在 program.cs 中改容易出問題,怎么改? 利用 VS 的代碼重構

46.如何改窗體的默認主題樣式 可以使用第三方控件完成

47.TextBox 中文本值改變時的響應事件(可以添加事件響應函數)。

48.文 件 打 開 中 將 文 件 寫 到 textbox 中 : 定 義 string[] 調 用 File.ReadAllLines 函數將文件內容逐行讀入到字符串數組中,然后利用 for 循環將文件內容逐行寫出到控件中。

49.填寫郵箱和文件路徑的時候需要有正確的規格,因為之前接觸過 c#不知道該如何完成,后來在經過詢問他人和網上資料查詢得知 用正則表達式來規范正確

的格式,便避免了這方面因格式而導致 的問題。

50.當輸入多行字符串,保存過后進行查看時,當有換行就會出現黑 乎乎的正方形。換行:rn

51.假設某個事件已經做好,可以作為一個模塊使用,那么如何在其 他代碼中調用此模塊

52.記事本的查找、替換模塊不知道如何實現 需要使用字符串函數

53.打開 txt 文件的時候中文沒有亂碼但是保持了之后在打開就有了 亂碼 實現:原先是因為保持的時候沒有使用 encoding.default 54.保存時文件不能自動保存文件 ?自動保存文件

55.在做簡易記事本的途中,創建快捷鍵的時候遇到一點問題,當在 雜項的 Shortcutkeys 中選擇 shift 的時候,它會報屬性值無效的 錯誤,后來無奈之下選擇了 Ctrl,居然就正確了

56.還有在 TextBox 的屬性 Dock 選擇了 fill 的時候,依然沒有變成 全部填充,真是百思不得其解!需要將 TextBox 設置為多行文本

57.發現了一種比較簡便的方法: 已經做完的某個控件出發的事件,可以作為一個法方來使用。例: private void SaveMenu_Click(object sender, EventArgs e){ //判斷文件是否已有路徑,若無,選定路徑,若有,保存在最新操作的文件路徑下 if(path == string.Empty){ if(SolgSave.ShowDialog()== DialogResult.OK){ path = SolgSave.FileName;File.AppendAllText(path, txtEdit.Text, Encoding.Default);} } else { File.AppendAllText(path, txtEdit.Text, Encoding.Default);} } private void ExitMenu_Click(object sender, EventArgs e){ if(txtEdit.Text!= string.Empty){ DialogResult dr = MessageBox.Show(“是否保存當前文本至

”+path,“

”, MessageBoxButtons.OKCancel,MessageBoxIcon.Warning);if(dr == DialogResult.OK){ //使用保存文本方法 this.SaveMenu_Click(sender,e);//SaveMenu 的單擊事件 } } //退出程序 Application.Exit();}

58.RichTextBox 與 TextBox 的換行區別問題。在 TextBox 中是以rn 為換行標志,而在 RichTextBox 中是以n 為換行標志。我在 C#程序中使用 RichTextBox 將其文本內容保存為文本文件,即(*.txt)類型的文件時,文本不能正常的換行,且出現一些亂碼。這是由于文本文件是以rn 作為換行符,當我改用 TextBox 時,就 沒有這樣的問題了。

59.文本的選中問題。SelectedText 這一屬性可以指向當前控件中選中的文本,60.通常我們會發現,保存操作在文本沒有保存的情況下時才會出現 保存文件對話框,當文本已經保存過時,新增的文本會保存到原 文件中,這兩個操作需要對文本是否保存過進行判斷。我采用了 判斷路徑的方法對我文本是否保存過進行了判斷,當文本路徑存 在時,表明文本已經保存過,反之,則沒有保存過。

第三篇:C語言編程自我總結

1.編譯器選擇8級優化時,可能會出現錯誤。剛寫好的程序,建議先用0級優化看能否正常運行,再用更高的優化等級進行優化。

2.a、寫中斷程序一定要用using語句指定寄存器組。第1、2、3組都可以,不能是0,否則可能會main()函數沖突。從一個中斷程序中調用函數必須和中斷使用相同的寄存器組(摘自《Keil Cx51 編譯器用戶手冊中文版》P129)。建議把原本中斷函數需要調用的函數直接寫在中斷函數里,無須調用。

b、51單片機的中斷有兩個優先級。一個中斷不會打斷另一個相同優先級的中斷。這樣相同級別中斷可以使用同一個組。比如:低優先級的中斷函數都用 using 1,高優先級的中斷都用 using 2。這樣不會沖突。

3.C語言無符號數容易犯的錯誤。若定義成有符號數char,則不會陷入死循環。

main(){ unsigned char i;for(i = 2;i>=0;i--){ printf(“%d”,i);} }

4.C51忌諱使用絕對定位_at_,因為只要定義變量和變量的作用域,編譯器就會把一個固定地址給這個變量,無須人工將其絕對定位,這樣可能引發其他問題。

5.bit與sbit的區別:bit定義的位標量的地址是隨機的,而sbit定義的位標量的地址是確定的。bit只能訪問芯片內部RAM中的可尋址位20H-2FH,而sbit可以訪問芯片內部RAM中的可尋址位和特殊功能寄存器中的可尋址位。注意不能直接在程序里用P1^0等位變量,需要經過sbit定義才可以使用。例如:

bit

tem;sbit led=P1^0;tem的地址是隨機分配的,而led的地址則固定為0x90.0。sbit變量后面需要跟等號=。6.為了避免由于使用參數宏而帶來意外的錯誤,需要注意以下幾點:

6.1 宏的參數必須帶括號,例如 #define CIRCLE_SQUARE(R)3.141*(R)*(R)6.2 對所使用的參數宏進行簡單地展開檢查;

6.3 使用簡單表達式、對參數加括號、避免節外生枝的使用方式(例如“++”、“--”一類都屬于不必要的附件運算);

6.4 在參數宏定義時,對于運算順序通過括號進行明確的限定,只要遵循以上幾點,就可以避免大多數應用場合的意外錯誤。

手把手教你寫程序

內容:從最簡單的程序入手,手把手教你寫程序,讓同學們拿到一個復雜的程序或者任務,能快速找到切入點,寫出程序,再在此基礎上優化程序。當拿到一個單片機任務時,不要急于動手寫程序,先仔細分析它的以下幾個點:

1、它要單片機整體實現什么功能

2、功能細分(模塊化),先干什么,再干什么,最后干什么

3、畫初步流程圖,(把幾個模塊畫出即可)

4、模塊之間的分析:一個模塊到另一個模塊之間,怎么變換,怎么連接(優化流程圖)

5、單個模塊分析:每個模塊要做什么(流程圖細化)

6、所有模塊結合連接,細化所有流程圖

7、分析單個模塊每步要用到的方法或者指令

8、總流程圖定型

9、紙上寫程序,對照流程圖分析其可行性,若不可行則返回

10、上機調試,加注釋

11、從小到大,一個功能一個功能地調試;

以上十一步,缺一不可(小程序例外)切記:流程圖的確定很重要,需反復修改

大忌:拿到任務,不仔細分析就寫程序。即使是小程序,我們也要養成良好的編程習慣,不要一味的追求結果。寫小程序可能比別人快,若是大程序,一旦出現思維混亂,或者出現程序調試不出結果,那么你花在調試上的時間,要比別人的多。!!!磨刀不誤砍柴工!!!程序的優化:屬于后期工作,只有調試出來后,才去優化,如果一開始優化和寫程序同時進行,一是加重你的思考量,二是出現問題無從下手。無疑增加了寫程序的難度。對于一個初學者,寫一個程序,本身頭腦就處于緊張的狀態,思考的問題就很多,如果此時把優化程序也考慮進去,你腦袋的負荷無疑加重,若你頭腦精明,你可以把優化的地方,先在紙上記下來,等到調試結果正常,再把你想到的,優化的地方加進去。

7、如果在中斷程序中改變了多字節類型的變量,那么中斷程序以外的程序中(主程序,子函數)要使用該多字節類型變量的話,讀寫前要關中斷,讀寫后再開中斷。否則會導致偶爾讀寫錯誤。(實質為資源沖突)舉一反三:

其他的數據類型也可能有這種影響。例如:長整型、浮點型。例如:

unsigned int ms_counter;void T0(){ //定時器程序每100毫秒中斷一次,程序略 if(ms_counter<1000)ms_counter++;} void main(void){ //初始化定時器程序每100毫秒中斷一次,程序略 unsigned char tt;ms_counter=0;tt=0;//用tt控制只響一次 while(1){ if(ms_counter<400){ if(tt==0){ tt=1;Sound_on();

} } else { Sound_off();} //其他程序 } }

8、sbit變量不能使用extern關鍵字,使其在不同的文件中被使用,如要在led.c和main.c文件中使用同一個變量led0,有以下下兩種辦法:

1.在各種文件中重復定義變量,如在led.c中定義sbit led0=P1^0;同樣在main.c中定義sbit led0=P1^0;這樣,led0就變成了全局變量,可以在兩個文件中使用。

2.將sbit led0=P1^0定義到led.h頭文件中,均在led.c和main.c中包含led.h這個頭文件。

9、在多文件的程序中聲明外部變量(extern和)

如果一個程序包含兩個文件,在兩個文件中都要用到同一個外部變量Num,不能分別在兩個文件中各自定義一個外部變量Num,否則在進行程序的連接時會出現“重復定義”的 錯誤。正確的做法是:在任一個文件中定義外部變量Num,而在另一個文件中用extern對Num作“外部變量聲明”。即extern Num;注意若Num為uchar類型,應當寫為“extern uchar Num”,否則會當為int,而導致出錯。

當使用static聲明變量和函數時,需要在定義變量和函數的基礎上加上此關鍵字,而不能單獨使用。例如:

static int a;//定義性聲明,需要時,直接使用變量a即可 a = 0x01;

static int funA(int a, int b);//聲明,且static不起作用 int funA(int a ,int b)//定義,即使funA有static關鍵字修飾,但由于static不能單獨使用,//故funA仍為外部函數。

{ …… } extern對變量進行聲明時,如沒有初始化,則為引用性聲明,不含定義,如需使用此變量,需要進行定義。例如:

extern int a;//引用性聲明,不含定義

extern int a = 0x01;//定義性聲明,需要時,直接使用變量a即可 int a;//定義

extern對函數進行聲明時,如沒有函數體,則為引用性聲明,不含定義。

extern int funB(int a ,int b);//引用性聲明,不含定義,且extern聲明可以省略

extern int funC(int a, int b)//定義性聲明 { …… }

10、一般的,要盡量減少中斷服務程序的內容和長度。因為在主程序中可以還需要隨時響應其他的中斷或事件。如果一個中斷服務程序過程,很可能會影響到主程序對外部信號的檢測和響應。通常,在中斷程序中只是改變一些變量或標志位,在主程序中再根據變量或標志位的值進行判斷,處理相應的事件。

11、在A/D和D/A轉換電路中,電源電壓和基準電壓的穩定性,對轉換的精度影響很大。另外,A/D和D/A轉換電路中要特別注意地線的正確連接,否則轉換結果將是不正確的,干擾影響將很嚴重。

12、根據C語言標準,左移“<<”和右移“>>”運算要求操作數至少是int,如果不滿int,自動轉換成int(C語言整型提升)。因此 uchar a=0x01;a<<8;實際運算,并不是8位數左移8位,而是int型左移8位。

13、在中斷里調用其他函數,且要進行參數傳遞時,必須保證被調用函數所使用的寄存器組與中斷函數一樣,否則會產生不正確的結果。為了保證被調用的函數與中斷函數使用的寄存器一致,可對被調用函數使用using,不過此函數只能被中斷函數調用。

14、函數不使用using 時,所使用寄存器組保持與此函數被調用前相同,不對RS0和RS1的值進行修改;當使用了using 關鍵字后,此函數所使用的寄存器組與using所定義的一樣。

15、當指定中斷程序的工作寄存器組時,保護工作寄存器的工作就可以被省略。使用關鍵 字using 后跟一個0 到3 的數對應著4 組工作寄存器當指定工作寄存器組的時候默 認的工作寄存器組就不會被推入堆棧這將節省32 個處理周期,因為入棧和出棧都需要2 個處理周期。為中斷程序指定工作寄存器組的缺點是所有被中斷調用的過程都必須使用 同一個寄存器組否則參數傳遞會發生錯誤。

16、如何使用pdata 類型的變量?當要使用到pdata 類型的變量,如下: void main(void){ uchar pdata a;a=0x01;}

則需要進行如下設置,否則pdata 的變量a則會無效。

a、修改STARTUP.A51的內容。默認時,PPAGEENALBE為0,表示不允許pdata類型的變量,須將其值改為1;PPAGE表示pdata類型的變量存儲在哪一頁,01H表示存放在外部存儲器的第1頁,地址范圍100H至1FFH,此時P2經STARTUP.A51處理后的值為0x01;此項設置需和BL51連接器的設置一致。

b、修改BL51連接器。根據STARTUP.A51中PPAGE所設置的值來填寫Pdata的值,如下圖。圖中Pdata的值可以填寫100H至1FFH中任意一個,表示pdata類型的變量從所填

寫的值開始存儲。例如,當Pdata填寫的值為108H時,表示pdata類型的變量從108H開始存儲,因此,存儲范圍變為了108H至1FFH。

另外,存儲模式Compact的作用是將沒有指定存儲類型的變量定義為pdata類型,對uchar pdata a;變量的定義沒有影響,但對uchar a;則有影響。

17、XBYTE的用法。XBYTE存在于#include 頭文件中。

XBYTE[0x000F]=data; // 此語句表示將data寫到外部RAM中的0x000F data=XBYTE[0x000F] // 此語句表示讀取外部RAM中0x000F的數據 以下語句與上面的語句等效:

#define EX_RAM XBYTE[0x000F] //將EX_RAM定義為外部RAM的地址0x000F EX_RAM=data;// 此語句表示將data寫到外部RAM中的0x000F data=EX_RAM // 此語句表示讀取外部RAM中0x000F的數據

18、如何在keil中用匯編實現51中沒有的指令

部分MCU與8051兼容,但會增加8051中沒有的指令,如華邦的W77E58和N79E352等芯片,具有8051中沒有的指令DEC DPTR。如何才Keil中實現此指令呢? 方法1:

在需要執行該指令的地方放置相應的機器碼 MAIN:

MOV DPTR,#02H DB 0A5H;由于從數據手冊上得知,DEC DPTR的機器碼為0A5H,故此處相當于執行了DEC DPTR指令。

AJMP $ END

方法2:

使用宏定義的方法

/*宏定義,表示用DEC_DPTR代替MACRO與ENDM之間的內容*/ DEC_DPTR MACRO

DB 0A5H;此處不能與MACRO同一行 ENDM

MAIN: MOV DPTR,#02H DEC_DPTR;放置機器碼0A5H,相當于執行DEC DPTR AJMP $ END

通過將以上兩種方法生成的hex文件調入到編程器中,發現代碼一樣。經測試,同樣可以用以上兩種方法代替8051中已有的指令。

例如,從數據手冊可知,MOV A,#0FH的長度為2字節,機器碼的值為74H,0FH。因此,經驗證,以下三個程序等效,產生的HEX文件一樣 MAIN: MOV A,#55H DB 74H DB 0FH MOV P1,A AJMP $ END

MAIN: MOV A,#55H MOV A,#0FH MOV P1,A AJMP $ END

TEST MACRO DB 74H DB 0FH ENDM MAIN: MOV A,#55H TEST MOV P1,A AJMP $ END

18、匯編中包含頭步驟:

例如,T2CON為定時器2的特殊功能寄存器,地址為0C8H,要對此寄存器賦值01H,除了

MOV 0C8H,#01H 和

T2CON EQU 0C8H MOV T2CON,#01H 外,還有用包含頭文件的方法 #include MOV T2CON,#01H 此時,需要將A51中的“Defines 8051 SFR Names”的勾去掉。

19、指針

C51 提供一個3 字節的通用存儲器指針。通用指針的頭一個字節表明指針所指的存儲 區空間,另外兩個字節存儲16 位偏移量。對于DATA IDATA 和PDATA 段只需要8 位偏移量。Keil 允許使用者規定指針指向的存儲段,這種指針叫具體指針。使用具體指針的好處是節省了存儲空間編譯器不用為存儲器選擇和決定正確的存儲器操作指令產生代碼這樣就使代碼更加簡短但你必須保證指針不指向你所聲明的存儲區以外的地方否則會產生錯誤而且很難調試。

由于使用具體指針能夠節省不少時間所以我們一般都不使用通用指針。

20、EEPROM存放開關機(復位)次數方法:每次開機(復位)讀取EEPROM存放開關機的數據,并加1后重新寫入EEPROM。

21、C51中,將printf函數與串口輸出結合注意事項:

a、關串口中斷;

b、初始化串口,并使TI=1;

c、KEIL里擴展出了b(8位),h(16位),l(32位)來對輸入字節寬的設置

在Keil C51中用printf輸出一個單字節變量時要使用%bd,若使用%d,則默認為雙字節寬度,輸出可能會出錯。如

unsigned char counter;printf(“Current count: %bdn”, counter);而在標準C語言中都是使用%d: printf(“Current count: %dn”, counter);d、輸出數據類型的長度應與定義的數據類型長度一致,如:

uint tem2=97;

printf(“%c,%bdn”,tem2,tem2);第一個輸出會出錯。

22、我一般不刻意的注意這個,都是從軟件自身找問題的。

我寫程序時對于軟件抗干擾都是在程序狀態上考慮意外情況的,例如:

if(a == 1){...} else if(a == 2){....} else{//這個else 一定得加的,即使自己認為不可能出現的情況也要加上

..//經過好多程序走飛的情況發現:大多情況都是缺少這個語句條件的,這 //語句可以寫成重新初始化a } 還有程序出現堆棧比較深的運算(例如浮點乘除法后)或中斷比較深,我加2個_nop_();

23、STC12C5410AD外部RAM使用方法:

a.在Keil中設置外部RAM的起始地址和大小,如下圖

b.將變量定義為xdata即可。

24、中斷嵌套

當有外部中斷0時,中斷標志位IE0由硬件自動置1,進入中斷服務程序后,IE0被自動清0。若外部中斷0觸發信號在執行完中斷服務程序后仍沒有撤除,就會再次使已經變0的中斷標志位IE0置1,再次進入中斷服務程序;若在響應中斷服務程序期間,再次產生外部中斷0觸發信號時,此中斷不能被識別,因為CPU在響應中斷時會自動關閉同一中斷。

如果外部中斷0比外部中斷1的優先級高,當在響應外部中斷0期間產生外部中斷1時,如果執行完外部中斷0后,外部中斷1的中斷請求標志位IE1仍沒有清除的話,將會響應外部中斷1的請求;但是如果在響應外部中斷0期間,外部中斷1的觸發信號產生后又撤除的話,IE1也會自動清除,也就是說,執行完外部中斷0后,不會去響應外部中斷1。

當多個中斷源同時向CPU請求中斷時,CPU就可以通過中斷優先權電路率先響應中斷優先權高的中斷請求,而把中斷優先權低的中斷請求暫時擱置起來,等到處理完優先權高的中斷請求后再來響應優先權低的中斷。

如果某一中斷源提出中斷請求后,CPU不能立即響應,只要該中斷請求標志位不被軟件人為清除,中斷請求的狀態就將一直保持,直到CPU響應中斷為止。但是對于串行口中斷,即使CPU響應了中斷,其中斷標志位RI/TI也不會自動清零,而必須在中斷服務程序中設置

清除RI/TI的指令后,才會再一次地提出中斷請求。

25、在滿足應用要求的前提下,選擇配較低的單片機,較小的RAM/ROM、較低的ADC分辨率、較低的ADC速率,較少的IO管腳都可以降低單片機的整體功耗。當然了,這個得能滿足你產品需求的前提下。

26、對于一個數字系統而言,其功耗大致滿足公式:P=CV2f。其中C為系統的負載電容,V為電源電壓,f為系統工作頻率[2]。功耗與電源電壓的平方成正比,因此電源電壓對系統的功耗影響最大,其次是工作頻率,再次就是負載電容。負載電容對設計人員而言,一般是不可控的,因此設計一個低功耗系統,在不影響系統性能的前提下,盡可能地降低電源的電壓和工作頻率。對于大多數低功耗單片機來說,工作頻率越低,意味著消耗的電流也越小,但是不能認為頻率越低,系統整體功耗越小,因為工作頻率降低,意味著需要更長的處理時間,其他外圍電路消耗的電能就越多。目前有很多單片機都允許有兩個或者兩個以上的時鐘源,低頻時鐘作為如UART、定時器等外圍功能器件的時鐘源,高頻時鐘作為系統的主時鐘。在不需要高速運行的場合下,低頻時鐘也可以作為系統主時鐘使用。對于需要在工作狀態與空閑狀態之間頻繁切換的應用,在考慮單片機本身低功耗的同時,應該考慮切換時間和切換電流。考慮到有些場合單片機的工作特點,選擇單片機不光要關注工作電流,更應該關注單片機休眠時的靜態電流。單片機豐富的低功耗模式和極低的靜態電流,在滿足特定應用功能的同時,有效降低系統的功耗。盡量關閉MCU內部不用的資源,比如ATmega8內部的模擬比較器,默認是開著的,還有ATmega88內部的大多數資源都可以在不用的時候用軟件關閉。

27、定時/ 計數器的實時性

定時/ 計數器啟動計數后,當計滿回0 溢出向主機請求中斷處理,由內部硬件自動進行。但從回0 溢出請求中斷到主機響應中斷并作出處理存在時間延遲,且這種延時隨中斷請求時的現場環境的不同而不同,一般需延時3 個機器周期以上,這就給實時處理帶來誤差差。大多數應用場合可忽略不計,但對某些要求實時性苛刻的場合,可采用動態補償措施。

所謂動態補償,即在中斷服務程序中對THx、TLx 重新置計數初值時,應將THx、TLx 從回0 溢出又重新從0 開始繼續計數的值讀出,并補償到原計數初值中去進行重新設置。可考慮如下補償方法: CLR EA ;禁止中斷

MOV A,T L x ;讀TLx 中已計數值 ADD A,#LOW ;LOW 為原低字節計數初值 MOV T L x,A ;設置低字節計數初值 MOV A,#HIGH ;原高字節計數初值送A ADDC A,T H x ;高字節計數初值補償 MOV T H x,A ;置高字節計數初值 SETB EA ;開中斷

28、動態讀取運行中的定時器/計數值

在動態讀取運行中的定時/ 計數器的計數值時,如果不加注意,就可能出錯。這是因為不可能在同一時刻同時讀取THx 和TLx 中的計數值。比如,先讀TLx 后讀THx,因為定時/ 計數器處于運行狀態,在讀TLx 時尚未產生向THx 進位,而在讀THx 前已產生進位,這時讀得的THx 就不對了;同樣,先讀THx 后讀TLx 也可能出錯。

一種可避免讀錯的方法是:先讀THx,后讀TLx,將兩次讀得的THx 進行比較;若兩次讀得的值相等,則可確定讀的值是正確的,否則重復上述過程,重復讀得的值一般不會再錯。此法的軟件編程如下:

RDTM: MOV A,THx ;讀取THx 存A 中 MOV R0,TLx ; 讀取TLx 存R0 中

CJNE A,THx,RDTM ;比較兩次THx 值,若相等,則讀得的值正確,否則重讀 MOV R1,A ;將THx 存于R1 中

29、掉電及空閑模式

掉電方式

當PCON中的第二位PD為1時,進入掉電模式,不會執行任何指令,外部時鐘停振,片內所有功能部件停止工作,如定時器,串行口,外部中斷(部分增強型8051的外部中斷可以工作),但片內RAM和SFR的內容保持不變。標準8051從掉電狀態退出的惟一方法是硬件復位(部分增強型8051還可以通過外部中斷來退出掉電狀態),復位后,SFR被重新初始化,但RAM的內容不變。因此,若要使得8051在供電恢復正常后繼續執行掉電前的程序,那就必須在掉電前預先把SFR中的內容保護到片內RAM,并在供電恢復正常后為SFR恢復到掉電前的狀態。

當PCON的第一位IDEL為1時,進入空閑模式,CPU停止工作,不會執行任何指令,但中斷、串行口和定時器可以繼續工作。此時,CPU現場(即SP、PC、PSW和ACC等)、片內RAM和SFR中其他寄存器內容均維持不變。退出空閑模式有兩種方法:

一、被允許中斷的中斷源發出中斷請求;

二、硬件復位。30、看門狗應用

將喂狗操作(取反指令,如 CPL P1.0)分成兩步,放在主程序和中斷里執行。如將SETB P1.0放在主程序中,將CLR P1.0放在中斷里,這樣可以避免主程序跑飛,中斷功能正常或者主程序正常,而中斷跑飛的情況導致看門狗失效。

31、volatile作用

如果將將變量加上volatile修飾,則編譯器保證對此變量的讀寫操作都不會被優化(肯定執行)。此例中i也應該如此說明。

一般說來,volatile用在如下的幾個地方:

1、中斷服務程序中修改的供其它程序檢測的變量需要加volatile;

2、多任務環境下各任務間共享的標志應該加volatile;

3、存儲器映射的硬件寄存器通常也要加volatile說明,因為每次對它的讀寫都可能由不同意義;

另外,以上這幾種情況經常還要同時考慮數據的完整性(相互關聯的幾個標志讀了一半被打斷了重寫),在1中可以通過關中斷來實現,2中可以禁止任務調度,3中則只能依靠硬件的良好設計了。32、51準雙向口讀取:

只有1條指令:

MOV A,P1為讀端口寄存器 有兩條指令: MOV A,#0FFH MOV A,P1為讀引腳

33、采用C語言和匯編語言混合編程是最佳的選擇;

34、系統投入運行的最初時刻,應對系統進行自檢和初始化。開機自檢在初始化前執行,如果自檢無誤,則對系統進行正常初始化,通常包括硬件初始化和軟件初始化兩個部分。硬件初始化是指對系統中的各種硬件資源設定明確的初始狀態,如對各種可編程芯片進行編程、對各I/O端口設定初始狀態和為單片機的硬件資源分配任務等。軟件初始化包括,對中斷的安排、對堆棧的安排、狀態變量的初始化、各種軟件標志的初始化、系統時鐘的初始化和各

種變量儲存單元的初始化等。

35、按鍵連擊速度一般為3-4次/s。

36、復合鍵利用兩個以上按鍵同時按下時產生的按鍵效果,但實際情況下,不可能做到真正的“同時按下”,它們的時間差可以長達50ms左右,故當檢測到有KEY1按鍵按下時,還要等待超過50ms,再判斷是否還有其他按鍵按下,再解析按鍵。

37、數碼管顯示閃爍效果時,一般閃爍速度為1-4次/s。

38、大電流和高電壓設備的啟動和關閉都是由軟件指令來完成,這些指令執行后,必然引起強烈的干擾,這些干擾不能算隨機干擾,它們與軟件完全相關;可以在最后才執行這些可能引起強烈干擾的I/O操作,之后立即進入睡眠狀態,這樣就不會干擾到CPU,等CPU醒來后,干擾的高峰也基本過去。

39、用積分時間為20ms整數倍的雙積分型A/D轉換方式,能有效地抑制50Hz工頻干擾。40、掉電檢測電路必須在電壓下降到CPU最低工作電壓之前就提出中斷申請,提前時間為幾百us到數ms,以便掉電中斷程序進行掉電保護。

41、用定時器作看門狗:當為專職看門狗時,在主程序中周期性清0定時器計數值,以使定時器中斷不能產生,當產生定時器中斷時,表明看門狗溢出,此時應執行出錯處理程序或者進行復位。當為兼職看門狗時,可以在定時器中斷程序對計數值進行加1,若計數值大于某值時,表明看門狗溢出,而主程序中應周期性地對計數值進行清0。

42、中斷中,沖突發生的條件:

1)某一資源為中斷程序和主程序所使用;該資源可以為1個變量,也可以為1個數組或者1個緩沖區。

2)中斷程序或主程序對該資源進行了寫操作;

3)主程序不能用一條指令對資源完成讀或者寫操作。(這條不對,參考深入淺出AVR單片機P100的例子)

當這三個條件均滿足時,即有可能發生資源沖突,導致程序偶然運行不正常。為了避免發生沖突,可以在主程序中先關中斷,再對資源進行讀或寫,結束后再開中斷。

當主程序對資源的訪問比較費時,長期關中斷可能影響系統的實時性;解決的辦法是盡可能縮短關中斷的時間,將一邊訪問,一邊處理的工作方式改為集中訪問,分批處理。如果是讀該資源,則關中斷迅速將該資源的內容轉移到緩沖區,再開中斷,然后再對緩沖區中的信息進行處理;如果是寫該資源,則先邊運算邊寫緩沖區,全部寫好后再關中斷,然后迅速將緩沖區中的內容復制到該資源中,邊可以開中斷了。

43、A/B*C的運算方案不如(A*C)/B的運算方案精度高。因此,應盡可能將出現偏差的運算往后排,先進行無偏差或偏差小的運算。在定點運算系統中,加減法只要不超限,是沒有偏差的,乘法運算的結果會使字長增加,如雙字節乘雙字節,積為四字節,如果保留全部結果,則沒有偏差的。乘法運算的結果會使字長增加,如雙字節乘雙字節,積為四字節,如果保留全部結果,則沒有偏差;如果受字長限制,則要舍去低位字節,從而產生舍入偏差。除法幾乎都是有偏差的能夠剛好整除的情況是很少的。在浮點運算系統中,加減法由于要進行對階操作,當兩操作數的階碼相差較大時,絕對值大的數有可能將絕對值小的數淹沒,使運算的結果仍為絕對值大的數,一點兒也看不出絕對值小的數對結果的影響。相比之下,浮點乘法和浮點除法引起的偏差就比較小,它們能夠保持一個比較穩定的運算精度。另外,不管在定點系統中還是在浮點系統中,都要盡可能避免兩個數值相近的數過早相減,因為他們都可能是近似值,相減以后,差的有效數值大大減少,必然帶來更大的相對誤差。經過后續運算之后,結果可能離真實值相差甚遠。再有,盡可能不要用絕對值小的數作分母,否則引起的誤差也是很大的。

44、要對軟件標志位的使用進行說明;對于全局定義的軟件標志,它有惟一的定義;對于局

部定義的軟件標志,必須注明其有效范圍。

45、軟件理論已經證明:任何一個程序(除某些短小的子程序外)都存在錯誤(缺陷),人們可以通過合理的測試來證明它仍然存在錯誤,卻無法證明它已經沒有錯誤。軟件測試應該把發現錯誤作為目的,而不能把“程序調通”作為目的。

1.P0口能驅動8個TTL電路意思: 8051單片機P0口驅動8個TTL電路的意思,TTL電路輸入懸浮時相當于輸入高電平,因此P0口輸出高電平驅動TTL電路幾乎不需輸出電流。TTL電路輸入為低電平時最少要釋放1mA電流,因此P0口輸出低電平時吸收的電流大于8mA。TTL輸出高電平最大1.6mA,輸出低電平時吸收的最大電流 16mA。51輸出最好用低電平有效,推動PNP管,因為51復位后IO為高電平,如果用高電平有效推N管的話上電復位后會先讓外部電路動做。

2.在51里,有一條指令沒有寫進書本,機器碼為A5,執行操作:將下一個字節跳過而不管它是單字節指令還是雙字節或三字節指令的一部分.如果反匯編工具不識別A5指令的話,你在A5以后的程序反匯編后就錯亂無章.當成個數據,用db a5 即可

3.有些51系統容易復位,一般是電路設計上的問題。很多電路介紹的復位電路都是10u和8.2k,但是在實踐過程中我們發現該電路在電源不穩時很容易復位,特別是附近有大干擾時,如繼電器動作等。我建議使用22u和1k的復位電路,有許多電路改為該數值后就工作穩定了。當然,最好的辦法還是使用專用復位電路或三極管電路,但是那樣要增加成本和體積。

4.電路中的濾波電容一定要注意加上,最好每個芯片都再加一個約0.1uf的電容,這樣對電路的穩定性很有好處。如果使用了看門狗電路,就有可能是軟件問題,程序工作到某些環節時忘記了復位看門狗,結果計數滿了就復位了。

5.如果在中斷程序中改變了多字節類型的變量,那么中斷程序以外的程序中(主程序,子函數),讀寫前要關中斷,讀寫后再開中斷。舉一反三:

其他的數據類型也可能有這種影響。例如:長整型、浮點型。

上面的例子是中斷里寫,主程序中讀。相反主程序寫,中斷里讀也可能出錯。

6.教你一招,別說我損。。

寫一個測試代碼,反復向EEPROM中的某幾個不用的空位字節寫入0x55,直到把它干到壽命終結不能寫為止,如果按照10MS寫一個字節計算的話,大約只需要20分鐘就能干掉它。然后向這個芯片中燒入你的正常代碼,當然了,這個代碼中應該有一段上電檢測EEPROM這幾個字節的代碼,先嘗試向它寫入0Xaa,然后再讀出來看看是否寫入成功,如果沒寫入則再來兩次,如果始終不能寫入,這當作檢查通過,如果就判斷為檢查失敗,這個時候代碼要裝著‘不知情’繼續執行正確代碼,下面的‘破壞’行為應該如何做就不要我講了把? 破壞行為要裝的掩蔽一點,例如調一段代碼檫除FLASH的代碼,嘿嘿,那對方肯定以為CHIP質量不好容易出現FLASH數據丟失,如果對方使用了AD什么的,可以偶爾人為讓它波動大一點,這樣對方一般只會懷疑PCB和硬件電路弄的不好,而不會想到是代碼動手腳了,長久以后他的用戶肯定也會認為他們的產品質量不好,你這個時候就可以向他的客戶推廣你的產品了。。

上電寫EEPROM的次數要在你自己的產品質量承諾的壽命時間之內,否則你自己的產品也

可能增加維修。。

這個方法特別適合在外接單掙錢的工程師,你可能給了對方幾個CHIP做測試,對方測試通過偏說不行,就是不給你余款,然后把CHIP拿去CRACK,妄想省掉這個錢,NND,讓他們見鬼去把,俺這招已經對付了不少不良分子。。

7.AD鍵盤

8.防解密高招

高招, 解密

使用一些帶內部晶振和內部EEPROM的單片機,如PIC16F913和ATMEGA8等,帶內部晶振的單片機有一個寄存器OSCTUNE(或OSCCAL),這個是芯片廠家用來校準內部晶振的,范圍從0-31,出廠時同型號的單片機這個寄存器的值是不一樣.我們可以利用一些隱藏功能,將OSCTUNE寄存器的值存入內部的EEPROM中,開機時讀取EEPROM的值,再與OSCTUNE的值相比較, 若二者相同系統正常工作,若不

相同則不正常工作.解密者將解密的程序燒寫進單片機中后,會發大部分的芯片不能正常工作,因為他們不知道這個隱藏的功能.舉例說明: 芯片為PIC16F913,這個廠品有4個按鍵(KEY0、KEY1、KEY2、KEY3),內部我們可以設定這樣子一個隱藏的功能,如果KEY0與KEY1同時按下3秒鐘以上,會將OSCTUNE寄存器存入單片機的EEPROM中。

開機復位后,讀取EEPROM中的數據,與OSCTUNE寄存器相比較,若二者相同系統正常工作,若不相同則不正常工作。以上有三個重點:

1、對于OSCTUNE寄存器不要進行寫的操作,只進行讀的操作,因為寫了一次以后,就一直是你寫的這個數據的。

2、剛才介紹的KEY0、KEY1同時按下3秒鐘這個功能,可不能讓解密者(包括產品的用戶)知道,當然大家可以用別的隱藏的功能。

3、單片機中的OSCTUNE寄存器(或OSCCAL)的值,同一種型號的單片機不是每一個都是一樣的,有32個數據,也就是說32個芯片中有一個是與解密的單片機是一樣的。這樣子造成的后果是:解密者解密了你的程序以后,卻發現有些單片機可以正常工作,可有些單片機不能正常工作,可以說是大部分的單片機不能正常工作。

不過需要注意一下:要是遇到強干擾把EEPROM中的數據改變了看客戶怎么收拾你!

9.PIC16F887A中,要求SLEEP指令后的下一條指令為NOP;不知51和AVR的芯片是否需要注意這一點。經查,AVR的datasheet無此要求,可能是其喚醒時,存在啟動延時。

10.中斷隨時隨刻都有可能產生,故編寫程序時,需要時刻注意中斷的影響。

11.注意以下語句在某些編譯器下,結果可能出錯:

unsigned char a,b;

unsigned int sum;

a=0x80;

b=0x80;

sum=a+b;

12.編程序最重要是好維護。幾個執行時間和程序的可讀性比,和開發時間比,我認為是不用考慮的。為了幾個機器周期而把程序搞得很復雜,是非常愚蠢的行為。可是很多人多樂此不疲啊。總體系統的算法是要考慮優化的問題的,這點我是贊同的。天天在技術上對著幾行程序去優化,而導致開發速度減慢,是非常愚蠢的行為。

13.串口通信協議:引導碼/識別碼+長度+命令字+data+校驗

通過引導碼/識別碼、長度、校驗三步檢測 每當出錯則丟棄當前數據并還原接收狀態和空間…………

14.當準備調試一塊板的時候,一定要先認真的做好目視檢查,檢查在焊接的過程中是否有可見的短路和管腳搭錫等故障,檢查是否有元器件型號放置錯誤,第

一腳放置錯誤,漏裝配等問題,然后用萬用表測量各個電源到地的電阻,以檢查是否有短路,這個好習慣可以避免貿然上電后損壞單板。調試的過程中要有平和的心態,遇見問題是非常正常的,要做的就是多做比較和分析,逐步的排除可能的原因,要堅信“凡事都是有辦法解決的”和“問題出現一定有它的原因”,這樣最后一定能調試成功。

做一個硬件設計人員要鍛煉出良好的溝通能力,面對壓力的調節能力,同一時間處理多個事務的協調和決斷能力和良好平和的心態,還有細心和認真等等。

對初學者來說,在新的領域面前一窮二白,要學的東西太多太多,一味機械地試圖學習這些“高深的語法”和“看不懂的技巧”,胡亂模仿些別人的“優秀風格”,不能說完全無所得,只能說會學得很累,而且往往事倍功半---久而久之,信心喪失殆盡,半途而廢。學習編程,做自己便好。學習眼前能夠看懂的內容,多寫自己會寫的程序。對于已經學到的東西,仔細地體會、思考,發掘其中的發展;學會用一種研究的心態去考察你的每一個疑問;不可以輕易地人云亦云,在網上看了別人無責任的經驗,甚至是寫錯了,丟在一邊,懶得改的東西之后,就放棄了自己的探索;要學會堅持自我,遇到別人先進的做法,在自己還沒有體會到自己當前這種做法的劣勢之前,不要輕易盲從;同樣,使用了先進的方法,在沒有同時理解這種做法的優點和缺點之前,請不要輕易地感嘆“這種方法好,跟帖頂一下!”“大師高手寧有種乎?”堅持“體會到了才是學到了”的態度,最終形成自己的風格,形成自己的技巧。

第四篇:C語言編程

#include(stdio.h)

main()

{ int question[4]={-1,-1,-1,-1},i=0,j=0,k=0,A=0,B=0,answer[4]={0};

char again='y';

while(again=='y'){ srand((int)time(0));

while(i4){ k=(int)rand()%10;

for(j=0;ji;j++)if(k==question[j]){ k=-1;break;}

if(k==-1)continue;question[i]=k;i++;}/*while i*/

for(i=8;i0;i--)/*還有8次機會*/

{ A=0;B=0;printf(“n你還剩下%d次機會。”,i);

printf(“n請輸入四個0-9之間的數字,中間用空格隔開n”);for(j=0;j4;j++)scanf(“%d”,&answer[j]);

for(j=0;j4;j++)

for(k=0;k4;k++)

{ if(answer[j]==question[k]){ if(j==k)A++;else B++;} }/*for*/

if(A==4){ again='0';

printf(“n你贏了,還繼續猜嗎?(y/n)”);

while(again!='y'&&again!='n')

scanf(“...%c”,&again);break;}/*if*/

printf(“n%dA%dB”,A,B);if(i==1){ again='0';

printf(“n你輸了,正確答案是”);

for(j=0;j4;j++)

printf(“%dt”,question[j]);

printf(“n還繼續嗎?(y/n)”);

while(again!='y'&&again!='n')scanf(“%c”,&again);

printf(“%c”,again);break;}/*if*/ }/*for changce*/ }/*while again*/ printf(“感謝您玩這個游戲。”);}

第五篇:C語言經典編程題(推薦)

C語言經典編程題

題目01:在一個已知的字符串中查找最長單詞,假定字符串中只含字母和空格,空格用來分隔不同的單詞。

[cpp] view plain copy print?

1.2.3.4.5.6.7.8.9.int main(){

// 用數組定義一個字符串

char array[50] = “zha junju zhamengjun z mengjun”;

char *str = array;// 定義指針變量str,指向數組array

int len = 0;// 定義變量len,用于計數

int max = 0;// 定義變量max,存放最長單詞的長度

char *p = 0;// 定義指針變量p,指向最長單詞的首字符

10.11.// 判斷指針當前指向的字符是不是'

主站蜘蛛池模板: 偷拍激情视频一区二区三区| 亚洲精品久久久久久久蜜桃臀| 无码h黄动漫在线播放网站| 久久99精品久久久久久| 亚洲精品蜜桃久久久久久| 色欲久久九色一区二区三区| 国产成人精品一区二区视频| 成年女人永久免费观看视频| 亚洲国产成人精品无码区在线播放| 最新在线精品国产福利| 亚洲乱亚洲乱妇无码| 日韩精品射精管理在线观看| 国产成人影院一区二区三区| 无码人妻一区二区三区av| 欧美激情a∨在线视频播放| 高潮潮喷奶水飞溅视频无码| 亚洲国产成人精品女人久久久| 67194熟妇在线观看线路1| 欧美 亚洲 国产 另类| 男人猛戳女人30分钟视频大全| 久久日韩乱码一二三四区别| 亚洲日韩精品无码专区网站| 亚洲AV秘?成人久久无码海归| 久久综合色一综合色88| 少妇午夜福利一区二区| 成人国产精品秘片多多| 国产精品无码专区av在线播放| 一本大道东京热无码一区| 秋霞在线观看片无码免费不卡| 久久久久国产a免费观看rela| 男人的天堂av高清在线| 国产精品美女一区二区视频| 国产白嫩护士被弄高潮| 国内精品久久久久久久999| 国产人妻久久精品二区三区| 尤物蜜芽国产成人精品区| 中文精品一区二区三区四区| 92国产精品午夜福利无毒不卡| 欧洲亚洲色视频综合在线| 亚洲中文字幕琪琪在线| 欧美性大战久久久久久|