【问题标题】:What is an ideal variable naming convention for loop variables? [closed]循环变量的理想变量命名约定是什么? [关闭]
【发布时间】:2010-09-11 04:37:45
【问题描述】:

如果你正在编写一个简单小循环,你应该将计数器命名为什么

提供示例循环!

【问题讨论】:

  • 很遗憾关闭了。一些答案提供了非常有用的见解。请打开这个!

标签: language-agnostic naming-conventions


【解决方案1】:

1) 对于普通的旧式小循环 - i、j、k - 如果您需要 3 级以上的嵌套循环,这意味着要么算法非常具体和复杂,要么您应该考虑重构代码。

Java 示例:

for(int i = 0; i < ElementsList.size(); i++) {
  Element element = ElementsList.get(i);
  someProcessing(element);
  ....
}

2) 对于像for(Element element: ElementsList) 这样的新型java 循环,最好使用普通的有意义的名称

Java 示例:

for(Element element: ElementsList) {
  someProcessing(element);
  ....
}

3) 如果可以使用您使用的语言,请将循环转换为使用迭代器

Java 迭代器示例:click here

【讨论】:

  • 我当然同意@Ande Turner 的观点,即“i” 对 99.9% 的程序员来说是自我描述的。但是,您在 Java 示例中为我提出了我的观点……如果您“重构”循环以不使用“i”——由于“someProcessing”,您无法对循环进行全局替换。如果它是“ii”,你可以;-)
  • @just mike:您可以进行全局替换:\bi\b
  • 几年前我学到的一个有趣的替代方法是使用“idx”(“index”的缩写),然后,如果您有第二个或嵌套循环,请使用“jdx”、“kdx”等. 所以它延续了 i,j,k 的传统,但有点可读性。
【解决方案2】:

我的经验是大多数人使用单个字母,例如: i, j, k, ... 要么 x, y, 要么 r, c(用于行/列) 要么 w, h(宽度/高度) 等。

但我很久以前就学会了一个很好的替代方法,并且从那时起就一直在使用它:双字母变量。

// recommended style              ●    // "typical" single-letter style
                                  ●
for (ii=0; ii<10; ++ii) {         ●    for (i=0; i<10; ++i) {
    for (jj=0; jj<10; ++jj) {     ●        for (j=0; j<10; ++j) {
        mm[ii][jj] = ii * jj;     ●             m[i][j] = i * j;
    }                             ●        }
}                                 ●    }

如果好处不是很明显:在代码中搜索任何单个字母都会发现许多不是您正在寻找的东西。字母i 经常出现在不是您要查找的变量的代码中。

【讨论】:

  • 此外,当循环变量不应该位于循环之外的任何位置时,为什么还要搜索它们?除非您之间有大量代码 - 这不是一个好主意。
  • 如果您需要搜索迭代变量,那就是重构时间!
  • 我同意其他人的说法,如果您需要在代码中搜索循环变量,那么是时候重构了。
  • 来自 Jeff 的博客条目:codinghorror.com/blog/archives/001172.html 这是我们每个人都在 SO 上使用的一些有趣的代码:refactormycode.com/codes/333-sanitize-html(见第 22 行);-)
  • 可能有点私人的东西,但我真的不喜欢这种命名约定。我觉得它丑陋,令人困惑且难以理解。 -1
【解决方案3】:

我也使用双字母约定。二、jj、kk。你可以 grep 那些而不想出一堆不需要的匹配。

我认为使用这些字母,即使它们是双倍的,也是最好的方法。这是一个熟悉的约定,即使加倍也是如此。

坚持惯例有很多话要说。它使事情更具可读性。

【讨论】:

    【解决方案4】:

    示例:。 . .在 Java 中


    非迭代循环:


    非嵌套循环:。 . .索引是一个值。

    。 . . 使用i就像在代数中一样,是最常见的做法。 . .

    for (int i = 0; i < LOOP_LENGTH; i++) {
    
        // LOOP_BODY
    }
    


    嵌套循环:。 . .区分指数有助于理解。

    。 . . 使用描述性后缀。 . .

    for (int iRow = 0; iRow < ROWS; iRow++) {
    
        for (int iColumn = 0; iColumn < COLUMNS; iColumn++) {
    
            // LOOP_BODY
        }
    }
    


    foreach 循环:。 . . Object 需要一个名字。

    。 . .使用描述性名称。 . .

    for (Object something : somethings) {
    
        // LOOP_BODY
    }
    


    迭代循环:


    for 循环:。 . .迭代器引用对象。 Iterator 两者都不是;一个索引,也不是一个索引。

    。 . . iter 是迭代器目的的缩写。 . .

    for (Iterator iter = collection.iterator(); iter.hasNext(); /* N/A */) {
    
        Object object = iter.next();
    
        // LOOP_BODY
    }
    


    while 循环:。 . .限制迭代器的范围。

    。 . . 评论循环目的。 . .

    /* LOOP_DESCRIPTION */ {
    
        Iterator iter = collection.iterator();
    
        while (iter.hasNext()) {
    
            // LOOP_BODY
        }
    }
    

    最后一个例子在没有 cmets 的情况下读起来很糟糕,因此鼓励了他们。 这可能很冗长,但在 C 中的范围限制循环中很有用。

    【讨论】:

      【解决方案5】:

      我总是使用一个有意义的名字,除非它是一个单级循环并且变量除了“我已经通过这个循环的次数”之外没有任何意义,在这种情况下我使用i.

      使用有意义的名称时:

      • 阅读您的代码的同事更容易理解代码,
      • 更容易找到循环逻辑中的错误,并且
      • 文本搜索变量名以返回对相同数据进行操作的相关代码段更可靠。

      示例 - 发现错误

      使用单个字母在这个嵌套循环中查找错误可能很棘手:

      int values[MAX_ROWS][MAX_COLS];
      
      int sum_of_all_values()
      {
          int i, j, total;
      
          total = 0;
          for (i = 0; i < MAX_COLS; i++)
              for (j = 0; j < MAX_ROWS; j++)
                   total += values[i][j];
          return total;
      }
      

      而使用有意义的名称会更容易:

      int values[MAX_ROWS][MAX_COLS];
      
      int sum_of_all_values()
      {
          int row_num, col_num, total;
      
          total = 0;
          for (row_num = 0; row_num < MAX_COLS; row_num++)
              for (col_num = 0; col_num < MAX_ROWS; col_num++)
                   total += values[row_num][col_num];
          return total;
      }
      

      为什么是row_num? - 拒绝替代品

      针对其他一些答案和 cmets,这些是使用 row_numcol_num 的一些替代建议以及我选择不使用它们的原因:

      • rc:这比 ij 略好。如果我的组织的标准是单字母变量是整数,并且始终是等效描述性名称的第一个字母,我只会考虑使用它们。如果函数中有两个名称以“r”开头的变量,系统就会崩溃,即使代码中的任何位置出现其他以“r”开头的对象,可读性也会受到影响。
      • rrcc:这对我来说很奇怪,但我不习惯双字母循环变量样式。如果它是我组织的标准,那么我想它会比rc 略好。
      • rowcol:乍一看,这似乎比 row_numcol_num 更简洁,并且具有描述性。但是,我希望像“行”和“列”这样的裸名词指代结构、对象或指向这些的指针。如果row 可能表示或者行结构本身,行号,则会导致混淆。
      • iRowiCol:这传达了额外的信息,因为 i 可能意味着它是一个循环计数器,而 RowCol 告诉你它在计数.但是,我更喜欢能够几乎用英文阅读代码:
        • row_num &lt; MAX_COLS 读作“行数ber 小于 ma​​ximum(数量)column s";
        • iRow &lt; MAX_COLS 充其量读作“整数循环计数器小于 ma​​ximum(数量)columns”。
        • 这可能是个人的事情,但我更喜欢一读。

      我会接受row_num 的替代方案row_idx:“索引”一词唯一地指的是数组位置,除非应用程序的域是数据库引擎设计、金融市场或类似领域。

      我上面的示例尽可能小,因此有些人可能看不到描述性命名变量的意义,因为他们可以一次将整个函数放在脑海中。然而,在实际代码中,函数会更大,逻辑也更复杂,因此为了提高可读性和避免错误,体面的名称变得更加重要。

      总之,我对所有变量命名(不仅仅是循环)的目标是完全明确。如果 任何人 读取了我的代码的任何部分并且无法立即计算出变量的用途,那么我就失败了。

      【讨论】:

      • 我发现第一个更具可读性。较长的名称(尤其是随处可见的“_num”)只会增加视觉混乱。
      • 问题不在于索引变量,但我认为新的代码阅读器不太可能发现第一个示例中存在 错误。第二,表达式“row_num
      • 为什么不将 row_num 缩写为 r,将 col_num 缩写为 c?对于普通读者来说,变量的含义同样清楚,您无需处理太多视觉上的混乱。
      • 我认为 Petr K 和 Derek 没有太多维护其他人的代码。第二个例子更容易阅读,更重要的是,更容易理解。做一些维护编程一段时间,你会渴望有意义的变量名。
      • Paul:你得到了我的投票,我完全同意你的约定。使用 i & j 你必须检查它在循环中的使用方式以找到错误(上下文)。使用 *_num 您可以在没有上下文的情况下看到潜在的错误。 i & j 也很容易混淆,因为有时您会使用行专业和其他列专业
      【解决方案6】:

      在 Python 中,如果我只计算次数,我会使用 i、j 和 k。如果将迭代计数用作索引,我将使用 x、y 和 z。但是,如果我实际上是在生成一系列参数,我将使用一个有意义的名称。

      【讨论】:

        【解决方案7】:

        我长期使用 i/j/k 命名方案。但最近我开始采用一种更随性的命名方法。

        我已经按其含义命名了所有变量,那么为什么不以相同的确定性方式命名循环变量。

        根据要求举几个例子:

        如果您需要循环遍历项目集合。

        for (int currentItemIndex = 0; currentItemIndex < list.Length; currentItemIndex++)
        {
            ...
        }
        

        但我尽量避免正常的 for 循环,因为我倾向于想要列表中的真实项目并使用它,而不是列表中的实际位置。所以不要用 a: 开始 for 块:

        Item currentItem = list[currentItemIndex];
        

        我尝试使用该语言的 foreach 结构。它改变了。

        for (int currentItemIndex = 0; currentItemIndex < list.Length; currentItemIndex++)
        {
            Item currentItem = list[currentItemIndex];
            ...
        }
        

        进入

        foreach (Item currentItem in list)
        {
           ...
        }
        

        这使得它更容易阅读,因为只表达了代码的真正含义(处理列表中的项目)而不是我们想要处理项目的方式(保持当前项目的索引并增加它直到它达到列表的长度,从而意味着项目集合的结束)。

        我仍然使用一个字母变量的唯一一次是在循环槽尺寸时。但后来我会使用 x、y,有时还会使用 z。

        【讨论】:

          【解决方案8】:

          对于整数,我使用 int index,除非它是嵌套的,否则我会在迭代的内容上使用 Index 后缀,例如 int groupIndex 和 int userIndex。

          【讨论】:

            【解决方案9】:

            我通常使用:

            for(lcObject = 0; lcObject < Collection.length(); lcObject++)
            {
               //do stuff
            }
            

            【讨论】:

            • ...当然假设没有从集合中添加或删除任何内容!
            【解决方案10】:

            Steve McConnell 的 Code Complete 像往常一样在这方面提供了一些很好的建议。相关页面(无论如何在第一版中)是 340 和 341。绝对建议任何有兴趣改进循环编码的人看看这个。 McConnell 建议使用有意义的循环计数器名称,但人们应该阅读他自己要说的内容,而不是依赖我薄弱的总结。

            【讨论】:

              【解决方案11】:

              无论您选择什么,在您的代码中始终使用相同的索引,只要它具有相同的含义。例如,要遍历一个数组,您可以使用 ijjkappa 等等,但始终在任何地方都使用相同的方式:

              for (i = 0; i < count; i++) ...
              

              最好的做法是让循环的这一部分在整个代码中看起来都一样(包括始终使用count 作为限制),这样它就可以成为一个习惯用法,你可以在脑海中跳过它以便专注于代码的主体,循环的主体。

              类似地,例如,如果您正在穿过一个二维像素数组,您可能会这样写

              for (y = 0; y < height; y++)
                for (x = 0; x < width; x++)
                  ...
              

              只需在您编写此类循环的每个地方都以相同的方式进行。

              您希望您的读者能够忽略无聊的设置,并在实际循环中看到您正在做的事情的精彩。

              【讨论】:

                【解决方案12】:

                在类似矩阵的集合上循环我最喜欢的约定是使用 x+y,因为它们在笛卡尔坐标中使用:

                for x in width:
                    for y in height:
                        do_something_interesting(x,y)
                

                【讨论】:

                • 在这种情况下,它们实际上是有意义的名称
                【解决方案13】:

                对于数值计算、matlab 等,不要使用 i、j

                这些是保留常量,但 matlab 不会抱怨。

                我个人最喜欢的是

                索引 第一秒 柜台 数

                【讨论】:

                  【解决方案14】:

                  我已经开始使用与上下文相关的循环变量名和hungarian

                  循环遍历行时,我将使用iRow。遍历列时,我将使用iCol。当循环通过汽车时,我将使用iCar。你明白了。

                  【讨论】:

                    【解决方案15】:

                    我使用 ijk(或 rc用于行列循环)。如果您需要一个方法中的循环变量超过三个,则该方法可能太长且太复杂,您的代码可能受益于将方法拆分为更多方法和命名他们正确

                    【讨论】:

                      【解决方案16】:

                      @JustMike 。 . . 几个例子:。 . .陪伴 Java 的。

                      非嵌套循环:。 . .尽可能限制范围

                      /*LOOP_DESCRIPTION*/ {
                      
                          int i;
                      
                          for (i = 0; i < LOOP_LENGTH; i++) {
                      
                              // loop body
                          }  
                      }
                      


                      嵌套循环:。 . .同上

                      /*LOOP_DESCRIPTION*/ {
                      
                          int row, column;
                      
                          for (row = 0; row < ROWS; row++) {
                      
                              for (column = 0; column < COLUMNS; column++) {
                      
                                  // loop body
                              }
                          }  
                      }
                      

                      这种布局的一个好处是它在没有 cmets 的情况下读起来很糟糕,从而鼓励了他们。
                      这可能很冗长,但就我个人而言,这就是我在 C 中执行循环的方式。

                      另外:我刚开始的时候确实使用了“index”和“idx”,但是这通常被我的同龄人改为“i”。

                      【讨论】:

                        【解决方案17】:

                        第一条规则是变量名的长度要与变量的作用域相匹配。第二条规则是有意义的名称使错误更浅。第三条规则是,如果您想为变量名添加注释,那么您选择了错误的变量名。最终规则是你的队友做的,只要它不抵消之前的规则。

                        【讨论】:

                        • 我同意你所说的一切(除了我已经知道说“推荐”比“规则”更好)——而且大多数人认为我的变量名太长了。 “......像你的队友那样做......”是我使用“一致性”标签的原因之一。另一个原因当然是“做你自己”。
                        【解决方案18】:

                        我使用 i, ii, iii, iv, v ... 不过从来没有超过 iii。

                        【讨论】:

                          【解决方案19】:

                          Perl 标准

                          在 Perl 中,内部循环的标准变量名是 $_forforeachwhile 语句默认使用此变量,因此您无需声明它。通常,$_ 可能被读作中性代词“它”。所以一个相当标准的循环可能看起来像:

                          foreach (@item){
                              $item_count{$_}++;
                          }
                          

                          用英语翻译为:

                          对于每个项目,增加它的 item_count。

                          然而,更常见的是根本不使用变量。许多 Perl 函数和运算符默认为 $_

                          for (@item){
                              print;
                          }
                          

                          英文:

                          对于 [每个] 项目,打印 [it]。

                          这也是计数器的标准。 (但计数器在 Perl 中的使用频率远低于在其他语言(如 C)中的使用频率)。所以要打印从 1 到 100 的整数的平方:

                          for (1..100){
                              print "$_*$_\n";
                          }
                          

                          由于只有一个循环可以使用 $_ 变量,因此通常在最内层循环中使用它。这种用法符合英语通常的用法:

                          对于每辆车,查看每个轮胎并检查其压力。

                          在 Perl 中:

                          foreach $car (@cars){
                              for (@{$car->{tires}}){
                                  check_pressure($_);
                              }
                          }
                          

                          如上所述,最好在外部循环中使用更长的描述性名称,因为在很长的代码块中很难记住通用循环变量名称的真正含义。

                          有时,使用较短的、非描述性的通用名称是有意义的,例如 $i$j$k ,而不是 $_ 或描述性名称。例如,匹配已发布算法中使用的变量很有用,例如cross product

                          【讨论】:

                            【解决方案20】:

                            如果它是一个简单的计数器,我坚持使用“i”,否则,使用表示上下文的名称。我倾向于将可变长度保持为 4。这主要是从代码阅读的角度来看,写入不算数,因为我们有自动完成功能。

                            【讨论】:

                              【解决方案21】:

                              始终尝试将变量命名为有意义且符合上下文的名称。

                              如果你不能决定,那么使用“索引”,如果只是为了让其他人(也许是你!)可以更轻松地点击它以便以后重构。

                              Paul Stephenson 请参阅此答案以获取示例。

                              【讨论】:

                              • 人们可能会争辩说命名索引变量毫无意义,但我发现它让你养成了有意识地思考变量命名的习惯。此外,如果您使用的是 C,则需要确保避免变量名与同一方法中的任何其他循环发生冲突。
                              • 错误,使用 C99 并在循环标题中声明您的循环变量(当然,假设您可以选择使用 C99)。
                              • 哎呀。感谢您的提醒。显然我已经很久没有使用 C 编译器了。
                              • 事情是,i 对几乎所有编程的人来说都是有意义的。当i 短得多,而且在我看来,更具可读性时,为什么还要输入index
                              【解决方案22】:

                              我使用“counter”或“loop”作为变量名。现代 IDE 通常使用完成这个词,因此较长的变量名使用起来不会那么乏味。此外,将变量命名为它的功能可以让维护您的代码的程序员清楚地了解您的意图。

                              【讨论】:

                                【解决方案23】:

                                如果要将计数器用作容器的索引,我使用ijk

                                如果要用于在一个范围内迭代(或执行一定次数的迭代),我经常使用n。不过,如果需要嵌套,我通常会恢复为 ijk

                                在提供foreach 风格结构的语言中,我通常这样写:

                                foreach widget in widgets do
                                  foo(widget)
                                end
                                

                                我想有些人会因为我将 widget 命名为与 widgets 相似而拒绝我,但我觉得它很可读。

                                【讨论】:

                                • 我经常使用 k 来迭代范围,使用 n 或 n_something 来标记范围的大小。否则我完全同意你。
                                • 我喜欢你为小部件中的每个元素使用小部件
                                【解决方案24】:

                                和之前的海报一样,我也使用 ii、jj、.. 主要是因为在许多字体中,单个 i 看起来与 1 非常相似。

                                【讨论】:

                                • 那为什么不使用不同的字母呢?还是一个词?
                                • 在编辑器中搜索/突出显示“ii”或“jj”也更容易。
                                • 再一次,我不得不质疑为什么你需要搜索循环变量。除非您编写复杂的(与 Complex 相对的复杂!)数学算法,否则循环变量的范围应该非常有限。
                                • 代码一次编写,多次阅读。因此,您应该立即清楚您阅读的内容。对于非常小的范围,一个简短的“单词”应该很短,但仍然可以与 1 区分开来。我认为 ii en jj 是很好的平衡。对于更大的范围,我同意前面的评论者并使用一个词。
                                【解决方案25】:

                                i

                                如果我有一个嵌套循环,那么还有j

                                这种约定非常普遍,以至于如果您设法在代码块中遇到变量i,以至于您看不到开头,您仍然可以立即识别出它是什么。

                                【讨论】:

                                  【解决方案26】:

                                  我的习惯是使用 't' - 接近于 'r' 所以在输入 'for' 后很容易理解

                                  【讨论】:

                                    【解决方案27】:

                                    我已经开始在 php 中使用 perlisms。

                                    如果它是一个单一的迭代,$_ 对于知道其用途的人来说是个好名字。

                                    【讨论】:

                                      【解决方案28】:

                                      仅当循环计数器是索引时,我才使用单个字母。我喜欢双字母背后的想法,但它使代码变得难以阅读。

                                      【讨论】:

                                        猜你喜欢
                                        • 1970-01-01
                                        • 1970-01-01
                                        • 1970-01-01
                                        • 1970-01-01
                                        • 1970-01-01
                                        • 1970-01-01
                                        • 1970-01-01
                                        • 1970-01-01
                                        相关资源
                                        最近更新 更多