C 我的老师告诉我我的代码是垃圾代码,为什么?
这两种算法之间有很大区别吗 这是我的:C 我的老师告诉我我的代码是垃圾代码,为什么?,c,C,这两种算法之间有很大区别吗 这是我的: void MergeList(sqList la,sqList lb,sqList *lc){ int j,k,n=0; for (j = la.length - 1, k = lb.length - 1; j >= 0 && k >= 0; ){ if (*(la.elem + j) > *(lb.elem + k)){ *(lc->elem + n) = *(la.elem + j)
void MergeList(sqList la,sqList lb,sqList *lc){
int j,k,n=0;
for (j = la.length - 1, k = lb.length - 1; j >= 0 && k >= 0; ){
if (*(la.elem + j) > *(lb.elem + k)){
*(lc->elem + n) = *(la.elem + j);
j--;
} else if(*(la.elem + j) < *(lb.elem + k)){
*(lc->elem + n) = *(la.elem + k);
k--;
} else {
*(lc->elem + n) = *(la.elem + j);
j--;
k--;
}
n++;
lc->length++;
}
for ( ;j >= 0; j--){
*(lc->elem + n) = *(la.elem + j);
lc->length++;
}
for ( ;k >= 0; k--){
*(lc->elem + n) = *(lb.elem + k);
lc->length++;
}
}
void合并列表(sqList la、sqList lb、sqList*lc){
int j,k,n=0;
对于(j=la.length-1,k=lb.length-1;j>=0&&k>=0;){
如果(*(la.elem+j)>*(lb.elem+k)){
*(lc->elem+n)=*(la.elem+j);
j--;
}否则(*(la.elem+j)<*(lb.elem+k)){
*(lc->elem+n)=*(la.elem+k);
k--;
}否则{
*(lc->elem+n)=*(la.elem+j);
j--;
k--;
}
n++;
lc->length++;
}
对于(;j>=0;j--){
*(lc->elem+n)=*(la.elem+j);
lc->length++;
}
对于(;k>=0;k--){
*(lc->elem+n)=*(lb.elem+k);
lc->length++;
}
}
这是书上的
void MergeList(sqList la,sqList lb,sqList *lc){
ElemType *pa,*pb,*pc,*pa_first,*pb_first;
pa = la.elem + la.length - 1;
pb = lb.elem + lb.length - 1;
pc = lc->elem;
pa_first = la.elem;
pb_first = lb.elem;
while(pa >= pa_first && pb >= pb_first){
if(*pa > *pb)
*pc++ = *pa--;
else if(*pa < *pb)
*pc++ = *pb--;
else{
*pc++ = *pa-- = *pb--;
}
lc->length++;
}
while(pa >= pa_first)
*pc++ = *pa--;
while(pb >= pb_first)
*pc++ = *pb--;
}
void合并列表(sqList la、sqList lb、sqList*lc){
元素类型*pa、*pb、*pc、*pa_优先、*pb_优先;
pa=la.elem+la.length-1;
pb=磅元素+磅长度-1;
pc=lc->elem;
pa_first=la.elem;
pb_first=lb.elem;
而(pa>=pa_优先&&pb>=pb_优先){
如果(*pa>*pb)
*pc++=*pa--;
否则,如果(*pa<*pb)
*pc++=*pb--;
否则{
*pc++=*pa--=*pb--;
}
lc->length++;
}
while(pa>=pa_优先)
*pc++=*pa--;
而(pb>=pb_优先)
*pc++=*pb--;
}
我的重构
所作的修改:
- 使
返回列表,这样调用者就可以执行类似MergeList
的操作,使其更加明显地显示所影响的内容resultList=MergeList(…
- 更改了变量名,使其更具描述性
- 到处都添加了“左大括号前的空格”
- 到处都添加了“逗号后空格”
- 到处都增加了“操作员周围的空间”
- 用数组查找替换指针计算(参见Jeremy Friesner的评论)
- 将过于复杂的
sheanigans(使用逗号、空段)替换为更简单/更易于阅读的循环for()
- 新增文档(功能开始前)
- 在函数中添加注释
- 在源代码列表中添加了
const
//通过合并来自的数据,按照“elem”的降序顺序构建一个新列表
//已按“elem”降序排序的两个现有列表。
//
//警告:
//如果两个源列表都未排序,则结果列表将不会排序。
//调用方必须确保在调用此函数之前为结果列表分配了足够的内存。
sqList*合并列表(常量sqList列表a、常量sqList列表b、sqList*结果列表){
int j,k,n=0;
//执行两个源列表中的条目,直到至少一个源列表中没有任何内容
j=列表长度-1;
k=列表长度-1;
而(j>=0&&k>=0){
if(列表元素[j]>列表元素[k]){
结果列表->元素[n]=列表元素[j];
j--;
}else if(list_a.elem[j]元素[n]=列表元素[k];
k--;
}否则{
结果列表->元素[n]=列表元素[j];
j--;
k--;
}
n++;
结果列表->长度++;
}
//如果列表_a中的所有条目都未被使用,请将其余条目复制到结果列表中
而(j>=0){
结果列表->元素[n]=列表元素[j];
结果列表->长度++;
j--;
}
//如果列表_b中的所有条目都未被消耗,则将其余条目复制到结果列表中
而(k>=0){
结果列表->元素[n]=列表元素[k];
结果列表->长度++;
k--;
}
返回结果列表;
}
这两种算法之间有很大区别吗
他们做的不一样,所以是的,有很大的不同
您的代码有一个bug,我想这是一个典型的复制粘贴错误。这一行是错误的:
} else if(*(la.elem + j) < *(lb.elem + k)){
*(lc->elem + n) = *(la.elem + k); // ERROR... la.elem should be lb.elem
k--;
} else {
代码中没有增量
for ( ;j >= 0; j--){
*(lc->elem + n) = *(la.elem + j);
lc->length++;
}
是的。所以又有了区别。我想这本书是错的,而你是对的
书中的代码递减指针,并将其与指向第一个元素的指针进行比较。由于递减的指针将指向第一个元素之前,因此代码具有未定义的行为
我的老师告诉我我的代码是垃圾代码,为什么
老师不应该这么说……老师至少应该解释一下原因
在评估代码时,可以关注以下几点:
- 功能,即它是否在做应该做的事情-这是最高优先级
- 性能,即代码是否以您需要的速度执行
- 可维护性,即代码易于阅读、理解和维护
*(la.elem + j) --> la.elem[j]
还请注意,本书中的代码不容易阅读。请看本书中的这一行:
while(pa >= pa_first)
*pc++ = *pa--;
*pc++ = *pa-- = *pb--;
作为代码的读者,我们只能想:“这段代码应该做什么?”这缺少很多上下文。我们需要一个能够进行更多注释的循环。需要注意的一点是,您的变量名称不透明得令人恼火。与其说
j
,这意味着什么,不如给它们命名一些暗示它们所做的事情,或者将它们限定在for
循环的范围内,以便它们的实用程序易于理解。什么是sqList代码>?我们如何测试此代码?第一个问题:您的程序的输出与本书中的输出相同?您可以通过将eg*(la.elem+k)
的所有实例替换为la.elem[k]来简化语法
这本书是错误的,不要相信它。他们向后遍历数组的方式有未定义的行为。你的代码是错误的(在最后两个循环中n被改变了?)他们的代码也是错误的(不要改变lc->length)。写lc->elem[n]
而不是*(lc->elem+n)
等等。我认为它们都是因为缺少元素而坏的
*pc++ = *pa-- = *pb--;