如何制作内存和数据结构的图表?

7

我需要用C语言编写一个操作字符串的短程序,但我总是遇到一些奇怪的指针错误。虽然K&R是这门语言的很好的参考书籍,当我感到困惑时我经常会去看它,但它已经假定你是一位合格的程序员。

教我们编程的讲师说,优秀的程序员会对这些东西制作漂亮的图表,但我不知道如何做。你能推荐一本好书或讲座吗?

谢谢,我将感激每一个回答。


注意:我不是在寻求演示工具。我正在寻找一种更好地想象内存和数据结构并为自己跟踪它们的方法(这样我就可以知道自己在做什么,而不是随意输入代码并进行调整,直到它们以某种方式起作用)。谢谢。 - Dimitar
11个回答

11

我赞同先在纸上画出它们,然后如果你感觉有必要,你可以将它们的ASCII版本包含在代码中。

我通常使用以下三种格式:


用于内存分析:

      +--------+
   0  |        |  <- 起始位置
      +--------+
   1  |        |  <- q 从起始到结尾扫描
      +--------+
      ~  ..... ~
      +--------+
      |        |  <- 结尾位置
      +--------+  \
      |        |  |
      +--------+  |__ 分配的其余内存区域
      ~  ..... ~  |   
  n   |        |  |
      +--------+ /


用于字符串分析:

    0               n
   +--+-- --+--+--+--+
   |  | ... |  |  |\0|
   +--+-  --+--+--+--+
     ^        ^__ q 从结尾到开头移动
     |            p 从开头到结尾移动


用于位运算分析:

   xxxx yyzz 00tt 11ss
   \    \ \  \ \  \ \__ 存储寄存器
    \    \ \  \ \  \___ 总是为1
     \    \ \  \ \_____ 临时值
      \    \ \  \______ 总是清零
       \    \ \________ 零标志位值
        \    \_________ y寄存器
         \_____________ x地址            


我曾经为有限状态机做过类似的事情,但它们往往太复杂了(也很耗时),所以现在我直接将GraphViz代码嵌入到注释中。即使不知道GraphViz,也应该很容易猜出如何绘制FSM图。

digraph G {
  mode = hier

  LIMBO [style= filled];
    node [shape = ellipse];
LIMBO -> HEADER ; HEADER -> LIMBO; HEADER -> TUNE ; TUNE -> LYRICS ;``` TUNE -> CHORD [style=dashed]; TUNE -> LIMBO; GRACE -> TUNE; GRACE -> CHORD [style=dashed]; SYMBOLS -> TUNE; SYMBOLS -> LIMBO;
overlap=false sep=1.5 }

这些图表涵盖了我所需的大部分内容。对于更复杂的图表,我会使用GraphViz或OpenOffice Draw。

```

8

我曾经做过的最有用的事情之一是让我的应用程序绘制图形...

在一个具有复杂数据结构的应用程序中(标准哈希表在这种情况下不起作用;-),我让我的应用程序输出一个“.dot”脚本,可以由graphviz的dot工具解析。

它通过具有转储例程(好吧,方法,它是C++)来输出.dot头文件。

 digraph g {

然后遍历我的数据结构并编写页脚。
 }

在结构体遍历中,它使用指针写入每个指针。
 SOURCE -> DESTINATION

其中,Source是引用对象的内存地址,以O(O213435354)开头,Destination是以同样格式指向的对象。

在每个对象的开头,它也会写入:

SOURCE [ .... ]  

对象数据是目标数据。

每当应用程序处于“有趣”的状态时,我会转储图形,然后使用graphviz的dot工具来可视化它。通过这种方式,我很容易找到很多指针错误,因为眼睛习惯在线条中看到规则结构...

顺便说一句,我仍经常使用graphviz,因为使用文本编辑器编写和编辑图形,然后让工具将其可视化非常方便。如果我需要为被PPT宠坏的观众打扮.dot图形,我会将它们加载到我的Mac上的OmniGraffle中。 (我的PC同事认为我拥有一些制图超级英雄的力量,因为使用这种组合时,我比他们使用Visio快10倍)


谢谢回复,Graphviz看起来很酷,但我担心它对我的需求来说有点太高级了。当我开始做更大的项目时,我一定会再次考虑它。 - Dimitar

7

优秀的程序员不会制作“漂亮”的图表 - 他们会制作凌乱、难以辨认但能够达到目的的图表。只需在任何可用的表面上涂鸦所需内容即可。不必担心绘制“正确”的形状 - 我的一位前同事曾说过,如果你无法在香烟包装纸的背面画出图表,那么图表方法论就毫无意义。


嗨,谢谢回复。我同意你的观点。你能举个图表方法的例子吗? - Dimitar

2
C的典型内存模型是将内存看作一组盒子,每个盒子的宽度为1字节。每个盒子都有一个十六进制地址。指针是一个变量,其中包含一个地址。
关于书籍/讲座,您需要寻找一本基本的计算机组织和架构的书。
我使用过这三本书;我按“难以理解程度递减”的顺序排序。经典的是Patterson和Hennessy的最后一本书,但我发现它是最不易读的。 YMMV。 http://www.amazon.com/Introduction-Computing-Systems-gates-beyond/dp/0072467509/ref=sr_1_1?ie=UTF8&s=books&qid=1238345302&sr=1-1 http://www.amazon.com/Digital-Design-Computer-Architecture-Harris/dp/0123704979/ref=sr_1_6?ie=UTF8&s=books&qid=1238345245&sr=1-6 http://www.amazon.com/Computer-Organization-Design-Fourth-Architecture/dp/0123744938/ref=sr_1_3?ie=UTF8&s=books&qid=1238345245&sr=1-3

1
你是在寻找帮助绘制图表的工具,还是想知道这些图表应该代表什么?我建议你只需使用纸和铅笔来理解自己所做的任何事情;你不需要任何花哨的工具。
如果你想了解指针的工作原理以及这些图表的含义,我在谷歌上搜索后发现this handout,看起来可能是一个不错的教程。

你好,谢谢您的快速回复。我在询问这些图表应该代表什么。这份讲义看起来非常好。 - Dimitar

1

你可能想看看 Gustave Duartes 的 博客。在他的文章中,他经常画出内存等方面的图表。他使用 Visio 来完成这些工作,我个人认为结果非常不错。


谢谢回复。我会查看Visio及其文档,尽管我怀疑我能否使用它。我想要做笔记和图表,而不是作为演示。但我还是会看看的。 - Dimitar

1

并没有很多工具可以绘制你的教授所指的内存映射样式。

他试图传达的思想是,当你作为一个初学者在C语言中使用指针和数组时,会感到非常困惑。什么目标指向什么?这两个指针指向同一件事吗?每个索引引用的字符串数组单元格是哪个等等。

有经验的程序员对此有一个心理形象。随着经验的积累,你也会有这种感觉。在那之前,你可以在纸上物理绘制一些东西来理解这些东西,而不是把它们都放在脑子里。

我同意K&R不是教科书,因此没有这些视觉效果。

你可以在我为C教程制作的幻灯片中看到这些图表的示例。


谢谢回复,我也认为他试图传达这个意思,但他声称他认识的更好的程序员仍然会画一些图表。 - Dimitar
我们作为程序员确实会制作很多图表,但这些图表主要是关于系统的总体结构,例如调用图、模块依赖和架构等方面的。 - Uri
嗯,你能给一些关于这个的通用建议吗?还是每个程序员都不同? - Dimitar

1

如果你想让你的图表看起来漂亮,可以使用一张方格纸和一支好铅笔*。这对于表示内存单元、字符串中的字母等也非常有用。如果你想时髦又想要方便,甚至可以购买方格摩leskines。

***我喜欢使用uni shalaku dx 0.5,因为它的进料按钮在侧面,所以你不必改变握笔方式就能获得更多的铅芯。


1

一个简单的方法是将内存绘制成一个巨大的“阶梯”。

阶梯上的每个框代表内存中的一个地址。您可以在框中键入数据,并在其旁边键入地址。

就像这样:

http://cosketch.com/Saved/pe6sHGD0

还要学习调试器的工作原理,它经常可以显示指针、变量等的内容。

谢谢回复。顺便说一下,cosketch真的很棒! - Dimitar

1

可视化问题的最佳方式是调试代码并关注变量。这不仅可以让您深入了解代码,还能让您绘制出您的讲师所说的代码图。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接