C# while(k>;=0&;arr[k]>;0)安全吗?
是 安全吗 当k在范围内且arr[k]>0时,它会循环。但我不知道这是否是一个好的编码实践。我知道如果我们这样做C# while(k>;=0&;arr[k]>;0)安全吗?,c#,coding-style,C#,Coding Style,是 安全吗 当k在范围内且arr[k]>0时,它会循环。但我不知道这是否是一个好的编码实践。我知道如果我们这样做 while (k >= 0 && arr[k] > 0) 这将是一场灾难。是的,这是一个很好的做法。事实上,这就是短路&&操作符被发明的部分原因。运算符从左到右计算其子表达式,并在发现错误的子表达式时停止。这正是你想要的;&&运算符允许您在一行中表示这一点。短路是安全的。如果k小于零,它将不会索引到arr while循环的主体可能不会正确地减小k,从而
while (k >= 0 && arr[k] > 0)
这将是一场灾难。是的,这是一个很好的做法。事实上,这就是短路
&&
操作符被发明的部分原因。运算符从左到右计算其子表达式,并在发现错误的子表达式时停止。这正是你想要的;&&
运算符允许您在一行中表示这一点。短路是安全的。如果k
小于零,它将不会索引到arr
while循环的主体可能不会正确地减小
k
,从而导致无限循环,这可能不安全。或者,如果k
超出arr
的界限,则可能不安全。您还应注意数组大小:
while (arr[k] > 0 && k >= 0)
while(k>=0&&k0)
将是更安全的代码。关于表达式: 而(k>=0&&arr[k]>0{…} 不,它不安全。 表达式
k>=0&&arr[k]>0
是安全的,它确保只使用arr[k]
的正指数(因为和&
缩短了k<0
的值,并且在这些情况下不计算第二个操作数arr[k]>0
)
但是请注意,不能保证索引超出范围(例如,k>=arr.length
)-并且arr也可以是null
。因此,您可以获得索引自动失效异常
或NullReferenceException
——如果未经处理,您的应用程序将中断
要避免这种情况,请使用
while (k >= 0 && k < arr.length && arr[k] > 0)
请注意,因为您不是从0开始的,所以我跳过了初始化var k=0
,我假设您是在上面的源代码之外的某个地方完成的
除此之外,还有一些附加信息-如果您想了解有关逻辑运算符和副作用的一些有趣细节,请继续阅读 在C/C++/C#中,了解
&
与&
和
与
之间的区别非常重要:&
和
以“位”方式计算整个表达式,而&
和
如果结果已经清楚,则停止计算(如果表达式的任何部分为假
,则逻辑和
不能为真
;如果表达式的任何部分为真
,则逻辑或
不能为假
)
在某些情况下但是,您也需要非快捷方式版本&
。假设您希望将字符串数组转换为整数数组,并且希望转换可以转换的每个值,即使某些值无法转换为整数(其他值应保持为0)-如以下示例所示:
if (k >=0 && arr != null)
for (; var k=0; k<arr.Length && arr[k] > 0; k++) { ... }
这不是我们所期望的,因为10和11也是有效的整数,应该进行转换,相反,我们得到了0和0
为了得到我们期望的结果,即
4 2 0 0 0 0
我们需要将&
替换为&
,如下所示:
4 2 0 0 10 11
这里有什么区别?
如果您在上面的语句中使用了&&
,那么只要bCheck的计算结果为false,就会执行快捷方式-这通常是正确的,因为这样我们就不必再检查表达式,因为它不可能被计算为true
但是,由于我们有了快捷方式,int.TryParse
不再被调用,因此值不会从函数中传递出去-无论sArr[i]
中包含的值如何,循环中的所有后续调用都将计算为0
这是我们在这里遇到的意外副作用,可以通过强制计算每个表达式(通过使用
&
)来修复.除非您说明如何更改k
,否则无法说明它是否安全。此外,在多线程场景中,答案会有很大差异。在这种格式下,您不能使用for循环吗?for(int k=20;arr.Length>k&&arr[k]>0;k--)也可以考虑可读性。它可以为你节省几行代码,但是一个更年轻的开发人员花了多少时间来弄清楚这是怎么做的……唯一安全可靠的是,如果第一个条件,<代码> k>=0 < /代码>评估为<代码> false <代码>,那么就不会尝试评估第二个条件。因此,arr[k]
不会因为负的k
而爆炸。当然,它可能会因为其他原因出错。顺便说一句,您是否考虑过LINQ?声明式地处理集合往往不那么麻烦。SkipWhile
和Take
可能会有帮助:
4 2 0 0 0 0
4 2 0 0 10 11
bCheck = bCheck & int.TryParse(sArr[i], out value);