哪个是为嵌套循环声明虚拟变量的更好方法?

时间:2017-02-18 04:51:17

标签: c nested-loops

  1. 方法1的优点是文件大小略小,因为源代码中的文本字符较少:

    int i, j;
    for (i = 0; i < numRows; i++)
        for (j = 0; j < numCols; j++)
        //<some code here>
    
  2. 方法2的优点是局部变量的范围较小。

    int i;
    for (i = 0; i < numRows; i++)
    {
        int j;
        for (j = 0; j < numCols; j++)
        //<some code here>
    }
    
  3. 即使在今天的现代计算机中优化的差异可以忽略不计,哪种方法被认为是“更好”的代码呢?

    编辑以澄清此问题不重复:

    这个问题是基于当前的C11标准,它不允许这样的语法:

    for (int i = 0; i < numRows; i++)
    

    在C ++和C99中,这种语法是完全可以接受的,而C11不允许for语句中的变量声明。

    编辑以纠正错误信息:

    我以为我使用的是C11,因为我最近从CodeBlocks下载了编译器,所以我之所以说C11不允许for语句中的变量声明。但事实证明我实际上使用的是C90,这是我问题的根源。

4 个答案:

答案 0 :(得分:5)

对于纯粹的紧凑性和范围的限制,我会使用:

for (size_t i = 0; i < numRows; i++) {
    for (size_t j = 0; j < numCols; j++) {
    //<some code here>
    }
}

请注意size_t用于看似数组索引的内容。 size_t类型是unsigned整数类型,保证能够保存任何数组索引。只是风格问题,但我还建议在所有循环体周围使用大括号。这使您不太可能通过不可避免的更新和更改来破坏代码。

通过习惯用这样的块作用域声明循环变量,你强迫自己选择来使用存储在代码中其他地方的循环变量中的值。

答案 1 :(得分:1)

这似乎是一个品味的问题,而不是有任何明确的答案,但我会给你我的意见:

鉴于目前的计算机,保存几个字符的源代码太简单甚至无法思考。事实上,我想我会说,即使我在1976年在VAX 11/780上学习C语言。

我赞成第二个例子,因为当前的偏好是将变量声明为尽可能接近第一次使用。在C ++中,您甚至可以将循环变量的声明放在for语句中:

for (int i = 0; i < numRows; i++) {
   for (int j = 0; j < numCols; j++) {
      ...
   }
}

但这只是一个品味问题:如果变量的声明接近其使用,则认为该程序将更具可读性。

答案 2 :(得分:1)

这两种方法都不是首选。

两种常见的编码指南是:(1)确保变量不存在超过其需要的时间;(2)不要将变量用于多个事物。遵循这些指导方针可以减少(通常但不总是消除)变量的意外使用,从而避免出现细微的编程错误。

在第一种情况下,ij继续存在,直到封闭范围结束 - 这意味着它们在循环完成后存在。这最大化了后续代码(在该封闭范围内)意外重用ij用于其他目的的机会(例如,当意图使用另一个变量时)。这些错误通常很难找到。

第二种情况有同样的问题,只有i除外。即使是一个存在这种问题的变量也是坏消息。

我可能会使用像

这样的结构
// unintentionally using i or j here will cause a compilation error

for (int i = 0; i < numRows; i++)
{
    // unintentionally using j here will cause a compilation error

    for (int j = 0; j < numCols; j++)
    {
       //<some code here>
    }

    // unintentionally using j here will cause a compilation error
}

// unintentionally using i or j here will cause a compilation error

(我已经插入的评论使得这一点更加难以理解,但在实践中通常不需要这样的评论。)

这可确保外部循环外不存在i而不是j。这也意味着j不能在外循环中意外使用。实际上,当i出现时很容易键入j(反之亦然) - 例如,它们在QWERTY键盘上靠得很近。 ij在视觉上看起来非常相似,因此可视代码检查经常会错过这些错误。但是,使用这样的方法,COMPILER将检测到这样的拼写错误。如果有选择,最好让编译器选择错误,而不是让人类找不到它们。

当然,这并不能防止内循环中ij的误用或交换 - 但这是指导原则鼓励使用更多信息名称的一个原因与ij相比 - 误读视觉上不同的名字对于凡人来说更容易被发现。

答案 3 :(得分:-1)

第二种方法是

的最佳方法
  1. 可以使用低内存
  2. 如果在任何其他循环中需要,则允许再次使用相同的变量