2010年5月20日 星期四

關於程式優化的問題

這是昨天在教學弟的程式


我覺得挺有趣的


為了怕我忘了,所以記錄一下


以往我們的學習都是從範例開始


反正可以動就不管程式的寫法了


不過因為找工作的時候被電過


所以


一個好的程式設計者應該是要會試著如何把程式優化。


 


以下是幾種不同程式的寫法,一樣都是把數值轉換成ASCII code,有興趣的人,可以把程式拿回家compiler,執行看看不同的結果與差異性,這邊就不再介紹,給大家一點功課嘛


 


以下是使用MPLAB IDE,compiler 是使用 C30 V3.10


/*******************************************************************************
曾百由
dsPIC數位訊號控制器原理與應用-第一版
P12-18
宏友圖書
範例程式
*******************************************************************************/

void num2ascii (unsigned int Number,char *buff)
{
 unsigned int The_number_10000,The_number_1000,The_number_100,The_number_10,The_number ;
 char *temp = (char *)buff ;


 The_number_10000 = Number / 10000 ;
 temp[0] = The_number_10000 + 48 ;


 The_number_1000 = (Number - ( The_number_10000 * 10000 ) )/ 1000 ;
 temp[1] = The_number_1000 + 48 ;


 The_number_100 = (Number - ( The_number_10000 * 10000 + The_number_1000 * 1000 ) )/ 100 ;
 temp[2] = The_number_100 + 48 ;


 The_number_10 = (Number - ( The_number_10000 * 10000 + The_number_1000 * 1000 + The_number_100 * 100 )) / 10 ; 
 temp[3] = The_number_10 + 48 ;


 The_number = Number - ( The_number_10000 * 10000 + The_number_1000 * 1000 + The_number_100 * 100 + The_number_10 * 10 ) ;
 temp[4] = The_number + 48 ; 
}


 /*******************************************************************************
利用陣列的方式做處理
*******************************************************************************/

void num2ascii_2 (unsigned int Number,char *temp)
{
 temp[0] = (Number / 10000) + 48 ;
 temp[1] = (( Number % 10000 ) / 1000) + 48 ;
 temp[2] = (( Number % 1000 ) / 100) + 48 ;
 temp[3] = (( Number % 100 ) / 10) + 48 ;
 temp[4] = (Number % 10) + 48 ;
}
 /*******************************************************************************
利用指標的方式做處理
*******************************************************************************/

void num2ascii_3 (unsigned int Number,char *temp)
{
 *temp++ = (Number / 10000) + 48 ;
 *temp++ = (( Number % 10000 ) / 1000) + 48 ;
 *temp++ = (( Number % 1000 ) / 100) + 48 ;
 *temp++ = (( Number % 100 ) / 10) + 48 ;
 *temp   = (Number % 10) + 48 ;
}
 /*******************************************************************************
利用指標的方式做處理,並加入判斷式
*******************************************************************************/

void num2ascii_4 (unsigned int Number,char *temp)
{
 if(Number<10000) *temp++ =' ';
 else *temp++ = (Number / 10000) + 48 ;


 if(Number<1000) *temp++ =' ';
 else *temp++ = (( Number % 10000 ) / 1000) + 48 ;


 if(Number<100) *temp++ = ' ';
 else *temp++ = (( Number % 1000 ) / 100) + 48 ;


 if(Number<10)*temp++ = ' ';
 else *temp++ = (( Number % 100 ) / 10) + 48 ;


 *temp   = (Number % 10) + 48 ;
}


 /*******************************************************************************
主程式
******************************************************************************/

int main(void){
 char TXdata[6];
 unsigned int data;


 data=12345;
 num2ascii (data,TXdata);


 data=23456;
 num2ascii_2 (data,TXdata);
 
 data=34567;
 num2ascii_3 (data,TXdata);
 
 data=45678;
 num2ascii_4 (data,TXdata); 



 data=6;
 num2ascii_4 (data,TXdata); 


 return 0;
}


 


 


不知道是否還有其他更好的寫法?目前看起來num2ascii_4 這支副程式應該比較理想。


4 則留言:

  1.                     while (_uquad >= 10) {
                            *--cp = to_char(_uquad % 10);
                            _uquad /= 10;
                        }
                        *--cp = to_char(_uquad);
    這是從NewLib的程式碼。
    Gnu的newlib有很多不錯的程式。

    [版主回覆05/22/2010 01:48:52]那裡有介紹比較完整的NewLib的資訊,這個lib好像挺有趣的,我最近也是在學習如何將程式寫得比較簡單易懂。
    謝謝

    回覆刪除
  2. 真正的優化
    效能跟可讀性一樣重要!!
     
    沒有人可以follow的程式
    就算再有效率都會過時.....
    這是老前輩給我的經驗
    也提供您參考唷~~~
    [版主回覆05/24/2010 19:26:50]謝謝您,我現在只是練習,相同的題目,如何利用不同的方式實現,而實現的方式是最佳且理想的。
    以前寫程式只寫功能正常就好,現在要練習的是,如何聰明的寫程式

    回覆刪除
  3. 提供一個我認為有趣不見得徹底完成的方法,只是無聊的想要指標副程式結合遞回呼叫,目的只是想弄得很怪,應該還有修正的地方畢竟我覺得不完美也想盡力去改進它
    char *itoA2(char*p,int num)
    {
         if(num<10)*(p)=num+0x30;
         else *(p=itoA2(p,num/10))=num%10+0x30;
         *(++p)=0;
         return p;
    }

    回覆刪除
  4. 上一篇有錯刪掉吧
    char *itoA3(char*p,int num)
    {
         *(p=((num<10)?p:itoA3(p,num/10)))=num%10+0x30;  
         *(++p)=0;
         return p;
    }

    回覆刪除