别告诉我你懂数组(2)

时间:2022-12-28 10:31:19

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.  
  4. #define LEN 7  
  5. int main(int argc, char *argv[])  
  6. {  
  7.     char szBuf[]="9559901010008888888木鸿飞  600.00      20110630063001230000测试一次  ";  
  8.     char varData[LEN][20];//记载所有数据域的数组   
  9.     int len[LEN] = {19, 8, 12, 8, 8, 4, 10};  
  10.     int s = 0, i;  
  11.  
  12.     /* 以下为处理代码 */   
  13.     for (i=0; i<LEN; i++)  
  14.     {  
  15.         strncpy(varData[i], szBuf + s, len[i]);  
  16.         varData[i][len[i]]=0;  
  17.         s += len[i];  
  18.     }      
  19.          /* 以下为打印代码 */ 
  20.     for (i=0; i<LEN; i++)  
  21.     {  
  22.         printf("第%d号域, 【%s】\n",  i+1, varData[i]);  
  23.     }      
  24.     system("PAUSE");    
  25.     return 0;  
  26. }  
  27.  

代码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.  
  4. #define LEN 7  
  5. int main(int argc, char *argv[])  
  6. {  
  7.     char szBuf[]="9559901010008888888木鸿飞  600.00      20110630063001230000测试一次  ";  
  8.     char szAccno[20]; //代表"账户"  
  9.     char szName[9];      //代表"姓名"  
  10.     char szAmt[13];      //代表"交易金额"  
  11.     char szDate[9];      //代表"交易日期"  
  12.     char szLine[9];      //代表"交易流水号"  
  13.     char szStatus[5]; //代表"交易状态"  
  14.     char szBz[11];       //代表"交易说明"  
  15.     char varData[LEN][20];//记载所有数据域的数组   
  16.     int len[LEN] = {19, 8, 12, 8, 8, 4, 10};  
  17.     char * varP[LEN] = {szAccno, szName, szAmt, szDate, szLine, szStatus, szBz};  
  18.     /* 以下为处理代码 */   
  19.     int s = 0, i;  
  20.     for (i=0; i<LEN; i++)  
  21.     {  
  22.         strncpy(varP[i], szBuf + s, len[i]);  
  23.         (varP[i])[len[i]]=0;  
  24.         s += len[i];  
  25.     }      
  26.     /* 以下为打印代码 */ 
  27.     for (i=0; i<LEN; i++)  
  28.     {  
  29.         printf("第%d号域, 【%s】\n",  i+1, varP[i]);  
  30.     }      
  31.  
  32.     system("PAUSE");    
  33.     return 0;  
  34. }  
  35.  

 

代码1-3

【总结】

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

作业3

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

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

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

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

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

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

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

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

//取消了“备注”域。

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

 

 
 
  1. char szBuf[]="201106300630123456789559901010008888888木鸿飞  600.00          999912340000";  
  2. char szAccno[20];          //代表“账户”  
  3. char szName[9];          //代表“姓名”  
  4. char szAmt[17];           //代表“交易金额”  
  5. char szDate[9];            //代表“交易日期”  
  6. char szLine[13];          //代表“交易流水号”  
  7. char szStatus[5];         //代表“交易状态”  
  8. char szBill[9];           //代表“传票” 

作业4

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

1号域,账号,【9559901010008888888

2号域,户名,【木鸿飞 

 前一篇   目录   后一篇

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

PS2:征求名称

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

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

目前考虑的名称有:

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

(2)我爱数组

(3)别告诉我你懂数组

(4)数组玩转趣味程序

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

 

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