程式員最希望什麼,當然是用最少的代碼,實作最多的功能,用簡單的代碼,實作最複雜的功能。換句話說就是又要馬兒跑,又不給馬兒吃草。隻是,這可能嗎?在這個世界中,總是一分耕耘,一分收獲,一份代碼,一份功能,有哪種簡單迅速而又全面的東西嗎。
有!這個東西就是數組,隻要條件滿足,使用數組可以優化代碼,簡化程式設計,減少錯誤,真不愧是程式設計偷懶,靈活開發的必備良藥!
計算機語言如雨後春筍般層出不窮,互相之間暗戰不止!老牌語言牢牢占據排名榜前三,新的語言也在排名榜上突飛猛進。
不同的語言之間,總是或多或少存在着差異,是以開發者們眼花缭亂,不知道選擇何種語言為好。
但是,如果能夠突破語言的迷霧,大家會發現,雖然不同的語言存在着差別,但是也有着一些共同的東西,數組恰恰就是其中之一。
數組是一個掩藏個性的地方。本來作為一個變量,能夠擁有自己的名字是一件比較風光的事情,無論這個名字是一個字母還是若幹單詞,總之給了開發者記住自己的機會。
不過可惜,有的變量沒有獨立的名字,若幹變量合在一起,共同使用一個名字,這就是數組。
單個變量描述方式:int amt, accno, accdate, reqdate;
數組描述方式:int a[4]
對于數組中的變量而言,獨立擁有姓名是一個奢望,稱職他們的方式就是“在共同的變量名稱後面加上編号”,正如 “9527是他永久的編号”一樣,唐伯虎入華府後的稱呼就是“華府家丁[9527]”。
為什麼要引入數組?這種撲滅個性的作法難道值得推廣嗎?使用具備個性的變量名稱的代碼應該更加容易閱讀了解才對。比較如下兩段代碼:
strcmp(szAmt, “100.00”);
strcmp(szAccno, “955990109000000”);
strcmp(accdate, “20110630”);
strcmp(reqdate, “20110629”);
代碼1-1
strcmp(szBuf[0], “100.00”);
strcmp(szBuf[1], “955990109000000”);
strcmp(szBuf[2], “20110630”);
strcmp(szBuf[3], “20110629”);
代碼1-2
顯然,代碼1-1更加容易了解,大家可以猜測出,變量szAmt是金額,szAccno是賬戶,accdate和reqdate都是日期。但若使用代碼1-2,曆時久遠之後,szBuf的含義可能也會随着時間的推移而逐漸被淡忘,意圖再次看懂代碼,或者看懂别人的代碼,就必須經過一番寒徹骨才行。
既然如此,為什麼還要産生“數組”這個東東,而且是很多語言中都使用了數組這個東東呢?那是因為,數組不适合這種張揚個性的環境,它使用共性來掩蓋個性,展現的是“團結就是力量”,“兄弟齊心,其力斷金”。
<b>作業1:</b>
<b></b>
(1)已知某銀行某項目中使用了字元串szBuf記載交易封包資訊,封包使用定長格式,分别記載了各個交易資料域,如下所示:
字元串第1位~19位代表了“賬戶”;長度19。
字元串第20位~27位代表了“姓名”;長度8。
字元串第28位~39位代表了“交易金額”;長度12。
字元串第40位~47位代表了“交易日期”;長度8。
字元串第48位~55位代表了“交易流水号”;長度8。
字元串第56位~59位代表了“交易狀态”;長度4。
字元串第60位~69位代表了“交易說明”;長度10。
程式要求将szBuf中的各個資料域拆分并分别存入其對應的變量中,對應關系如下所示:
char szAccno[20]; //代表“賬戶”
char szName[9]; //代表“姓名”
char szAmt[13]; //代表“交易金額”
char szDate[9]; //代表“交易日期”
char szLine[9]; //代表“交易流水号”
char szStatus[5]; //代表“交易狀态”
char szBz[11]; //代表“交易說明”
請設計程式實作之,并在螢幕上每一行分别一各資料域以及該域的序号,為了并于觀察,可用“【】”包含域資料。
比如字元串:
szBuf[]="9559901010008888888木鴻飛 600.00 20110630063001230000測試一次 ";
則拆分後存入結果如下表所示:
變量
含義
内容(為表明效果,特增加“【】”,另外符号“_”代表空格)
szAccno
賬戶
【9559901010008888888】
szName
姓名
【木鴻飛__】
szAmt
交易金額
【600.00______】
szDate
交易日期
【20110630】
szLine
交易流水号
【06300123】
szStatus
交易狀态
【0000】
szBz
交易說明
【測試一次__】
程式運作結果應該如下:
第1号域, 【9559901010008888888】
第2号域, 【木鴻飛 】
第3号域, 【600.00 】
第4号域, 【20110630】
第5号域, 【06300123】
第6号域, 【0000】
第7号域, 【測試一次 】
(2)在程式設計好之後需求發生變更,封包格式變更如下:
字元串第1位~8位代表了“交易日期”; //位置提前
字元串第9位~20位代表了“交易流水号”; //位置提前,長度加長
字元串第21位~39位代表了“賬戶”;
字元串第40位~47位代表了“姓名”;
字元串第48位~63位代表了“交易金額”; //長度加長
字元串第64位~71位代表了“傳票号”; //新增域
字元串第72位~75位代表了“交易狀态”;
//取消了“備注”域。
字元串執行個體和變量情況如下:
char szBuf[]="201106300630123456789559901010008888888木鴻飛 600.00 999912340000";
char szAmt[17]; //代表“交易金額”
char szLine[13]; //代表“交易流水号”
char szBill[9]; //代表“傳票”
<b>程式1-1:</b>
【特别提示】在查閱程式前,請各位讀者務必獨立思考并且完成上述試題,然後再來閱讀程式。
首先使用函數strncpy分别複制資料,然後分别在每個字元串後面增加結束符0,最後再分别顯示出來即可,程式代碼如下所示:
#include <stdio.h>
#include <stdlib.h>
int main(int argc, char *argv[])
{
char szBuf[]="9559901010008888888木鴻飛 600.00 20110630063001230000測試一次 ";
char szAccno[20]; //代表"賬戶"
char szName[9]; //代表"姓名"
char szAmt[13]; //代表"交易金額"
char szDate[9]; //代表"交易日期"
char szLine[9]; //代表"交易流水号"
char szStatus[5]; //代表"交易狀态"
char szBz[11]; //代表"交易說明"
/* 以下為處理代碼 */
strncpy(szAccno, szBuf, 19);
szAccno[19]=0;
strncpy(szName, szBuf+19, 8);
szName[8]=0;
strncpy(szAmt, szBuf+27, 12);
szAmt[12]=0;
strncpy(szDate, szBuf+39, 8);
szDate[8]=0;
strncpy(szLine, szBuf+47, 8);
szLine[8]=0;
strncpy(szStatus, szBuf+55, 4);
szStatus[4]=0;
strncpy(szBz, szBuf+59, 10);
szBz[10]=0;
/* 以下為列印代碼 */
printf("第1号域, 【%s】\n", szAccno);
printf("第2号域, 【%s】\n", szName);
printf("第3号域, 【%s】\n", szAmt);
printf("第4号域, 【%s】\n", szDate);
printf("第5号域, 【%s】\n", szLine);
printf("第6号域, 【%s】\n", szStatus);
printf("第7号域, 【%s】\n", szBz);
system("PAUSE");
return 0;
}
【程式說明】以下代碼在Windows XP 加Dev C++下編譯通過,如果在DOS或Unix/Linux下設計,可以取消“system("PAUSE");”一行。
【特别提示】如果你在之前沒有獨立設計程式,而是直接看到這裡,請将上述代碼輸入電腦,調試通過後再接着閱讀。
【程式分析】
上述程式中存在三宗罪。
第一宗罪:代碼冗長。
其實很無奈,上述程式代碼太不整潔,疑式重複代碼太多。以“處理代碼”部分為例,其實大部分代碼遵循如下規則:
strncpy(字元串變量, szBuf+起始位置, 長度);
szBz[長度]=0;
乍一看很可以使用循環方式來解決,但其實不然,因為每一個“字元串變量”、“起始位置”和“長度”就是不一樣,就是不能整合到循環之中。
同理“列印代碼”部分也是一樣,想整合而不能。
第二宗罪:容易出錯。
在上述代碼中,每個資料域的起始位置都是在計算之後顯示的寫入代碼中,如果某一個地方出現失誤,則将導緻後續一連串的錯誤。
比如下述代碼:
strncpy(szName, szBuf+19, 8);
szName[8]=0;
strncpy(szAmt, szBuf+27, 12);
其中szAmt的“起始位置”為szName的“起始位置+長度”,以後的都是前一個“起始位置+長度”,這個過程需要手工完成,倘若計算錯誤或者輸入錯誤,則可能引起後續一系列的錯誤。
第三宗罪:代碼重用效果差。
按照題設的需求,封包格式會發生變化,此時需要更改全部的“處理代碼”部分,程式的重用性能太差了。
<b>作業2:</b>
更改代碼1-1,使之捷徑、可重用,不易出錯。
本文轉自 zhuyunxiang 51CTO部落格,原文連結:http://blog.51cto.com/zhuyunxiang/600261,如需轉載請自行聯系原作者