-
方法1的优点是文件大小稍小,因为源代码中的文本字符较小:
int i, j; for (i = 0; i < numRows; i++) for (j = 0; j < numCols; j++) //<some code here>
-
方法2的优点是局部变量的较小范围。
int i; for (i = 0; i < numRows; i++) { int j; for (j = 0; j < numCols; j++) //<some code here> }
即使在当今现代计算机中优化的差异可以忽略不计,哪种方法被认为是"更好"的代码?
编辑以澄清这个问题不是重复的:
这个问题基于当前的C11标准,该标准不允许这样的语法:
for (int i = 0; i < numRows; i++)
在C 和C99中,此语法是完全可以接受的,而C11不允许在for
语句中进行可变声明。
编辑以纠正错误信息:
我以为我正在使用C11,因为我最近从CodeBlocks下载了编译器,所以这就是为什么我说C11不允许for
语句中的可变声明。但事实证明,我实际上正在使用C90,这是我问题的根源。
纯紧凑和范围的限制,我会使用:
for (size_t i = 0; i < numRows; i++) {
for (size_t j = 0; j < numCols; j++) {
//<some code here>
}
}
请注意,size_t
的使用似乎是数组索引。size_t
类型是unsigned
整数类型,保证能够保留任何数组索引。只是一个时尚问题,但我还建议在所有环形车身周围使用牙套。这使您不可避免的更新和更改破坏代码的可能性要小得多。
通过养成像这样的块范围声明循环变量的习惯,您可以迫使自己选择使用代码其他位置中的循环变量中存储的值。
这似乎是一个品味问题,而不是有明确的答案,但我会给你我的意见:
给定当前的计算机,保存几个字符的源代码太微不足道,甚至无法考虑。实际上,我认为我会说,即使我在1976年在VAX 11/780上学习C时。
我会偏爱第二个示例,因为当前的偏好是将变量声明尽可能接近第一个使用。在C 中,您甚至可以将循环变量的声明放在for语句中:
for (int i = 0; i < numRows; i++) {
for (int j = 0; j < numCols; j++) {
...
}
}
但这仍然只是一个品味:如果变量的声明接近其使用,则该程序将更可读。
两个常见的编码指南是(1)确保不存在的变量比所需的多变量,并且(2)不要将变量用于多个因素。按照此类准则减少(通常但并非总是会消除)意外用法以不打算的方式使用变量,因此有助于避免细微的编程错误。
在您的第一种情况下,i
和j
都一直存在,直到封闭范围结束为止 - 这意味着它们在循环完成后存在。这最大化了后续代码(封闭范围)的机会,意外地使用i
或j
出于另一个目的(例如,目的是使用另一个变量)。这样的错误通常很难找到。
第二种情况有相同的问题,除了i
。不过,即使有一个问题的一个变量也是个坏消息。
我可能会使用
之类的构造// unintentionally using i or j here will cause a compilation error
for (int i = 0; i < numRows; i++)
{
// unintentionally using j here will cause a compilation error
for (int j = 0; j < numCols; j++)
{
//<some code here>
}
// unintentionally using j here will cause a compilation error
}
// unintentionally using i or j here will cause a compilation error
(我插入的评论使这重点使它更加不可读,但是在实践中通常不需要这样的评论)。
这确保了i
不存在j
在外循环外部。这也意味着j
不能在外循环中意外使用。实际上,当j
的意图(反之亦然)时,很容易键入i
- 例如,它们在QWERTY键盘上靠近。i
和j
在视觉上看起来也非常相似,因此视觉代码检查通常会错过此类错误。但是,使用这样的方法,编译器将检测到这种错别字。考虑到一个选择,最好让编译器收集错误,而不是让人类难以找到它们。
当然,这不能阻止内部循环中i
和j
的滥用或互换 - 但这是指南通常会鼓励使用比i
和j
更有用的名称的原因之一仅仅是致命的。
第二种方法是
的最佳方法- 它可以使用低内存
- 如果在任何其他循环中需要的话,请再次使用相同的变量