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的评论)

  • 将过于复杂的
    for()
    sheanigans(使用逗号、空段)替换为更简单/更易于阅读的循环

  • 新增文档(功能开始前)

  • 在函数中添加注释

  • 在源代码列表中添加了
    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--;