【问题标题】:Suggestions for improving the readability of this code提高本代码可读性的建议
【发布时间】:2015-05-04 08:43:17
【问题描述】:

我不确定是否应该在此处或其他 StackExchange 站点询问此问题,但我会继续……如果此处不适合,请迁移)

我正在审查代码。要求是调用函数nnumber 次,参数范围为0 到n。但如果n大于7,则只调用该函数7次。

我的同事是这样实现的:

void ExecuteFunctions(U8 count)
{
    if(count > 0) oprA(0);
    if(count > 1) oprA(1);
    if(count > 2) oprA(2);
    if(count > 3) oprA(3);
    if(count > 4) oprA(4);
    if(count > 5) oprA(5);
    if(count > 6) oprA(6);
    if(count > 7) oprA(7);
}

我修改为:

void ExecuteFunctions(U8 count)
{
    for(U8 loopcnt = 0; loopcnt < count; loopcnt++)
    {
        oprA(loopcnt);

        if(loopcnt == 7)
        {
            // We don't want to execute this function more number of times if it is already executed 7 times
            break;
        }
    }
}

但我仍然觉得可能有更好的方法并且需要您的意见。 (如果这里离题,也请迁移)

【问题讨论】:

  • 让编译器对其进行优化。它可能会为你展开循环。
  • @AustinMullins 好主意,但优化已关闭。你可以说,它现在对我来说就像一个编程谜题!
  • 可读性或性能优化?
  • 您可以将loopcnt &lt; 8 条件移动到循环条件中。它不会对其进行优化,但会使其更紧凑。
  • 问题不清楚:07 已经是8 次了。 n 是否包含在范围内?您的代码和您同事的代码似乎都没有实现规范。

标签: c code-readability


【解决方案1】:

MIN 是一个有用且经常定义的宏

#define MIN(a,b)     (((a) > (b)) ? (b) : (a))
#define MAX_STEP 7

void ExecuteFunctions(U8 count)
{
    int loopcnt = 0;
    count = MIN(count, MAX_STEP);

    while(loopcnt++ < count) {
        oprA(loopcnt);   
    }
}

【讨论】:

  • 您还应该提到MIN 宏的陷阱。 This link 在这里也很有用。
  • while(loopcnt++ &lt; count) 应更改为 for (loopcnt = 0; loopcnt &lt; count; loopcnt++) 否则 oprA() 会调用递增值。
【解决方案2】:

让编译器优化它。我觉得以下内容更具可读性:

void ExecuteFunctions(U8 count)
{
    for(U8 loopcnt = 0; loopcnt < count && loopcnt < 8; loopcnt++)
    {
        oprA(loopcnt);
    }
}

当然,您需要运行分析器来实际评估程序的性能。

【讨论】:

  • 很好的for 循环。注意:swtich() 以相反的顺序调用oprA()
  • 对,这就是为什么我说“如果顺序无关紧要”。
  • 为什么是你这样做 - 快速阅读和代码比文档更响亮的另一个例子。
  • 此代码为count &lt; 8 额外调用了一次oprA(),但如果顺序和准确性都不重要...
  • 我想知道为什么没有人早点发现。我会删掉 switch 语句部分。
【解决方案3】:

我会这样写

void ExecuteFunctions(unsigned count) {
    // Could use min() too if available.
    unsigned iters = count < 7 ? count : 7;

    for (unsigned i = 0; i < iters; ++i)
        oprA(i);
}

在使用 GCC 4.9 和 -O3 的 X86_64 上,为此函数生成的代码大小约为 36 字节。原始版本的大小为 141 字节(GCC 似乎不太聪明)。

请注意,传递普通的ints、unsigned ints、size_ts 等通常比仅仅因为您知道值会很小而缩小参数要好。编译器通常更容易为具有架构自然大小的变量生成好的代码。当您需要存储大量数据时例外。

更新:

以下版本(根据 Austin 的回答稍作修改——抱歉偷了它:))顺便提供了 32 个字节。我想我更喜欢它。

void ExecuteFunctions(unsigned count) {
    for (unsigned i = 0; i < count && i < 8; ++i)
        oprA(i);
}

【讨论】:

  • 在 SO 上没有偷窃之类的东西。最好的答案终将出现。你的不用提我了。
【解决方案4】:
void ExecuteFunctions(U8 count)
{
    for(U8 loopcnt = 0; loopcnt < (count & 7); loopcnt++)
    {
        oprA(loopcnt);
    }
}

【讨论】:

  • 对于count == 8,这将是零次。可能是一些类似的技巧......
【解决方案5】:

如果你真的喜欢switch 语句,试试这个,看看它是否能通过代码审查:

void ExecuteFunctions(U8 count) {
    int i = 0;
    switch (count) {
      default: oprA(i++);
      case 6:  oprA(i++);
      case 5:  oprA(i++);
      case 4:  oprA(i++);
      case 3:  oprA(i++);
      case 2:  oprA(i++);
      case 1:  oprA(i++);
      case 0:  oprA(i);
    }
}

【讨论】:

    猜你喜欢
    • 2010-10-07
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-08-22
    • 2023-04-04
    • 1970-01-01
    • 2021-07-30
    • 2010-11-11
    相关资源
    最近更新 更多