16

就变量命名约定而言,应该命名迭代器i还是更语义化的东西count?如果你不使用i,为什么不呢?如果您认为这i是可以接受的,是否存在不应该使用它的迭代案例?

4

21 回答 21

35

取决于我想的上下文。如果您在某个集合中循环遍历一组对象,那么从上下文中您正在做什么应该是相当明显的。

for(int i = 0; i < 10; i++)
{
    // i is well known here to be the index
    objectCollection[i].SomeProperty = someValue;
}

但是,如果从上下文中不能立即清楚您在做什么,或者如果您正在修改索引,则应该使用更能说明用法的变量名称。

for(int currentRow = 0; currentRow < numRows; currentRow++)
{
    for(int currentCol = 0; currentCol < numCols; currentCol++)
    {
        someTable[currentRow][currentCol] = someValue;
    }
} 
于 2008-09-25T00:32:27.627 回答
15

“i”对程序员来说意味着“循环计数器”。它没有任何问题。

于 2008-09-25T00:30:41.687 回答
6

这是另一个完全没问题的例子:

foreach (Product p in ProductList)
{
    // Do something with p
}
于 2008-09-25T00:31:32.887 回答
5

我倾向于将 i、j、k 用于非常本地化的循环(就源代码行数而言仅存在很短的一段时间)。对于存在于较大源区域中的变量,我倾向于使用更详细的名称,这样我就可以看到它们的用途,而无需在代码中进行搜索。

顺便说一句,我认为这些命名约定来自早期的 Fortran 语言,我是第一个整数变量(A - H 是浮点数)?

于 2008-09-25T00:31:30.343 回答
3

i是可以接受的,可以肯定的。然而,一个学期我从一位 C++ 老师那里学到了很多东西,他拒绝了对每个变量都没有描述性名称的代码。描述性地命名一切的简单行为迫使我更加努力地思考我的代码,并且在那门课程之后我编写了更好的程序,不是来自学习 C++,而是来自学习命名一切。Code Complete在这个主题上有一些好话。

于 2008-09-25T00:33:30.510 回答
3

很好,但这样的事情不是:

for (int i = 0; i < 10; i++)
{
    for (int j = 0; j < 10; j++)
    {
        string s = datarow[i][j].ToString(); // or worse
    }
}

程序员在不经意间交换代码中的 i 和 j 是很常见的,尤其是当他们视力不好或他们的 Windows 主题是“热狗”时。对我来说,这总是一种“代码味道”——如果没有搞砸,这种情况很少见。

于 2008-09-25T01:43:47.847 回答
3

i 是如此常见以至于它是可以接受的,即使对于喜欢描述性变量名称的人也是如此。

绝对不可接受的(在我的书中是一个罪过)是在任何其他上下文中使用 i、j 或 k,而不是作为循环中的整数索引......例如

foreach(Input i in inputs)
{
    Process(i);

}
于 2008-09-25T02:00:02.237 回答
2

我绝对可以接受。不知道我需要做出什么样的理由——但我确实一直在使用它,其他非常受人尊敬的程序员也这样做。

社会验证,我猜:)

于 2008-09-25T00:26:27.003 回答
2

是的,事实上它是首选,因为任何阅读您的代码的程序员都会明白它只是一个迭代器。

于 2008-09-25T00:27:02.820 回答
2

使用 i 而不是更具体的变量名有什么价值?为了节省 1 秒或 10 秒,或者甚至可能,甚至 30 秒的思考和打字?

使用 i 的成本是多少?也许什么都没有。也许代码很简单,使用 i 就可以了。但也许,也许,使用 i 将迫使未来使用此代码的开发人员不得不思考片刻“我在这里的意思是什么?” 他们将不得不思考:“它是一个索引、一个计数、一个偏移量还是一个标志?” 他们将不得不思考:“这种变化是否安全,是否正确,我会落后 1 分吗?”

在编写代码时使用 i 可以节省时间和精力,但最终可能会在未来花费更多的精力,甚至可能由于误解代码而导致无意中引入缺陷。

一般来说,大多数软件开发都是维护和扩展,因此阅读代码所花费的时间将大大超过编写代码所花费的时间。

很容易养成在任何地方使用有意义的名字的习惯,一旦你养成了这个习惯,用有意义的名字编写代码只需要几秒钟,但是你的代码更容易阅读、更容易理解等等显然是正确的。

于 2008-09-25T00:36:21.673 回答
2

我将 i 用于短循环。

没问题的原因是,我发现有人可以看到带有初始化程序的迭代器类型声明,然后在三行之后声称不清楚该变量代表什么,这完全令人难以置信。他们只是在假装,因为他们已经决定“有意义的变量名”必须意味着“长变量名”。

我实际这样做的原因是,我发现使用与手头的特定任务无关的东西,而且我只会在很小的范围内使用,这样我就不用担心我可能会使用一个具有误导性或模棱两可的名称,或者有一天会在更大范围内对其他东西有用。它是“i”而不是“q”或“count”的原因只是从数学中借来的惯例。

如果出现以下情况,我不使用 i:

  • 循环体不小,或者
  • 除了从范围开始到循环结束的前进(或后退)之外,迭代器执行任何操作:

i 不一定必须以 1 为增量,只要增量一致且清晰,当然可能会在 iterand 结束之前停止,但如果它改变方向,或者没有被循环的迭代修改(包括在前向循环中对 iterator.insertAfter() 的恶意使用),我尽量记住使用不同的东西。这表明“这不仅仅是一个平凡的循环变量,因此这可能不是一个平凡的循环”。

于 2008-09-25T00:37:54.150 回答
1

如果“更语义化的东西”是“迭代器”,那么没有理由不使用 i;这是一个很好理解的成语。

于 2008-09-25T00:29:59.443 回答
1

我认为我在 for 循环情况下是完全可以接受的。我一直觉得这是非常标准的,当我在这种情况下使用时,从来没有真正遇到过解释问题。foreach-loops 变得有点棘手,我认为这真的取决于你的情况。我很少在 foreach 中使用 i,仅在 for 循环中使用,因为我发现 i 在这些情况下太不具描述性了。对于 foreach 我尝试使用正在循环的对象类型的缩写。例如:

foreach(DataRow dr in datatable.Rows)
{
    //do stuff to/with datarow dr here
}

无论如何,只是我的 0.02 美元。

于 2008-09-25T11:01:08.223 回答
0

如果您将其命名为描述它正在循环的内容,它会有所帮助。但我通常只使用 i.

于 2008-09-25T00:26:14.553 回答
0

只要您使用 i 来计算循环,或者使用从 0(或 1,取决于 PL)到 n 的索引的一部分,那么我会说 i 很好。

否则它可能很容易命名 i 一些有意义的东西,它不仅仅是一个索引。

于 2008-09-25T00:28:40.227 回答
0

我应该指出 i 和 j 也是矩阵索引的数学符号。通常,您正在遍历一个数组。所以这是有道理的。

于 2008-09-25T00:32:02.900 回答
0

只要您在一个简单的循环中临时使用它,并且很明显您在做什么,当然可以。也就是说,没有其他短词可以代替吗?

i被广泛称为循环迭代器,所以如果你在循环之外使用它,你实际上更有可能混淆维护程序员,但如果你使用更具描述性的东西(如filecounter),它会使代码更好。

于 2008-09-25T00:32:41.963 回答
0

这取决于。如果您正在迭代某些特定的数据集,那么我认为使用描述性名称更有意义。(例如,filecounter正如丹建议的那样)。

但是,如果您正在执行任意循环,则i可以接受。正如一位工作伙伴向我描述的那样 -i是一种约定,意思是“这个变量只被for循环构造修改。如果这不是真的,不要使用i

于 2008-09-25T00:38:56.020 回答
0

将 i、j、k 用于 INTEGER 循环计数器可以追溯到 FORTRAN 的早期。
只要它们是整数计数,就我个人而言,我对它们没有任何问题。
但后来我在 FORTRAN 上长大!

于 2008-09-25T00:39:55.957 回答
0

我的感觉是使用单个字母的概念对于“简单”循环来说很好,但是,我很久以前就学会了使用双字母并且效果很好。

我上周问了一个类似的问题,以下是我自己回答的一部分:

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

我已经这样做了至少10年了。

请注意,很多人评论说上述任何一个/两个都是“丑陋的”......

于 2008-09-25T16:46:11.890 回答
-1

我要反对谷物,说不。

对于说“我被理解为迭代器”的人群,这可能是真的,但对我来说,这相当于“将值 5 分配给变量 Y”之类的评论。像评论这样的变量名称应该解释为什么/什么不是如何。

要使用先前答案中的示例:

for(int i = 0; i < 10; i++)
{
    // i is well known here to be the index
    objectCollection[i].SomeProperty = someValue;
}

像这样使用一个有意义的名字就更难了吗?

for(int objectCollectionIndex = 0; objectCollectionIndex  < 10; objectCollectionIndex ++)
{
    objectCollection[objectCollectionIndex].SomeProperty = someValue;
}

授予(借用的)变量名称 objectCollection 的名称也很糟糕。

于 2010-11-03T17:44:28.310 回答