别告诉我你懂数组(2)

2、整洁的代码

程序1-1的三宗罪,分别是:代码冗长、容易出错和重用效果差。当然罗,现在网络上面最流行找茬,别说三宗,n宗都可以找到。其实无论在网络上还是工作中,找茬都不是问题,问题是找到“茬”之后如何解决之。

【程序变】

应该说,程序1-1的“处理代码”段遵循如下规则:

, szBuf+域起始位置);

[长度s=0s=s+长度;

另外定义一个字符串数组i+1个数据域时,只需将数据拷贝入

处理代码字段可以抽象为:

 
  1. //第i次循环
  2. strncpy(varData[i],szBuf+s,len[i]);
  3. varData[i][len[i]]=0;
  4. s=s+len[i];

于是,程序可以通过循环方式化简如下:

 
  1. #include<stdio.h>
  2. #include<stdlib.h>
  3. #defineLEN7
  4. intmain(intargc,char*argv[])
  5. {
  6. charszBuf[]="9559901010008888888木鸿飞600.0020110630063001230000测试一次";
  7. charvarData[LEN][20];//记载所有数据域的数组
  8. intlen[LEN]={19,8,12,8,8,4,10};
  9. ints=0,i;
  10. /*以下为处理代码*/
  11. for(i=0;i<LEN;i++)
  12. {
  13. strncpy(varData[i],szBuf+s,len[i]);
  14. varData[i][len[i]]=0;
  15. s+=len[i];
  16. }
  17. /*以下为打印代码*/
  18. for(i=0;i<LEN;i++)
  19. {
  20. printf("第%d号域,【%s】\n",i+1,varData[i]);
  21. }
  22. system("PAUSE");
  23. return0;
  24. }

代码1-3

【技巧】

其一、上述程序中使用了宏“#define LEN 7”,利用LEN来代替数字7,这种做法是为了便于程序扩展。假设不使用宏LEN,则代码中必定多次出现数字7(本处为4次),而一旦需求变更,数据域数量增加或是减少,就必须更改代码中的每一次,一旦漏掉了某处,都将给程序代码不可估量的损失。使用宏LEN后,只需一次更改即可。

其二、数字元素本身可以作为数组的下标,比如表达式varData[i][len[i]]中,数组元素len[i]成为了二维数组varData的下标。

【疑问】

需求中要求将各个域数据存入szAccnoszName等数组中,而代码13似乎太过于大胆了,居然私自更改需求,将之存储与另外的字符串数组中,如此行为,是可忍熟不可忍。

【编程浪子曰】

用户的需求是可以引导的。

很多时候,用户并不是特别清楚自己的需求,尤其在某些细节方便。比如本处,开发者完全可以引导客户,比如说:“数据域的存储位置无所谓,只要能够拆分出来就可以了。”

【程序又变】

但是,有的时候,有的客户是很执着的,他认定的需求就是不能更改,此时需求再难也必须不折不扣的完成。

再次回到程序的处理核心,如下:

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};

有关指针数组的详细介绍,等到本书“指针与数组”一章中会有详细介绍,这里还是先看程序的改变结果,如下:

 
  1. #include<stdio.h>
  2. #include<stdlib.h>
  3. #defineLEN7
  4. intmain(intargc,char*argv[])
  5. {
  6. charszBuf[]="9559901010008888888木鸿飞600.0020110630063001230000测试一次";
  7. charszAccno[20];//代表"账户"
  8. charszName[9];//代表"姓名"
  9. charszAmt[13];//代表"交易金额"
  10. charszDate[9];//代表"交易日期"
  11. charszLine[9];//代表"交易流水号"
  12. charszStatus[5];//代表"交易状态"
  13. charszBz[11];//代表"交易说明"
  14. charvarData[LEN][20];//记载所有数据域的数组
  15. intlen[LEN]={19,8,12,8,8,4,10};
  16. char*varP[LEN]={szAccno,szName,szAmt,szDate,szLine,szStatus,szBz};
  17. /*以下为处理代码*/
  18. ints=0,i;
  19. for(i=0;i<LEN;i++)
  20. {
  21. strncpy(varP[i],szBuf+s,len[i]);
  22. (varP[i])[len[i]]=0;
  23. s+=len[i];
  24. }
  25. /*以下为打印代码*/
  26. for(i=0;i<LEN;i++)
  27. {
  28. printf("第%d号域,【%s】\n",i+1,varP[i]);
  29. }
  30. system("PAUSE");
  31. return0;
  32. }

代码1-3

【总结】

数组的妙用之一就在于其能化繁杂为简单,将一系列毫无联系的内容集合在一个数组中,就可以通过循环的方式处理之,从而大大的简化程序代码。

作业3

上述程序在设计好之后需求发生变更,报文格式变更如下:

字符串第1位~8位代表了“交易日期”;//位置提前

字符串第9位~20位代表了“交易流水号”;//位置提前,长度加长

字符串第21位~39位代表了“账户”;

字符串第40位~47位代表了“姓名”;

字符串第48位~63位代表了“交易金额”;//长度加长

字符串第64位~71位代表了“传票号//新增域

字符串第72位~75位代表了“交易状态”;

//取消了“备注”域。

字符串实例和变量情况如下:

 
  1. charszBuf[]="201106300630123456789559901010008888888木鸿飞600.00999912340000";
  2. charszAccno[20];//代表“账户”
  3. charszName[9];//代表“姓名”
  4. charszAmt[17];//代表“交易金额”
  5. charszDate[9];//代表“交易日期”
  6. charszLine[13];//代表“交易流水号”
  7. charszStatus[5];//代表“交易状态”
  8. charszBill[9];//代表“传票”

作业4

上述程序在设计好之后需求发生变更,运行结果要求打印每号域的域说明,比如:

1号域,账号,【9559901010008888888

2号域,户名,【木鸿飞】

前一篇 目录 后一篇

PS1:欢迎跟帖,写下自己的作业心得。

PS2:征求名称

本书将讲述数组相关的知识与应用,适用语言:C语言。

描述显示:每次通过一个案例来说明。比如当前为字符串报文解析程序,接下来马上使用音乐演奏程序。

目前考虑的名称有:

(1)数组达人成长之路。

(2)我爱数组

(3)别告诉我你懂数组

(4)数组玩转趣味程序

你觉得那个名称更加吸取眼球,或者你有什么好的建议,欢迎跟帖。

喜欢的同学,请点击“顶”字,可千万别点击“踩”了。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值