【问题标题】:for loop macro coding stylefor 循环宏编码风格
【发布时间】:2016-12-11 19:55:09
【问题描述】:

我在大学的一位导师建议使用宏来减少 c99 代码中的重复,就像这样。

#define foreach(a, b, c) for (int a = b; a < c; a++)
#define for_i foreach(i, 0, n)
#define for_j foreach(j, 0, n)
#define for_ij for_i for_j

可以这样使用:

for_ij { /*do stuff*/; }
for_i  { /*do stuff*/; }

另一位具有工业背景的导师不鼓励使用它,声称它被他的前雇主视为一种反模式(但他不知道这背后的原因)。事实上,通过搜索大型项目的源代码,人们很少会在简短的学术示例之外找到这些结构。

我的问题是:为什么这种结构在实践中很少使用?是不是有点危险?

【问题讨论】:

  • 您实际上是在使用预处理器创建自己的方言。 Doig so 总是充满危险,并阻碍对任何其他人(或以后的你自己)的理解。无论如何,这是Software Engineering 的更多问题,而不是SO。
  • 打个比方,想象一本书的序言指出“SR”将取代“罗伯特说”,“TND”将取代“第二天”。您可以阅读它,但至少可以说很奇怪
  • 当我学习 C 时(很久以前),我比你的第一位导师聪明,并且做到了#define forloop for (int i = 0; i &lt; n; i++) {。通过将{ 添加到宏中,我节省了更多重复!现代文本编辑器对不平衡的大括号并不满意,但在过去的美好时光这不是问题......
  • 听第二位导师——有工业背景的。他的建议更明智,IMNSHO。这种宏很少使用,因为节省的输入量不足以保证增加混淆选项。

标签: c loops macros c-preprocessor


【解决方案1】:

这是对学术界与现实世界差距的完美诠释,令人难以置信。但它看起来太奇怪了。

回答您的问题:这种结构在实践中使用,并且使用隐式变量和条件隐藏信息是有风险的。

以下是一些普通读者会思考的问题:

  • 上限是多少?不是很明显应该是n
  • i 的实际范围是多少?
  • 它是基于0 的吗?
  • 是否包含n 或之前停止?

C 程序员非常擅长阅读惯用的结构,例如

for (int i = 0; i < n; i++) {
    ...
}

隐藏这个循环逻辑的细节并不能节省任何东西,会适得其反,容易出错,并且应该被本地编码约定取缔。它不在我的团队中的唯一原因是没有人想出这么奇怪的想法。

您可能需要谨慎对待希望使用这些缩写的大学导师,这可能是 APL 怀旧之情,并避免冲突。你可能想和他玩一些code golfing,有一个stack exchange dedicated to that,他会喜欢人们如何浪费无数小时从源代码中删除字节......

但是你应该听从其他导师的建议,编写清晰明确的代码,仔细缩进和间隔,在重要的地方使用有意义的名称,在使用明显的地方使用简短的名称。尽可能使用惯用的结构,因为它使代码更易读、更不容易出错并且更适合优化编译器。

【讨论】:

    【解决方案2】:

    问题在于重复的减少(因此可读性的提高)是相当微不足道的。你在减少

    for (int i = 0; i < n; i++)
        for (int j = 0; j < n; j++)
    

    for_ij
    

    这并没有太大的改进,因为变量名称 ijn 都很短,因此重复它们不是问题。

    同时,您隐藏了参数 n —— 后一个循环隐式依赖于 n,即使 nfor_ij 或(可能)在for 循环。隐藏重要信息使阅读代码变得更加困难——要阅读此内容,您需要知道 n 的关键重要性,您只能通过搜索两个级别的宏间接来看到它。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2015-03-30
      • 1970-01-01
      • 2011-07-15
      • 2021-12-14
      相关资源
      最近更新 更多