4

理解大代码的问题之前已经得到了很好的回答。但是我觉得我应该再问一次这个问题来问我一直面临的问题。

我刚刚开始了一份学生工作。我是一名初级程序员,两个月前才了解课程。不过,在这份工作中,我收到了一个代码,它是一个大型软件的一部分。我了解该代码应该做什么(读取文件)。但是在花了几个星期试图理解代码并修改它以达到我们想要的结果之后,我得出的结论是我需要理解代码的每一行。代码大约1300行。

现在,当我开始阅读代码时,我发现,例如,一个变量被定义为:

VarType VarName

NowVarType不是intor之类的类型float。这是一个用户定义的类型,所以我必须去上课看看这个类型是什么。

在下一行,我看到一个函数被调用,比如points.interpolate(x); 现在我必须进入另一个班级,看看插值函数做了什么。

这种情况经常发生,这意味着即使我尝试理解一小部分代码,我也必须去 3 或 4 个不同的课程,并同时记住它们,而不会失去主要目标,这很困难。

我可能不是一个熟练的程序员,但我希望能够做到这一点。我可以对我应该如何处理这个问题提出一些建议吗?

另外(当我问这个问题时,我听起来真的很愚蠢)什么是调试器?我希望这能让您了解我的立场(以及再次提出这个问题的必要性)。:(

4

6 回答 6

6

运气好的话,这些函数和类应该至少有一些文档来描述它们的作用。您无需了解它们的工作方式即可了解它们的工作当您看到interpolate. 相反,阅读它的文档,它应该会告诉你理解使用它的代码所需要知道的一切。

如果没有文件,我会同情你。我可以提出两个建议:

  1. 从函数或类的名称、返回类型和参数以及使用它的周围代码对函数或类将做什么做出一般假设,直到发生与这些假设相矛盾的事情。我可以很好地猜测interpolate它是如何工作的,而无需阅读它是如何工作的。这仅在函数或类的名称具有足够的自文档性时才有效。

  2. 如果您需要深入了解某些代码的工作原理,请从底部开始向上工作。这样做意味着当您搜索代码库时,您最终不必记住您在某些高级代码中的位置。在尝试理解这些类型的高级应用之前,先对低级基础类有一个很好的理解。

    这也意味着您将在一般意义上理解函数和类,而不是在引导您使用它们的代码的上下文中。当你找到 时points.interpolate(x),不要想知道这个特定参数interpolate对这些特定的做了什么,而是找出它的一般作用。稍后,您将能够将新发现的知识应用于使用相同功能的任何代码。pointsx

尽管如此,我不会担心 1300 行代码。这基本上是一个小项目。它只比示例和大学作业大。如果您考虑到这些提示,那么该数量的代码应该很容易管理。


调试器是帮助您调试代码的程序。调试器的共同特性允许您逐行执行代码并观察变量值的变化。您还可以在代码中设置感兴趣的断点,调试器会在遇到断点时通知您。一些调试器甚至允许您在执行时更改代码。有许多不同的调试器都具有不同的功能集。

于 2013-03-28T13:46:49.910 回答
5

尝试根据其标题对代码的作用做出假设。例如,假设该interpolate函数正确地插入了您的观点;只有在输出看起来可疑时才去挖掘那段代码。

于 2013-03-28T13:46:47.600 回答
1

首先,考虑获得具有以下功能的编辑器/IDE

  • 括号/括号/大括号匹配
  • 大括号之间代码块的折叠/展开
  • 类型突出显示(在工具提示中)
  • 宏扩展(在工具提示或单独的窗口/面板中)
  • 函数原型扩展(在工具提示或单独的窗口/面板中)
  • 快速导航到类型、函数和类并返回
  • 在不同位置的多个窗口/面板中打开同一个文件
  • 搜索特定类型、变量、函数或类的所有提及/使用,并将其显示为列表
  • 调用树/图构建/导航
  • 除了简单搜索之外的正则表达式搜索
  • 书签?

Source Insight就是这样的工具之一。一定还有其他人。

其次,考虑在阅读代码时对其进行注释。执行此操作时,请注意(写下)以下内容:

  • 不变量(始终正确或必须始终正确)
  • 假设(可能不正确,例如缺少检查/验证或无根据的期望),思考“如果”
  • 一段代码的目标(什么)
  • 实现的特性/细节(如何;例如是否抛出异常以及哪些异常,返回哪些错误代码以及何时)
  • 一个简化的调用树/图来查看代码流
  • 对数据流做同样的事情

绘制图表(ASCII 码或纸/纸板);我有时会为我的论文或黑板拍照。具体来说,绘制框图状态机

使用不同抽象/细节级别的代码。放大看细节,缩小看结构。折叠/展开代码块和调用树/图的分支。

另外,有一个你要做什么的清单。检查您已完成的项目。根据需要添加更多。如果合适的话,为工作项目分配优先级。


调试器是一个程序,可让您逐步执行程序并检查其状态(变量)。它还允许您修改状态,这有时也很有用。

如果您对代码或编程语言不太熟悉,则可以使用调试器来理解您的代码。

另一件可能派上用场的事情是为您的程序编写测试或输入数据测试集。它们可能会揭示逻辑和性能方面的问题和限制。


另外,不要忽视文档人员!如果有某事或某人可以为您提供有关项目/代码的更多信息,请使用该某事或某人。征求意见


我知道这听起来很多,但无论如何你最终都会做一些这样的事情。等待一个足够大的项目。:)

于 2013-03-28T14:18:25.970 回答
0

已经给出了许多很好的答案。我想增加我作为前学生的理解(不久前)以及我学到的知识来帮助我理解代码。这对我特别有帮助,因为我开始了一个项目,将我多年前用 Java 编写的数据库转换为 C++。

1. **Code Reading** - Do not underestimate this important task.  The ability to write code  
   does not always translate into the ability to read it -- and reading it can be more 
   frustrating than writing it.

花点时间仔细发现每一行代码的作用。这肯定会帮助您避免做出假设,除非您遇到您熟悉的代码并且可以掩饰它。

2. Don't hesitate to follow references, locate declarations, and uncover definitions of 
   code elements you are reading. What you learn about how a particular variable, 
   method call, or class are defined all contribute to learning and ultimately to you 
   being able to perform your task. 

这一点特别重要,因为侦探和有效的侦探工作是理解代码的小部分的重要部分,这样您将来就可以更轻松地掌握较大的部分。

其他人已经发布了有关什么是调试器的信息,您会发现它是跟踪代码错误的宝贵资产,而且我认为它有助于代码阅读、知识获取和理解,因此您可以成为一名成功的程序员。

这是一个使用 Visual Studio 的调试器教程的链接,可以让您至少对手头的过程有一个深刻的理解。

于 2013-03-28T14:58:13.550 回答
0

“尝试调试器方法”

[更新:调试器是一个特殊程序,它可以让您暂停正在运行的程序以检查程序的状态(变量值/哪个函数正在运行/谁是父函数等)]

对于我想了解的用例,我这样做的方法是逐步调试代码。

如果您使用的是 Advanced/Mordern IDE,那么在入口点(如 main() 或兴趣点)设置断点相当容易。然后从那里进入您想要检查或超越该功能的功能。

给你一步一步的方法

  1. 在 main() 方法(入口点)开始表达式中设置断点。
  2. 在调试活动的情况下运行程序
  3. 程序将在断点处中断。
  4. 现在,如果跨步直到遇到一个看起来很有趣的函数/表达式。(比如说,你的points.interpolate(x);)函数
  5. 进入函数,并实时检查程序状态,如变量和函数堆栈。
  6. 避免使用复杂的系统库。只是跨过/走出。(例如:避免类似的东西MathLib.boringComputaion()
  7. 重复直到程序退出。

我发现这种学习方式非常快速,可以让您快速了解任何复杂/大型软件。

使用 Eclipse,或者如果你不能尝试 GDB,如果它的 C/C++。每种流行的编程语言都有一个不错的调试器。

了解基本的调试操作将是一个好处:

  1. 设置断点。
  2. 在断点处停止。
  3. 检查/观察变量。
  4. 检查函数堆栈(函数调用的层次结构)
  5. 单步 - 单步执行代码中的下一行。
  6. 步入函数。
  7. 跳出一个函数。
  8. 跳过一个函数。
  9. 跳转到下一个断点(兴趣点)。

希望能帮助到你!

于 2013-03-28T14:04:02.133 回答
0

您可能首先需要了解被调用的函数的功能是什么,然后了解该函数的输入和输出是什么,例如,如果您确实需要了解如何interpolate完成,则可以进入细节。通常,函数的名称是不言自明的,如果代码写得好,你可以从函数的名称中感受到函数的作用。

您可能想要尝试的另一件事是运行一些玩具示例来浏览代码,您可以使用一些可以帮助您浏览代码的调试器或 IDE。理解大规模代码需要时间和经验,耐心点。

于 2013-03-28T13:54:08.713 回答