清洁代码

调试从了解你尝试调试的代码开始。

不好的代码:

int main() {
    int value;
    std::vector<int> vectorToSort;
    vectorToSort.push_back(42); vectorToSort.push_back(13);
    for (int i = 52; i; i = i - 1)
    {
    vectorToSort.push_back(i *2);
    }
    /// Optimized for sorting small vectors
    if (vectorToSort.size() == 1);
    else
        {
        if (vectorToSort.size() <= 2)
            std::sort(vectorToSort.begin(), std::end(vectorToSort));
        }
    for (value : vectorToSort) std::cout << value << ' ';
return 0; }

更好的代码:

std::vector<int> createSemiRandomData() {
    std::vector<int> data;
    data.push_back(42);
    data.push_back(13);
    for (int i = 52; i; --i)
        vectorToSort.push_back(i *2);
    return data;
}

/// Optimized for sorting small vectors
void sortVector(std::vector &v) {
    if (vectorToSort.size() == 1)
        return;
    if (vectorToSort.size() > 2)
        return;

    std::sort(vectorToSort.begin(), vectorToSort.end());
}

void printVector(const std::vector<int> &v) {
    for (auto i : v)
        std::cout << i << ' ';
}

int main() {
    auto vectorToSort = createSemiRandomData();
    sortVector(std::ref(vectorToSort));
    printVector(vectorToSort);

    return 0;
 }

无论你喜欢和使用哪种编码样式,具有一致的编码(和格式)样式都将帮助你理解代码。

查看上面的代码,可以确定一些改进,以提高可读性和可调试性:

使用单独的函数进行单独的操作

如果你对细节不感兴趣,可以使用单独的函数跳过调试器中的某些函数。在这种特定情况下,你可能对创建或打印数据不感兴趣,只想进入排序。

另一个优点是,你需要在单步执行代码时读取更少的代码(并记住它)。你现在只需要阅读 main() 中的 3 行代码来理解它,而不是整个函数。

第三个优点是你只需要查看更少的代码,这有助于训练有素的人在几秒钟内发现这个 bug。

使用一致的格式/结构

使用一致的格式和构造将消除代码中的混乱,使得更容易专注于代码而不是文本。很多关于’正确’格式化风格的讨论已经得到了充分的讨论。无论这种风格如何,在代码中使用单一一致的样式将提高熟悉度并使其更容易专注于代码。

由于格式化代码是一项耗时的任务,因此建议使用专用工具。大多数 IDE 至少对此有一些支持,并且可以比人类更加一致地进行格式化。

你可能会注意到样式不仅限于空格和换行符,因为我们不再混合使用自由样式和成员函数来获取容器的开始/结束。 (v.begin() vs std::end(v))。

请注意代码的重要部分

无论你决定选择何种样式,上面的代码都包含一些标记,可能会提示你可能重要的内容:

  • 一个评论说明 optimized,这表明一些奇特的技术
  • sortVector() 的一些早期回报表明我们正在做一些特别的事情
  • std::ref() 表明 sortVector() 正在发生一些事情

结论

使用干净的代码可以帮助你理解代码,并减少调试代码所需的时间。在第二个示例中,代码审阅者甚至可能在第一眼看到错误,而错误可能隐藏在第一个错误中。 (PS:该错误与 2 相比。)