2、整洁的代码
程序1-1的三宗罪,分别是:代码冗长、容易出错和重用效果差。当然罗,现在网络上面最流行找茬,别说三宗,n宗都可以找到。其实无论在网络上还是工作中,找茬都不是问题,问题是找到“茬”之后如何解决之。
【程序变】
应该说,程序1-1的“处理代码”段遵循如下规则:
, szBuf+域起始位置);
[长度s=0;s=s+长度;
另外定义一个字符串数组i+1个数据域时,只需将数据拷贝入
处理代码字段可以抽象为:
- //第i次循环
- strncpy(varData[i], szBuf + s, len[i]);
- varData[i][len[i]]=0;
- s = s + len[i];
于是,程序可以通过循环方式化简如下:
- #include <stdio.h>
- #include <stdlib.h>
- #define LEN 7
- int main(int argc, char *argv[])
- {
- char szBuf[]="9559901010008888888木鸿飞 600.00 20110630063001230000测试一次 ";
- char varData[LEN][20];//记载所有数据域的数组
- int len[LEN] = {19, 8, 12, 8, 8, 4, 10};
- int s = 0, i;
- /* 以下为处理代码 */
- for (i=0; i<LEN; i++)
- {
- strncpy(varData[i], szBuf + s, len[i]);
- varData[i][len[i]]=0;
- s += len[i];
- }
- /* 以下为打印代码 */
- for (i=0; i<LEN; i++)
- {
- printf("第%d号域, 【%s】\n", i+1, varData[i]);
- }
- system("PAUSE");
- return 0;
- }
代码1-3
【技巧】
其一、上述程序中使用了宏“#define LEN 7”,利用LEN来代替数字7,这种做法是为了便于程序扩展。假设不使用宏LEN,则代码中必定多次出现数字7(本处为4次),而一旦需求变更,数据域数量增加或是减少,就必须更改代码中的每一次,一旦漏掉了某处,都将给程序代码不可估量的损失。使用宏LEN后,只需一次更改即可。
其二、数字元素本身可以作为数组的下标,比如表达式varData[i][len[i]]中,数组元素len[i]成为了二维数组varData的下标。
【疑问】
需求中要求将各个域数据存入szAccno、szName等数组中,而代码1-3似乎太过于大胆了,居然私自更改需求,将之存储与另外的字符串数组中,如此行为,是可忍熟不可忍。
【编程浪子曰】
用户的需求是可以引导的。
很多时候,用户并不是特别清楚自己的需求,尤其在某些细节方便。比如本处,开发者完全可以引导客户,比如说:“数据域的存储位置无所谓,只要能够拆分出来就可以了。”
【程序又变】
但是,有的时候,有的客户是很执着的,他认定的需求就是不能更改,此时需求再难也必须不折不扣的完成。
再次回到程序的处理核心,如下:
strncpy(域字符串变量, szBuf + s, len[i]);
域字符串变量[len[i]]=0;
s = s + len[i];
其实,前面已经有了成功方案,就是将一群完全不关联的数据域长度集合到一个整型数组中。既然可以集合整数,当然也可以集合“字符串变量”,要知道字符串变量本质上就是指针,那么完全可以将之集合到一个指针数组之中。
【点子】varP,其元素的类型是字符串指针(
大家千万不要一听说“指针数组”就觉得一个头有两个大,其实很简单,就是一个数组,这数组的每个元素都是一个指针,其定义方式如下:
varP[0] = szAccno;
char * varP[LEN] = {szAccno, szName, szAmt, szDate, szLine, szStatus, szBz};
有关指针数组的详细介绍,等到本书“指针与数组”一章中会有详细介绍,这里还是先看程序的改变结果,如下:
- #include <stdio.h>
- #include <stdlib.h>
- #define LEN 7
- 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]; //代表"交易说明"
- char varData[LEN][20];//记载所有数据域的数组
- int len[LEN] = {19, 8, 12, 8, 8, 4, 10};
- char * varP[LEN] = {szAccno, szName, szAmt, szDate, szLine, szStatus, szBz};
- /* 以下为处理代码 */
- int s = 0, i;
- for (i=0; i<LEN; i++)
- {
- strncpy(varP[i], szBuf + s, len[i]);
- (varP[i])[len[i]]=0;
- s += len[i];
- }
- /* 以下为打印代码 */
- for (i=0; i<LEN; i++)
- {
- printf("第%d号域, 【%s】\n", i+1, varP[i]);
- }
- system("PAUSE");
- return 0;
- }
代码1-3
【总结】
数组的妙用之一就在于其能化繁杂为简单,将一系列毫无联系的内容集合在一个数组中,就可以通过循环的方式处理之,从而大大的简化程序代码。
作业3:
上述程序在设计好之后需求发生变更,报文格式变更如下:
字符串第1位~8位代表了“交易日期”; //位置提前
字符串第9位~20位代表了“交易流水号”; //位置提前,长度加长
字符串第21位~39位代表了“账户”;
字符串第40位~47位代表了“姓名”;
字符串第48位~63位代表了“交易金额”; //长度加长
字符串第64位~71位代表了“传票号”; //新增域
字符串第72位~75位代表了“交易状态”;
//取消了“备注”域。
字符串实例和变量情况如下:
- char szBuf[]="201106300630123456789559901010008888888木鸿飞 600.00 999912340000";
- char szAccno[20]; //代表“账户”
- char szName[9]; //代表“姓名”
- char szAmt[17]; //代表“交易金额”
- char szDate[9]; //代表“交易日期”
- char szLine[13]; //代表“交易流水号”
- char szStatus[5]; //代表“交易状态”
- char szBill[9]; //代表“传票”
作业4:
上述程序在设计好之后需求发生变更,运行结果要求打印每号域的域说明,比如:
第1号域,账号,【9559901010008888888】
第2号域,户名,【木鸿飞 】
前一篇 目录 后一篇
PS1:欢迎跟帖,写下自己的作业心得。
PS2:征求名称
本书将讲述数组相关的知识与应用,适用语言:C语言。
描述显示:每次通过一个案例来说明。比如当前为字符串报文解析程序,接下来马上使用音乐演奏程序。
目前考虑的名称有:
(1)数组达人成长之路。
(2)我爱数组
(3)别告诉我你懂数组
(4)数组玩转趣味程序
你觉得那个名称更加吸取眼球,或者你有什么好的建议,欢迎跟帖。
喜欢的同学,请点击“顶”字,可千万别点击“踩”了。