帮朋友分析程序--新手看看
查看(1146) 回复(0) |
|
lyh2006
|
发表于 2010-08-18 19:34
楼主
考研之路已结束,闲得无聊,正好一个今年跨考的朋友叫我帮他看看写的代码为什么运行不了,就分析了一下,
发现了一些常见的问题,这正是不会写代码的新人常见的问题,于是就发上来了.新手可以看看,高手就不用看笑话了. 如果发现自己动力能力很差的同学,也可以看看,从中找找启发. 部分代码: 复制内容到剪贴板 代码: #define maxsize 50 typedef int type; typedef struct { type elem[maxsize]; int length; }sqlist; void initlist(sqlist *l) { l=(sqlist *)malloc(sizeof(sqlist)); l->length=0; } int listinsert(sqlist *&l,int i,type e) { int j; if(i<1||i>l->length+1) return 0; i--; for(j=l->length;j>i;j--) l->elem[j]=l->elem[j-1]; l->elem=e; l->length++; return 1; } ...... main() { sqlist *l; type x; initlist(l); listinsert(l,1,1); listinsert(l,2,2); ...... 1.这个sqlist跟本没有价值. 明显作者意图是写一个链表.但链表的特点是什么?是方便插入删除运算,大小易扩充. 而这里用的静态数组实现,还define了maxsize,而insert中也没有重分配空间的意图.链表的特点在这里完全没有体现出来. 插入删除需要大量元素移动,malloc一个固定大小出来,大了是浪费,小了就没用了. 这些是学习数据结构是要理解的基础东西.每一种数据结构存在的优缺点一定要弄清楚. 2.代码风格 看这种风格就知道又是严奶奶"类C"的受害者.特别是把C++的引用搞到C上面,害了多少初学者. 对于C,可以看到很多代码都是直接把结点指针就定义成链表类型了. #define list node* 而对于C++,则采用类,类中封装头结点(指针),可能还会封装length,在构造函数中初始化. class list { node* head; int length; }; 这些东西混用之后就有点四不像的感觉了.特别是现在看sqlist *&l 这样的东西觉得特别扭(虽然一年前我也写这种句子). 按C的习惯,可以选择用指针实现引用的功能.C代码中是没有引用的.但可以用sqlist **l 呀. 其实这里 initlist按C风格来做,可以用个宏来写,还更美观些而且不会出现弄不清引用,参数传递等容易犯的错误. 复制内容到剪贴板 代码: #define INITLIST(l) do{ l=(sqlist *)malloc(sizeof(sqlist)); l->length=0;}while(0) 如果看过linux内核的代码,就会发现很多地方都用这类的宏.反正感觉是比类C看起来地道. 3.函数参数传递 这是新手最容易出的问题.我拿到代码就编译,运行后内存错误.然后就发现initlist没能正确地完全任务 再看发现 void initlist(sqlist *l) 这里,l传值进去后的修改是不会返回到实参的,新手在这些地方很容易出错. C语言的基础一定要学扎实.这里可以改一改,比如以引用方式传void initlist(sqlist * &l).或者我上面也写了,用宏实现就没有传参的问题. 而后面那个listinsert不必用传引用的方式,因为在函数内部修改的不是sqlist指针而是其指向的空间.这里可以看出来我这位朋友对函数参数传递还是没理解透. 希望对这个还不熟的朋友们都回顾一下. 4.文件包含问题 朋友把代码发给我的时候乱七八糟的,上面已经是整理过后的片断了.原始的上面还好多extern...函数定义和声明都放的.cpp,还把cpp文件都include进去... 文件包含其实说简单很简单,说深很深.反正记住是声明放在头文件,实现放在cpp文件中. 以上是不会写代码的人要克服的基本问题.只是一个简单的分析. 当然我朋友跨考的,确实这些地方还很不足.其实去年我也是这种样子,嘿嘿. 各位研友可以看看自己存在哪些类似的问题并引起注意.动手能力也是慢慢练上来的.多动手就容易了. 最后祝11的研友好运~ |
回复话题 |
||
上传/修改头像 |
|
|