【发布时间】:2010-09-11 04:37:45
【问题描述】:
如果你正在编写一个简单小循环,你应该将计数器命名为什么?
提供示例循环!
【问题讨论】:
-
很遗憾关闭了。一些答案提供了非常有用的见解。请打开这个!
标签: language-agnostic naming-conventions
如果你正在编写一个简单小循环,你应该将计数器命名为什么?
提供示例循环!
【问题讨论】:
标签: language-agnostic naming-conventions
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
【讨论】:
我的经验是大多数人使用单个字母,例如:
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 经常出现在不是您要查找的变量的代码中。
【讨论】:
我也使用双字母约定。二、jj、kk。你可以 grep 那些而不想出一堆不需要的匹配。
我认为使用这些字母,即使它们是双倍的,也是最好的方法。这是一个熟悉的约定,即使加倍也是如此。
坚持惯例有很多话要说。它使事情更具可读性。
【讨论】:
非嵌套循环:。 . .索引是一个值。
。 . . 使用
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 中的范围限制循环中很有用。
【讨论】:
我总是使用一个有意义的名字,除非它是一个单级循环并且变量除了“我已经通过这个循环的次数”之外没有任何意义,在这种情况下我使用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_num 和 col_num 的一些替代建议以及我选择不使用它们的原因:
r 和 c:这比 i 和 j 略好。如果我的组织的标准是单字母变量是整数,并且始终是等效描述性名称的第一个字母,我只会考虑使用它们。如果函数中有两个名称以“r”开头的变量,系统就会崩溃,即使代码中的任何位置出现其他以“r”开头的对象,可读性也会受到影响。rr 和 cc:这对我来说很奇怪,但我不习惯双字母循环变量样式。如果它是我组织的标准,那么我想它会比r 和c 略好。row 和 col:乍一看,这似乎比 row_num 和 col_num 更简洁,并且具有描述性。但是,我希望像“行”和“列”这样的裸名词指代结构、对象或指向这些的指针。如果row 可能表示或者行结构本身,或行号,则会导致混淆。iRow 和 iCol:这传达了额外的信息,因为 i 可能意味着它是一个循环计数器,而 Row 和 Col 告诉你它在计数.但是,我更喜欢能够几乎用英文阅读代码:
row_num < MAX_COLS 读作“行数ber 小于 maximum(数量)column s";iRow < MAX_COLS 充其量读作“行的整数循环计数器小于 maximum(数量)columns”。我会接受row_num 的替代方案row_idx:“索引”一词唯一地指的是数组位置,除非应用程序的域是数据库引擎设计、金融市场或类似领域。
我上面的示例尽可能小,因此有些人可能看不到描述性命名变量的意义,因为他们可以一次将整个函数放在脑海中。然而,在实际代码中,函数会更大,逻辑也更复杂,因此为了提高可读性和避免错误,体面的名称变得更加重要。
总之,我对所有变量命名(不仅仅是循环)的目标是完全明确。如果 任何人 读取了我的代码的任何部分并且无法立即计算出变量的用途,那么我就失败了。
【讨论】:
在 Python 中,如果我只计算次数,我会使用 i、j 和 k。如果将迭代计数用作索引,我将使用 x、y 和 z。但是,如果我实际上是在生成一系列参数,我将使用一个有意义的名称。
【讨论】:
我长期使用 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。
【讨论】:
对于整数,我使用 int index,除非它是嵌套的,否则我会在迭代的内容上使用 Index 后缀,例如 int groupIndex 和 int userIndex。
【讨论】:
我通常使用:
for(lcObject = 0; lcObject < Collection.length(); lcObject++)
{
//do stuff
}
【讨论】:
Steve McConnell 的 Code Complete 像往常一样在这方面提供了一些很好的建议。相关页面(无论如何在第一版中)是 340 和 341。绝对建议任何有兴趣改进循环编码的人看看这个。 McConnell 建议使用有意义的循环计数器名称,但人们应该阅读他自己要说的内容,而不是依赖我薄弱的总结。
【讨论】:
无论您选择什么,在您的代码中始终使用相同的索引,只要它具有相同的含义。例如,要遍历一个数组,您可以使用 i、jj、kappa 等等,但始终在任何地方都使用相同的方式:
for (i = 0; i < count; i++) ...
最好的做法是让循环的这一部分在整个代码中看起来都一样(包括始终使用count 作为限制),这样它就可以成为一个习惯用法,你可以在脑海中跳过它以便专注于代码的主体,循环的主体。
类似地,例如,如果您正在穿过一个二维像素数组,您可能会这样写
for (y = 0; y < height; y++)
for (x = 0; x < width; x++)
...
只需在您编写此类循环的每个地方都以相同的方式进行。
您希望您的读者能够忽略无聊的设置,并在实际循环中看到您正在做的事情的精彩。
【讨论】:
在类似矩阵的集合上循环我最喜欢的约定是使用 x+y,因为它们在笛卡尔坐标中使用:
for x in width:
for y in height:
do_something_interesting(x,y)
【讨论】:
对于数值计算、matlab 等,不要使用 i、j
这些是保留常量,但 matlab 不会抱怨。
我个人最喜欢的是
索引 第一秒 柜台 数
【讨论】:
我已经开始使用与上下文相关的循环变量名和hungarian。
循环遍历行时,我将使用iRow。遍历列时,我将使用iCol。当循环通过汽车时,我将使用iCar。你明白了。
【讨论】:
我使用 i、j、k(或 r 和 c用于行列循环)。如果您需要一个方法中的循环变量超过三个,则该方法可能太长且太复杂,您的代码可能受益于将方法拆分为更多方法和命名他们正确。
【讨论】:
@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”。
【讨论】:
第一条规则是变量名的长度要与变量的作用域相匹配。第二条规则是有意义的名称使错误更浅。第三条规则是,如果您想为变量名添加注释,那么您选择了错误的变量名。最终规则是你的队友做的,只要它不抵消之前的规则。
【讨论】:
我使用 i, ii, iii, iv, v ... 不过从来没有超过 iii。
【讨论】:
在 Perl 中,内部循环的标准变量名是 $_。 for、foreach 和 while 语句默认使用此变量,因此您无需声明它。通常,$_ 可能被读作中性代词“它”。所以一个相当标准的循环可能看起来像:
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。
【讨论】:
如果它是一个简单的计数器,我坚持使用“i”,否则,使用表示上下文的名称。我倾向于将可变长度保持为 4。这主要是从代码阅读的角度来看,写入不算数,因为我们有自动完成功能。
【讨论】:
始终尝试将变量命名为有意义且符合上下文的名称。
如果你不能决定,那么使用“索引”,如果只是为了让其他人(也许是你!)可以更轻松地点击它以便以后重构。
Paul Stephenson 请参阅此答案以获取示例。
【讨论】:
i 对几乎所有编程的人来说都是有意义的。当i 短得多,而且在我看来,更具可读性时,为什么还要输入index?
我使用“counter”或“loop”作为变量名。现代 IDE 通常使用完成这个词,因此较长的变量名使用起来不会那么乏味。此外,将变量命名为它的功能可以让维护您的代码的程序员清楚地了解您的意图。
【讨论】:
如果要将计数器用作容器的索引,我使用i、j、k。
如果要用于在一个范围内迭代(或执行一定次数的迭代),我经常使用n。不过,如果需要嵌套,我通常会恢复为 i、j、k。
在提供foreach 风格结构的语言中,我通常这样写:
foreach widget in widgets do
foo(widget)
end
我想有些人会因为我将 widget 命名为与 widgets 相似而拒绝我,但我觉得它很可读。
【讨论】:
和之前的海报一样,我也使用 ii、jj、.. 主要是因为在许多字体中,单个 i 看起来与 1 非常相似。
【讨论】:
i
如果我有一个嵌套循环,那么还有j。
这种约定非常普遍,以至于如果您设法在代码块中遇到变量i,以至于您看不到开头,您仍然可以立即识别出它是什么。
【讨论】:
我的习惯是使用 't' - 接近于 'r' 所以在输入 'for' 后很容易理解
【讨论】:
我已经开始在 php 中使用 perlisms。
如果它是一个单一的迭代,$_ 对于知道其用途的人来说是个好名字。
【讨论】:
仅当循环计数器是索引时,我才使用单个字母。我喜欢双字母背后的想法,但它使代码变得难以阅读。
【讨论】: