顯示具有 C語言 標籤的文章。 顯示所有文章
顯示具有 C語言 標籤的文章。 顯示所有文章

2013年6月10日 星期一

[C語言] GOOGLE CODE

最近筆者發現GOOGLE CODE ,應該是一個不錯的程式控管中心。


以後就可以靠著Google code 與大家來分享程式


不然google drive 早晚會有空間不足的危機。


 


這邊有一個簡單的教學。


 


還記得之前有介紹過SVN的文章嗎?


 


測試專案:


 


http://afrodevices.googlecode.com/svn/trunk


 


希望大家玩的愉快。


 


我們以這個專案來說:


https://code.google.com/p/maze-solver/

 


除了擁有Project 的介紹: 還可以下載/wiki/issue 討論,


最後還可以連結到ohloh的資料統計頁面上:


 


 


 


http://www.ohloh.net/p/MicroMouseSim

 


這實在是太強大,且好用了。


2013年5月30日 星期四

[C#] ZedGraph 外掛模組

筆者有時也會寫簡單的人機介面如VB/VC++/VC#,但後來覺得可能會盡量的轉到C#這邊。 其實因為範例C#有愈來愈多的趨勢,所以會以這個為主。 介紹大家一個繪圖上好用的外掛模組, 使用方式可以參考國外網址:How to use ZedGraph, 筆者很多人機介面都是利用這個模組來實現的。


 


以下就是一個未來打算製作一個簡單的示波器所做的人機介面: 敬請期待。


 


 


 





 


2013年5月29日 星期三

[C語言] code review

最近筆者的朋友在分享一篇文章 - 我的code review 經驗談


平常筆者的工作上也不常有code 的review這件事,其實平常的工作就很忙了,真的沒有空做這件事。


不過因為上班常常需要接觸別人寫的code,所以常常可以接觸廠商或是其他人寫的code,所以常常可以比較不同寫法所造成的效果,或是別人寫這些code背後的想法。雖然都是做類似的事,但工作如果可以在其中找到樂趣,其實也比較不會那麼的枯燥乏味。


不過以前筆者的實驗室常常因為要考量到整體演算法的效率,所以常常在檢討如何寫code才會最有效率,雖然那時候可能在已知的範圍內做到效率最高,但有做過這件事,在寫程式的思考模式真的就不太一樣。至少會考慮程式應該怎麼寫才會比較「好」 -  不管是效率就是易閱讀。


 


以前實驗室的boss常常說:優化,也必需知道有多少種方法,當你知道愈多,做的優化才會是極大值。


還是鼓勵大家,多多閱讀別人的專案(程式),多多和別人討論,這絕對是進步的不二法門。


 


希望對大家有幫助。


2013年5月22日 星期三

[STM32F3 教學] (MDK)Keil option 巨集



因為上一篇有在教大家使用多重專案的建構方式。這次要教大家,巨集的使用方式, 當我們把多重專案建立完成後,可以如下圖的設定方式,在option加入一個巨集,這樣我們程式在操作的時候,其實也會滿有彈性的。















      #ifdef PROJECT_UART



      printf("This is UART for
Project\n\r");



      #else



     printf("This
is RS232 for Project\n\r");



      #endif







大家可以比較看看,「rs232」和「uart」這2個專案,所跑的程式為何,當大家學會了一些小技巧後,在維護專案上,應該就可以更得心應手了。



範例程式下載:

https://docs.google.com/file/d/0B2FFxTDyyRQAaVFyQWhhMzZyMTA/edit

2013年5月13日 星期一

[C語言] 工具的準備



通常寫簡單的小程式,用原廠提供 的 IDE tools 就會很好用了, 但當今天要維護大專案或是閱讀別人的程式時,這時候簡單的IDE就顯得不太夠用,或者是不太好用……




 




以筆者為例,大概會準備幾套常用的軟體,大概就可以通殺所有的專案了:




 




一、檔案/檔案夾比對軟體,Beyond Compare: 這是一套用來比較2個檔案或是2個資料夾內,不同之處。 常常我們需要比對此版韌體和上一版韌體有什麼不同,用這個軟體來幫忙,就可以很快的找出差異性了。




 




二、程式編輯軟體,Source Insight: 這是一套非常方便閱讀程式的軟體,他可以自動找出變數/副程式相關的地方,並可以整出結構來,方式編輯與閱讀。




 




三、程式編輯軟體,Ultra Edit: 這是一套強大的文字編輯軟體,有些binary和大量的文字要處理的話,也可以利用此套軟體來幫忙。




 




四、版本控制軟體,Mercurial: 這是一套分散控制的版本控制軟體,如果習慣了SVN(中央控制版本控制軟體),也可以試著改換這一套,筆者我覺得這對小型的專案來說,非常好用。




 




其他推薦軟體:




 




一、              
數學運算軟體,Freemat: 一套相容於matlab的免費軟體,有在使用matlab的可以考慮使用。




二、              
版本控制軟體,GIT: 一套比mercurial 更強大的版本控制,大型的專案就會使用這套軟體。




三、              
IDE軟體,Eclipse: 一套整合非常多功能IDE軟體,很多開發商也慢慢加入Eclipse的行列。




四、              
專案管理軟體,Trello: 一個線上專管管理的軟體。滿適合meeting使用的。




 




如果有什麼也是不錯的軟體的話,也可以推薦給我做參考。





2013年5月11日 星期六

[C語言] 簡單的程式技巧 - 4



        今天碰巧有人分享了一個邪惡C語言寫法,坦白說,做為一個優秀的程式工程師是要讓程式寫得好維護,而非把程式寫得像神一般另人無法抓摸才是,也就是今天就算寫出一個執行效率一百分的程式,但卻沒人看得懂的程式,那也是枉然,所以當今天遇到了執行效率和維護上(好不好懂)的取捨上, 筆者一定盡量的選擇後者,畢竟現在不管是CPU或是MCU的效能都愈來愈好了,有時候損失一點效率換來維護上的彈性和閱讀性,那麼也是值得的。




 




如果有興趣的話,可以參考一下以下的網址:「http://blog.ez2learn.com/2008/09/27/evil-undefined-behavior/」。 最後,這也是告訴大家,把程式寫得屌很帥,事實上反而是另人困擾的,而寫得淺寫易懂的程式,這也是筆者一直在努力研究的方向。



2013年5月10日 星期五

[C語言] 簡單的程式技巧 - 3



        其實做一個寫程式的人,除了自己動手「寫」程式以外,閱讀別人的程式也是常常需要的,所以在閱讀程式之前,如果可以事先知道一些隱藏式的規則的話,這樣在閱讀上是可以達到事半功備的。




        有一派人很喜歡使用匈牙利命名法「http://www.csie.nctu.edu.tw/~skyang/simonyi.zhtw.htm」來取變數名稱:


這樣的命名法是有好處的,就是當今天我們在看變數時,只需要看到他的prefix前綴詞時,你就可以知道這個變數的型態了,但缺點是當你在維護專案時,需要變更一個變數的型態,通常就覺得這個命名規則很麻煩。




 




舉例來說:




 




unsigned char bTest;




 




當我們在看bTest 時,就知道這是一個BYTE的型態了。




 




筆者我不是很喜歡用匈牙利命名法,因為要修改變數時,就會很痛苦了,但有2個prefix前綴詞還滿推薦使用的。




 




m/m_: class/struct 內的member 成員。




g/g_: global變數




 




舉例:




 




int gTest;




 




當我們在看gTest時,就知道這是一個全域式變數了。




 




如果可以了解一些特定的潛規則的話,在閱讀程式上是非常有幫助的。還是老話一句,多聽多看多寫,經驗就會愈來愈老道了。




 




 





2013年5月8日 星期三

[C語言] 簡單的程式技巧 - 2



筆者以前寫程會在沒有規劃好就開始寫了,所以就需要寫很多註解來幫助自己的記憶,當然,沒有寫註解的下場就是每次遇到問題時,就還要再「複習」一次。




舉個例子來說:




 




int test_a, test_b, test_c;




if ( test_a == 1)




{




        test_c
= 1; // go to eat




}




else if ( test_b == 1)




{




        test_c
= 2;       //
go to drink




}




else




{




        test_c
= 0;       //
to do something




}




 




        其實這樣寫並沒有問題,只是說程式寫完後,需要額外的註解,但如果我們在一開始就設定好了有意義的名稱,這樣就可以省下一些註解的說明了。




 




#define BEHAVIOR_TO_DO_SOMETHING     0




#define BEHAVIOR_GO_TO_EAT                    1




#define BEHAVIOR_GO_TO_DRINK                2




 




int Hunger, Thirsty, Behavior;




 




if ( TRUE == Hunger)




{




        Behavior
= BEHAVIOR_GO_TO_EAT;




}




else if ( TRUE == Thirst)




{




        Behavior
= BEHAVIOR_GO_TO_DRINK;




}




else




{




        Behavior
= BEHAVIOR_TO_DO_SOMETHING;




}




 




原則上就是養成習慣,把寫程式當作是在寫作文的話,那麼寫起來的程式就會比較有人性化一點,也不需要寫一大堆的註解,導致整個版面非常的「擁擠」,讓真正的註解,可以一目了然。




 




有人問我,寫程式的技巧如何才會進步,其實這個答案是沒有絕對對與錯的,但方法是有的,就是多看看別人寫的code,對自己總是有幫助的,建議可以去MCU廠所提供的範例程式,好好參透一番,這樣肯定會有收獲的。





2013年5月7日 星期二

[C語言] 簡單的程式技巧



筆者在就學時,讀的是電子工程而不是資訊工程,所以在寫程式上,其實還是和所謂資工系的高手有一段落差,這在上班時,會有很明顯的認知,尤其是在分工清楚的公司,更甚明顯。不過畢竟術業有專攻,大家也別太枉自匪薄,只要多看,注意一些小細節,總是會有機會的。




以寫程式為例,電子工程相關的人的心態是:
可以動就好。而資訊工程講求的是程式的高閱讀性和維護性。所以今天我們要探討的就是如何讓程式保有高閱讀性和維護性。




以下是一個非常簡單的程式,或許compiler 不會過,但只要抓到重點就可以了:




if(test_flag1==1){




        test_data=1;




}




else if(test_flag2==0){




        test_data=2;




}




else{




        test_data=0;




}




 




        以上的程式,盡可能的讓程式碼「擠」在一起,雖然版面可以塞得下較多的程式,但因為都滿擠的,當程式看久了,常常會讓眼精非常的吃力。而且如果不了解數值的內容的話,閱讀上就會很辛苦。大家不仿可以試試看下面的寫法:




 




        #define
TRUE                1




        #dfeine
FALSE              0




 




        #define
FRUIT_APPLE         0




        #define
FRUIT_BANANA    1




        #define
FRUIT_GRAPAS     2




 




        if ( TRUE == test_flag_1)




        {




                test_data
= FRUIT_BANANA;




        }




        else if ( FALSE == test_flag_2)




        {




                test_data
= FRUIT_ GRAPAS;




        }




        else




        {




                test_data
= FRUIT_ APPLE;




        }




 




 




        不知道個位客倌有沒有覺得上面的寫法比較容易閱讀且容易維護,(謎之音: 你虎爛。), 沒關係,
就讓筆者慢慢解說上面的程式有幾件事的差別。




 




 


 





差別1:擠在一起常常會有搞混的情況發生,盡可能的讓程式中間穿插空白,增加閱讀的方便性。






差別2: 盡可能的讓常數使用巨集(#define)的方式,定義一個有意義的名稱。


        這邊要有2個地方值得注意:




(a)常數最好使用大寫的英文,因為這是一個不成文的規定,所以以後你在閱讀別人的程式時,遇到大寫時,第一直覺就可以知道這是「常數」。




(b)相同的巨集,最好前面帶有一個表示相同類型使用到的英文,以避免亂用巨集的情況發生,導致閱讀的混亂(就是呼叫到不該呼叫的巨集)。




差別3,大括號(「{ }」  最好分2行, 因為有專案開發時,常常會遇到需要把判斷式省略或是做測試使用。
舉個簡單舉子:如果我要讓test_data
永遠都只會是” FRUIT_
APPLE”
的話, 那麼這時候我會這樣做:




 




        #if 0




if ( TRUE == test_flag_1)




        {




                test_data
= FRUIT_BANANA;




        }




        else if ( FALSE == test_flag_2)




        {




                test_data
= FRUIT_ GRAPAS;




        }




        else




        #endif




        {




                test_data
= FRUIT_ APPLE;




        }




 




這樣的好處就:




(a)   
非常好加入巨集的維護,而且可以很方便的啟用(enable)與關閉(disable)




(b)  
如果有版本控制軟體的話(SVN/Mercurial/GIT),在比較程式不同時,只會發現多出來的巨集(#if 0/ #endif),這在專案維護上非常重要。




 




差別4: 
判斷式的寫法:




 




        if (
TRUE == test_flag_1)
和 if (test_flag_1 == TRUE)




建議遇到常數時,盡可能的養成常數寫在判斷式的左側,以防止筆誤造成的除錯上的困難。




(a)                 
if (test_flag_1 0 = TRUE)
ç 筆者不小心寫錯,但這樣compiler會過,而且會永遠成立,因為判斷式非0即真。




(b)                 
( TRUE = test_flag_1)
ç 筆者不小心寫錯,但這樣compiler會出現錯誤。因為常數沒有辦法被設定成另一個數值。




 




這個是一個非常重要的小技巧,可以防止筆誤的機率。




 




以上分享給大家知道,並且歡迎大家討論。


 


 


 





感謝沒事才做木工大大的提醒,在寫這篇文章的時候,到是沒有認真思寫這裡的變數使用方式,假設變數都只有TRUE或是FALSE的話,那麼到是可以換個方式寫:





if ( test_flag_1)


        {


                test_data
= FRUIT_BANANA;


        }





        else if ( !test_flag_2)


        {


                test_data
= FRUIT_ GRAPAS;


        }


        else


        {


                test_data
= FRUIT_ APPLE;


        }




其實有時候在寫程式時,也是希望可以讓程式短一點,這樣可以少寫一點或是讓版面可以更精簡一點。








2012年8月15日 星期三

OBJ 陣列 for VC++

之前寫VC++ 都會用很笨的方式在寫, 最近發現,原來是可以用成陣列的方式在寫,


這樣的程式就可以省很多空間了


 


假設我有3個textBox 的OBJ, 那以寫的方式會用


textBox1->Text = "123";


textBox2->Text = "123";


textBox3->Text = "123";


 


如果OBJ多了一點,這樣就只好用EXCEL 來幫助寫程式了。


 


其實,還有更好的方式,用OBJ的ARRAY來寫:


以下是個範例:


 


先宣告一個GLOBAL 變數


           public ref class Form1 : public System::Windows::Forms::Form


           {


           public:


                     static array <System::Windows::Forms::TextBox^>  ^TextBoxArray = gcnew array <System::Windows::Forms::TextBox^>(10);


                     Form1(void)


                     {


                                InitializeComponent();


                                //


                                //TODO: Add the constructor code here


                                //


                     }


           }


 


接著在LOAD FORM時,載入物件


           private: System::Void Form1_Load(System::Object^  sender, System::EventArgs^  e) {


                                           int i;          


                                           TextBoxArray [0] = textBox3;


                                           TextBoxArray [1] = textBox4;


                                           TextBoxArray [2] = textBox5;


 


                                           for (i =0; i<3; i++)


                                           {


                                                     TextBoxArray [i]->Text = "ABC";


                                           }


                                }



最後做一個BUTTON來做測試其他功能


           private: System::Void button1_Click(System::Object^  sender, System::EventArgs^  e) {


                                           int i; 


                                           TextBoxArray [0] = textBox3;


                                           TextBoxArray [1] = textBox4;


                                           TextBoxArray [2] = textBox5;


 


                                           for (i =0; i<3; i++)


                                           {


                                                     TextBoxArray [i]->Text = "kkk";


                                           }


                                }






好棒,這樣程式碼就可以乾淨許多