循环变量的理想变量命名约定是什么?

时间:2008-09-19 10:55:32

标签: language-agnostic naming-conventions

如果您正在编写简单小循环,那么 应该为计数器命名?

提供示例循环!

28 个答案:

答案 0 :(得分:40)

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

使用有意义的名字时:

  • 阅读代码的同事可以理解代码,
  • 在循环逻辑中找到错误更容易,
  • text搜索变量名称以返回在相同数据上运行的相关代码段更可靠。

示例 - 发现错误

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

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? - 拒绝的替代方案

在回答其他一些答案和评论时,这些是使用row_numcol_num的一些替代建议以及我选择不使用它们的原因:

  • r c :这比ij稍好一些。如果我的组织的标准是单字母变量是整数,我也只考虑使用它们,并且也总是成为等效描述性名称的第一个字母。如果我在函数中有两个变量,其名称以“r”开头,那么系统就会崩溃,即使其他以“r”开头的对象出现在代码的任何地方,也会失去可读性。
  • rr cc :这对我来说很奇怪,但我不习惯双字母循环变量样式。如果它是我组织中的标准,那么我认为它会比rc略好。
  • row col :乍一看,这似乎比row_numcol_num更简洁,就像描述一样。但是,我希望像“行”和“列”这样的裸名词能够引用这些结构,对象或指针。如果row可能意味着 行结构本身,行号,则会产生混淆。
  • iRow iCol :这传达了额外的信息,因为i可能意味着它是一个循环计数器{{1 }和Row告诉你它在计算什么。但是,我更喜欢能够几乎用英语阅读代码:
    • Col读作“行数 ber 小于 max imum(数量) col UMN 取值“;
    • row_num < MAX_COLS充其量只读“整数循环计数器 小于 max < / strong> imum(数量) col umn s “。
    • 这可能是个人的事情,但我更喜欢第一次阅读。

我接受iRow < MAX_COLS的替代方法是row_num:“index”这个词唯一指的是一个数组位置,除非应用程序的域位于数据库引擎设计,金融市场或类似领域。

我上面的例子就像我能做到的那样小,因此有些人可能没有看到描述性地命名变量的重点,因为他们可以一次性掌握整个函数。然而,在实际代码中,函数会更大,逻辑更复杂,所以正确的名称对于提高可读性和避免错误变得更加重要。

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

答案 1 :(得分:35)

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 Iterator示例:click here

答案 2 :(得分:12)

示例:。 。 。在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循环次数。 。 。迭代器引用对象。迭代器它既不是;索引,也不是指数。

  

。 。 。 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
    }
}
  

最后一个例子在没有评论的情况下读得很糟糕,从而鼓励他们。   它可能很冗长,但在C中的范围限制循环中很有用。

答案 3 :(得分:12)

我的经验是大多数人使用单个字母,例如: ijk, ... 要么 xy, 要么 rc(对于行/列) 要么 wh(宽度/高度) 等等。

但是我很久以前就学会了一个很好的选择,并且从那时起就开始使用它:双字母变量。

// 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经常出现在代码中,而不是您正在寻找的变量。

答案 4 :(得分:8)

始终尝试将变量命名为有意义且在上下文中。

如果你无法决定,那么使用“index”,如果只是为了让别人(也许你!)可以更容易点击它进行重构。

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

答案 5 :(得分:6)

我使用 i j k (或 r &amp; c 用于行列循环)。如果在方法中需要三个以上的循环变量,那么该方法可能太长而且复杂,并且您的代码可能从将方法拆分中转移到更多方法中命名他们正确

答案 6 :(得分:5)

i

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

这个惯例是如此常见,以至于如果你设法在一段代码中遇到一个变量i,你看不到它的开头仍然会立即识别出它是什么。

答案 7 :(得分:5)

我使用i,ii,iii,iv,v ......但是,从来没有比iii更高。

答案 8 :(得分:4)

仅当循环计数器是索引时才使用单个字母。我喜欢双字母背后的想法,但它使代码完全不可读。

答案 9 :(得分:3)

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

如果要用于迭代范围(或执行一定数量的迭代),我经常使用n。但是,如果需要嵌套,我通常会恢复为ijk

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

foreach widget in widgets do
  foo(widget)
end

我认为有些人会告诉我widget的命名与widgets类似,但我发现它非常易读。

答案 10 :(得分:2)

史蒂夫麦康奈尔的 Code Complete 像往常一样,在这方面有一些很好的建议。相关页面(无论如何都是第一版)是340和341.绝对建议任何有兴趣改进循环编码的人来看看。 McConnell建议使用有意义的循环计数器名称,但人们应该阅读他自己要说的内容而不是依赖我的弱摘要。

答案 11 :(得分:2)

像以前的海报一样,我也使用ii,jj,...主要是因为在许多字体中,单个i看起来非常类似于1.

答案 12 :(得分:1)

Perl标准

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

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

在英语中,转换为:

  

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

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

for (@item){
    print;
}

英文:

  

对于[each]项目,请打印[it]。

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

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

由于只有一个循环可以使用 $ _ 变量,因此通常它在最内层循环中使用。此用法与英语通常的工作方式相符:

  

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

Perl:

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

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

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

答案 13 :(得分:1)

我也使用双字母约定。 ii,jj,kk。你可以点击那些而不是想出一堆不想要的比赛。

我认为使用这些字母,即使它们加倍,也是最好的方法。这是一个熟悉的惯例,即使加倍。

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

答案 14 :(得分:1)

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

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

最佳做法是让整个代码中的循环部分看起来相同(包括始终使用count作为限制),这样它就成了一个成语,你可以跳过精神上以便集中注意力关于代码的肉,循环的主体。

同样,例如,如果您正在浏览像素数组,则可以编写

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

在你编写这种循环的每个地方都这样做。

您希望您的读者能够忽略枯燥的设置并看到您在实际循环中所做的事情的辉煌。

答案 15 :(得分:1)

第一条规则是变量名的长度应该与变量的范围相匹配。第二个规则是有意义的名称使错误变得更浅。第三条规则是,如果您想在变量名称中添加注释,则选择了错误的变量名称。最终的规则是你的队友做的,只要它不会违反先前的规则。

答案 16 :(得分:1)

@JustMike。 。 。 A FEW C示例:。 。 。与Java一起。

NON-NESTED循环。 。 。尽可能限制范围

/*LOOP_DESCRIPTION*/ {

    int i;

    for (i = 0; i < LOOP_LENGTH; i++) {

        // loop body
    }  
}


NESTED循环:。 。 。同上

/*LOOP_DESCRIPTION*/ {

    int row, column;

    for (row = 0; row < ROWS; row++) {

        for (column = 0; column < COLUMNS; column++) {

            // loop body
        }
    }  
}

关于这种布局的一个好处是它没有评论就读得很糟糕,从而鼓励它们。
也许这很冗长,但就个人而言,这就是我在C中循环的方式。

另外:我在开始时使用了“index”和“idx”,但这通常被同行改为“我”。

答案 17 :(得分:1)

我早就使用了i / j / k命名方案。但最近我开始采用更加随之而来的命名方法。

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

根据要求提供了一些例子:

如果你需要循环一个项目集合。

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

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

开始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。

答案 18 :(得分:1)

我使用“counter”或“loop”作为变量名。现代IDE通常会执行单词完成,因此较长的变量名称使用起来并不繁琐。此外,要将变量命名为其功能,程序员将清楚地了解您的意图是什么。

答案 19 :(得分:0)

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

答案 20 :(得分:0)

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

循环遍历行时,我将使用iRow。循环遍历列时,我将使用iCol。在循环浏览汽车时,我会使用iCar。你明白了。

答案 21 :(得分:0)

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

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

我个人的好消息是

索引 第一秒 计数器 计数

答案 22 :(得分:0)

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

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

答案 23 :(得分:0)

我的习惯是使用't' - 接近'或',因此在输入'for'后它很容易跟随

答案 24 :(得分:0)

我通常使用:

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

答案 25 :(得分:0)

我开始在php中使用perlisms。

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

答案 26 :(得分:0)

对于整数我使用int索引,除非它是嵌套的,然后我使用索引后缀而不是像int groupIndex和int userIndex这样的迭代。

答案 27 :(得分:0)

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