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

如果你正在写一个简单的小循环,你应该怎么指定柜台?

提供示例循环!

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

使用有意义的名称时:

  • 代码读取代码的同事更容易理解,
  • 在循环逻辑中find错误更容易
  • 文本search的variables名返回相关的代码片上运行相同的数据更可靠。

例如 – 发现错误

使用单个字母来查找这个嵌套循环中的错误可能非常棘手:

 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一些替代build议,为什么我select不使用它们:

  • rc :这比ij稍微好点。 如果我的组织的标准是单字母variables是整数,那么我只会考虑使用它们,并且总是成为等效描述性名称的第一个字母。 如果我的名字以“r”开头的函数中有两个variables,系统就会崩溃,即使代码中任何地方出现了以“r”开头的其他对象,可读性也会受到影响。
  • rrcc :这看起来很奇怪,但是我不习惯双字母循环variables样式。 如果这是我组织的标准,那么我认为它会比rc稍好。
  • rowcol :乍一看,这似乎比row_numcol_num更简洁,正如描述性一样。 但是,我会期望像“row”和“column”这样的名词来指向结构,对象或指向这些的指针。 如果row可能意味着行结构本身行号,那么会导致混淆。
  • iRowiCol :这expression了额外的信息,因为i可以指它是一个循环计数器,而RowCol告诉你它在计算什么。 不过,我更喜欢用英文阅读代码:
    • row_num < MAX_COLS读作“ 行号 小于最大列数( 数)”;
    • iRow < MAX_COLS最多读为“该整数循环计数器 小于最大值(列数)”。
    • 这可能是个人的事情,但我更喜欢第一读。

row_num的另一种select是row_idx :除非应用程序的领域是在数据库引擎devise,金融市场或类似领域,否则“index”这个词唯一地指代一个数组的位置。

我上面的例子尽可能小,因此,有些人可能无法描述性地指出variables的含义,因为他们可以将整个function放在头上。 然而,在真实代码中,函数会更大,逻辑更复杂,所以体面的名字变得更重要,以帮助可读性和避免错误。

总之,我所有的variables命名(不只是循环)的目标是完全明确的 。 如果有人读取我的代码的任何部分,并不能立即确定variables是什么,那么我已经失败了。

1)对于正常的老式小循环 – i,j,k – 如果你需要超过3级嵌套循环,这意味着要么algorithm是非常具体和复杂的,要么你应该考虑重构代码。

Java示例:

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

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

Java示例:

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

3)如果你使用的语言是可能的,转换循环使用迭代器

Java迭代器例子: 点击这里

例子: 在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 } 

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

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

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

这个最后一个例子没有评论就读得很差,从而鼓励他们。 它可能是冗长的,但在C中作用域限制循环是有用的。

总是尝试将variables命名为有意义的内容。

如果你不能决定,那么使用“索引”,如果只是让别人(也许你!)可以更容易地点击它来稍后重构。

Paul Stephenson查看此答案的示例。

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

但是我很久以前就学会了一个很好的select,并且自那以后就使用它:双字母variables。

 // 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; } ● } } ● } 

如果好处不明显:通过代码search任何单个字母将会发现很多不是你正在寻找的东西。 字母i在代码中经常出现,它不是你正在寻找的variables。

我使用ijk (或行列循环的rc )。 如果在一个方法中需要三个以上的循环variables ,那么这个方法可能太长又复杂,而且你的代码可能会受益于把方法分解成更多的方法并正确地 命名

i

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

这个约定很常见,如果你在一段代码中遇到一个variablesi ,你看不到你的开始,那么它仍然可以立即识别它是什么。

我使用我,二,三,四,五…从来没有比三高,但。

只有当循环计数器是索引时,我才使用单个字母。 我喜欢双字母背后的想法,但却使得代码难以理解。

如果计数器用作容器的索引,则使用ijk

如果它被用来迭代一个范围(或者执行一系列的迭代),我经常使用n 。 但是,如果需要嵌套,我通常会回到ijk

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

 foreach widget in widgets do foo(widget) end 

我想有些人会告诉我命名widget widgets ,所以类似于widgets ,但我觉得它很可读。

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

史蒂夫·麦康奈尔的Code Complete像往常一样,在这方面有一些很好的build议。 相关页面(无论如何,第一版)是340和341.绝对build议任何谁有兴趣改善他们的循环编码给这个看看。 麦康奈尔build议有意义的循环计数器名称,但人们应该阅读他自己要说的话,而不是依靠我的弱点。

我使用“计数器”或“循环”作为variables名称。 现代的IDE通常会完成这个单词,所以更长的variables名称并不繁琐。 此外,将variables命名为它的function使得程序员清楚要保持你的代码的意图。

Perl标准

在Perl中,内部循环的标准variables名是$ _forforeachwhile语句默认为这个variables,所以你不需要声明它。 通常, $ _可以像中性通用代词“it”一样被读取。 所以一个相当标准的循环可能看起来像:

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

用英语表示:

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

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

 for (@item){ print; } 

用英语:

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

这也是柜台的标准。 (但是在Perl中计数器的使用要less于其他语言(如C))。 所以要打印从1到100的整数的正方形:

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

由于只有一个循环可以使用$ _variables,所以通常用在最内部循环中。 这种用法与英语通常的工作方式相匹配:

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

在Perl中:

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

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

偶尔,使用较短的非描述性的通用名称比如$ i$ j$ k ,而不是$ _或描述性名称是有意义的。 例如,匹配已发布的algorithm中使用的variables(例如交叉乘积)很有用。

第一条规则是variables名的长度应该与variables的范围相匹配。 第二条规则是有意义的名字使错误更加浅薄。 第三条规则是,如果你想给variables名添加注释,你select了错误的variables名。 最后的规则是像你的队友一样做,只要它不抵制先前的规则。

@JustMike。 。 。 几个C实例: 。 。 。 陪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 } } } 

关于这种布局的一个好处是,它没有评论就读得很差,从而鼓励他们。
这可能是冗长的,但个人来说,这是我如何循环在C

另外: 当我开始使用“索引”和“idx”时,通常我的同事变成了“我”。

无论你select什么,只要你的代码有相同的含义,就一致地使用相同的索引。 例如,要遍历一个数组,可以使用ijjkappa ,但是在任何情况下都可以使用相同的方法:

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

最好的做法是让循环的这一部分在你的代码中看起来是一样的(包括一贯地使用count作为限制),这样它就成为一个习惯,你可以跳过精神上的焦点,以专注于代码的肉,循环的主体。

同样,例如,如果你正在穿过像素的二维数组,你可能会写

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

只要在你写这种types的循环的每个地方以同样的方式做。

你希望你的读者能够忽略无聊的设置,并看到你在实际循环中所做的辉煌。

我很久以前就使用过i / j / k命名scheme。 但是最近我已经开始适应一个更加随之而来的命名方法。

我已经通过它的含义命名了所有的variables,为什么不用相同的确定性方式来命名循环variables呢?

正如要求的几个例子:

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

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

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

 Item currentItem = list[currentItemIndex]; 

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

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

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

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

我仍然只使用一个字母variables的时候是我正在循环槽的尺寸。 但是接下来我会用x,y和z。

我也使用双字母约定。 ii,jj,kk。 你可以grep这些,而不是拿出一堆不需要的匹配。

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

对于坚持惯例有很多要说的。 它使事情变得更可读。

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

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

我的习惯是使用't' – 接近于'r',所以它很容易在后面input'for'

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

我已经开始使用与匈牙利混合的上下文相关的循环variables名称。

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

对于数值计算,matlab,和它的喜欢,不要使用我,j

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

我个人的喜好是

指数第一,第二计数器

我最喜欢的用于循环类matrix的约定是使用x + y,因为它们用于笛卡尔坐标:

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

我通常使用:

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

对于整数,我使用int索引,除非嵌套,那么我使用索引后缀,比如int groupIndex和int userIndex。

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