C语言 如何更有效地修复此while循环?[已关闭]

ix0qys7i  于 2023-03-01  发布在  其他
关注(0)|答案(2)|浏览(161)

编辑问题以包含desired behavior, a specific problem or error, and the shortest code necessary to reproduce the problem。这将有助于其他人回答问题。
5小时前关门了。
Improve this question
此循环工作正常

y = pop(stk2, &top2);
while(y != -1) {
   /* ... and at the end */
   y = pop(stk2, &top2);
}

但我不喜欢重复pop呼叫。我已经尝试过了

while(y = pop(stk2, &top2) != -1)

还有这个

while((y = pop(stk2, &top2)) != -1)

但都不管用。

f5emj3cl

f5emj3cl1#

根据您的问题,您似乎希望在中断while循环之前执行y = pop(stk2, &top2);的代码语句,这可以使用do-while循环来完成。
do-while可以帮助您在检查条件之前至少执行一次代码语句。如果满足条件,循环将退出。
您的代码可以按以下方式组织:

do{
    /* ... and at the end */
    y = pop(stk2, &top2);
}while(y != -1)
jhdbpxl9

jhdbpxl92#

"I don't like"不是任何事情的理由。首先,你必须验证在循环之前有一个额外的函数调用是否真的会导致一些性能问题,或者只是你的想象。我写了一些你的代码的人工示例,并进行了反汇编,最后得到了类似于(x86)的结果:

call    pop
    cmp     eax, -1
    je      .L2
.L3:
    ...
    call    pop
    cmp     eax, -1
    jne     .L3

除了函数调用本身,cmp也可能会因为它是一个分支而在一定程度上延迟执行,但是,调用/分支的总量不会因为重写代码而有所不同。
然后我写了这样的东西

int y = 0;
  
while(y != -1) {
  printf("do something with y here %d", y);
  y = pop(stk2, &top2);
}

我注意到编译器删除了第一个y != 1比较,因为它可以推断出y在第一次循环时肯定不是-1。本质上,编译器在汇编器级别上创建了一个do-while循环。尽管我们只保存了一个分支,所以这是一个微优化,很可能不值得我们花时间去担心,所以你的代码一开始可能是可以的。
更重要的是,上面的代码只需要一个函数调用,可读性稍微好一点。但是while((y = pop(stk2, &top2)) != -1)的可读性要差得多,依赖于条件赋值的糟糕实践,这对性能是否有任何影响是非常值得怀疑的。
最佳做法:

  • 只有当你发现了真正的瓶颈,并且对底层硬件有了相当的了解时,才可以手动优化代码。(显然,优化在算法级别上不必要的慢代码总是可以的。)
  • "不要重复你自己"(DRY)通常是一个好原则,只要它不走极端(在这种情况下,它是有害的)。当调用相同的函数与相同的参数,这是一个好主意,只在代码中的一个地方做函数调用,为可读性和可维护性的目的。
  • 避免在if/loop条件中赋值。这是众所周知的安全隐患,并且会降低代码的可读性。一般来说,避免在一行中执行多个操作的代码,包括试图在一行中使用尽可能多的运算符的代码(运算符优先级错误y = pop(stk2, &top2) != -1就是一个说明)。避免在一个表达式中出现多个副作用。

相关问题