i和 j是非常流行的变量名(参见例如 这个问题和 这个)。
i
j
例如,在循环中:
for i=1:10, % Do something... end
作为矩阵的索引:
mat(i, j) = 4;
为什么在 MATLAB 中使用 不应该作为变量名?
默认情况下,i和 j代表虚单位。所以从 MATLAB 的角度来看,使用 i作为变量有点像使用 1作为变量。
1
因为 i和 j都是表示 想象单位的函数:
因此,一个名为 i或 j的变量将覆盖它们,有可能悄无声息地破坏执行复杂数学的代码。
可能的解决方案包括使用 ii和 jj作为循环变量,或者在需要 i来表示虚单元时使用 1i。
ii
jj
1i
最好避免使用 i和 j变量,以避免将它们混淆为变量或假想单位。
然而,就我个人而言,我经常使用 i和 j作为变量作为短循环的索引。为了避免在我自己的代码中出现问题,我遵循了另一个关于 i和 j的良好实践: 不要使用它们来表示虚数。事实上,MATLAB 自己的文档状态:
为了提高速度和鲁棒性,可以用 1i代替复杂的 i和 j。
因此,我没有因为潜在的冲突而避免使用两个非常常用的变量名,而是明确说明了虚数。这也使我的代码更加清晰。每当我看到 1i,我知道它代表 sqrt(-1),因为它不可能是一个变量。
sqrt(-1)
如其他答复所述,不建议在一般代码中使用 i,原因有二:
建议: 1i和 ii。然而,尽管这两种方法都与 i有很好的偏差,但是将这两种方法结合使用并不是很好。
以下是我个人不喜欢它的一个原因:
val2 = val + i % 1 val2 = val + ii % 2 val2 = val + 1i % 3
一个不会轻易被误解为两个或三个,而是两个和三个相似。
因此,我个人的建议是: 如果您有时使用复杂的代码,总是使用 1i结合不同的循环变量。
单字母索引的例子,如果你不使用很多循环变量和字母足够: t,u,k和 p
t
u
k
p
较长索引的示例: i_loop、 step、 walk和 t_now
i_loop
step
walk
t_now
当然,这也是一个个人品味的问题,但是不难找到一些有明确含义的索引来使用,而不会增长太长。
指出 1i是一种可以接受的、明确的 sqrt(-1)写法,因此没有必要避免使用 i。然而,作为 丹尼斯指出,很难看出 1i和 ii之间的区别。我的建议是: 尽可能使用 1j作为假想常数。这是电气工程师使用的同样的技巧-他们使用 j作为 sqrt(-1),因为 i已经被用于 sqrt(-1)0。
1j
就我个人而言,我从不使用 i和 j; 当我需要使用复数时,我使用 ii和 jj作为速记索引变量,(和 kk,ll,mm,...)和 1j。
在旧版本的 MATLAB 中,有一个很好的理由来避免使用 i和 j作为变量名——早期版本的 MATLAB JIT 不够聪明,不能分辨你是把它们当作变量还是想象单元使用,因此会关闭许多其他可能的优化。
因此,仅仅因为 i和 j作为变量的存在,您的代码就会变得更慢,如果您将它们更改为其他变量,代码就会变得更快。这就是为什么,如果您通读了很多 MathWorks 代码,您将看到 ii和 jj作为循环索引被相当广泛地使用。有一段时间,MathWorks 甚至可能非正式地建议人们自己编程(尽管他们总是正式地建议人们为优雅/可维护性编程,而不是按照当前 JIT 所做的任何事情编程,因为每个版本都是一个移动的目标)。
但那已经是很久以前的事了,现在有点像“僵尸”的问题,实际上没有许多人认为的那么重要,但他们拒绝死去。
在最近的任何版本中,是否使用 i和 j作为变量名实际上是个人偏好。如果你对复数做了大量的工作,你可能想要避免 i和 j作为变量,以避免任何小的潜在的混淆风险(虽然你可能也/相反地只想使用 1i或 1j为更少的混淆,和一点点更好的性能)。
另一方面,在我的典型工作中,我从不处理复数,而且如果我可以随意使用 i和 j作为循环索引,我会发现我的代码更具可读性。
我在这里看到了很多答案,说 不建议..。没有说谁在做这个推荐。下面是 MathWorks 从 i的当前发布文档中提出的实际建议的范围:
因为 i 是一个函数,所以它可以被重写并用作变量。但是,如果您打算在复杂的算术中使用变量名,最好避免使用 i 和 j。[ ... ]为了提高速度和鲁棒性,可以将复数 i 和 j 替换为1i。
这里已经很好地讨论了与虚单元的混淆,但是还有一些其他更平凡的原因,为什么有时不鼓励使用这些变量名和其他单字母变量名。
特别是 MATLAB: 如果您使用代码从您的 MATLAB 代码生成 C + + 源代码(不要,这是可怕的) ,那么您将被明确警告不要重用变量,因为潜在的类型冲突。
一般来说,根据 IDE 的不同,单个字母的变量名可能会对高亮显示器和搜索/替换造成严重破坏。MATLAB 没有遇到这个问题,而且我相信 Visual Studio 已经有一段时间没有遇到这个问题了,但是 C/C + + 编码标准,如 米斯拉等,倾向于反对它们。
就我而言,我避免所有的单字母变量,尽管直接实现数学资源有明显的优势。在开始的几百次中,你需要付出一些额外的努力,但是在那之后你就不会注意到了,当你或者其他可怜的人来读你的代码的时候,你会发现它的好处是很多的。
除非你是一个非常困惑的用户,我认为使用变量名 我和 J的风险很小,我经常使用它们。我没有看到任何官方的迹象表明这种做法应该避免。
尽管如其他文章中所提到的,在某些情况下,隐藏想象单元确实会引起一些混淆,但总的来说,我并不认为这是一个主要问题。在 MATLAB 中可以做更多令人困惑的事情,例如定义 false=true
false=true
在我看来,您唯一应该避免使用它们的时候是您的代码专门处理虚数的时候。
任何非平凡的代码都包含多个 for循环,最佳实践建议您使用一个描述性的名称来指示其用途和范围。自古以来(除非它的5-10行脚本我不打算保存) ,我一直使用变量名,如 idxTask,idxAnotherTask和 idxSubTask等。
for
idxTask
idxAnotherTask
idxSubTask
或者至少把数组的第一个字母加倍,比如 ss索引 subjectList,tt索引 taskList,但是不是 ii或者 jj,它们不能帮助我毫不费力地从我的多个 for 循环中识别出它们索引的是哪个数组。
ss
subjectList
tt
taskList