【发布时间】:2019-05-27 12:28:18
【问题描述】:
我正在查看 Don Knuth 教授的一些代码,用 CWEB 编写,转换为 C。一个具体的例子是 dlx1.w,可从Knuth's website 获得
在某一阶段,结构 nd[cc] 的 .len 值会递减,并且以笨拙的方式完成:
o,t=nd[cc].len-1;
o,nd[cc].len=t;
(这是一个 Knuth 特定的问题,所以也许您已经知道“o”是一个用于递增“mems”的预处理器宏,它是通过访问 64 位字来衡量的运行总工作量.) "t" 中剩余的值绝对不会用于其他任何事情。 (这里的例子在dlx1.w的第665行,或者在ctangle之后的dlx1.c的第193行。)
我的问题是:为什么 Knuth 会这样写,而不是
nd[cc].len--;
他确实在其他地方使用过(dlx1.w 的第 551 行):
oo,nd[k].len--,nd[k].aux=i-1;
(而且“oo”是一个类似的宏,用于将“mems”递增两次——但这里有一些微妙之处,因为 .len 和 .aux 存储在同一个 64 位字中。将值分配给 S.len和 S.aux,通常只计算一次内存增量。)
我唯一的理论是递减由两次内存访问组成:首先是查找,然后是分配。 (对吗?)这种写法是对这两个步骤的提醒。这对 Knuth 来说会异常冗长,但也许这是本能的备忘录而不是说教。
对于它的价值,我在CWEB documentation 中进行了搜索,但没有找到答案。我的问题可能更多地与 Knuth 的标准做法有关,我正在一点一点地学习。我会对将这些实践作为一个整体进行布局(并且可能受到批评)的任何资源感兴趣——但现在,让我们专注于 Knuth 为何以这种方式编写它。
【问题讨论】:
-
Knuth 所做的一切都很笨拙,并且针对混淆进行了优化。
-
@Boann 我很好奇是什么让你这么说;你能详细说明一下吗?就我个人而言,我一直觉得 Knuth 的写作清晰而令人愉悦,从我第一次遇到(具体数学)到他的几篇论文和计算机编程艺术的部分内容。 (他的编程风格似乎与 1970 年代的主流有所不同,即他找到了与大多数其他人不同的解决方案,但不知道您指的是什么。)
-
@ShreevatsaR 听到有人这么说我很惊讶!我努力在 TAOCP 上取得任何进展,然后放弃并扔掉了这本书。对我来说,Knuth 是一个真正希望编程更少语言和更抽象的娱乐数学的人,所以他假装是那样的,尽管这(对我来说)完全令人困惑和不切实际。看看问题中那些荒谬的变量名;
o、t、nd、cc、aux。难以理解。 -
@Boann 你的经验是你的,我无法反驳,但 IMO Knuth 是最“现实世界”的数学家/算法家:最明确不是 假装抽象是真实的,但分析真实计算机上的真实程序可能会发生什么(例如,他不仅分析 Big-O 渐近线,还分析了常数因子)。当然,TAOCP 是关于算法的数学分析(见前言),但 IMO 它比它的任何继任者/替代品都更“具体”(例如,它们中的哪些包括用于研究缓存、RAM 大小、流水线等效果的汇编程序?)
标签: c increment decrement literate-programming knuth