我需要向后移动一个数组,所以我有这样的代码:
for (int i = myArray.Length - 1; i >= 0; i--) { // Do something myArray[i] = 42; }
有没有更好的方法呢?
更新:我希望C#可能有一些内置机制,如:
foreachbackwards (int i in myArray) { // so easy }
更新2:有是更好的方法.符文获奖:
for (int i = myArray.Length; i-- > 0; ) { //do something } //or for (int i = myArray.Length; i --> 0; ) { // do something }
在常规C中看起来更好(感谢Twotymz):
for (int i = lengthOfArray; i--; ) { //do something }
小智.. 134
虽然可以肯定有点模糊,但我会说这样做的印刷最令人愉悦的方式是
for (int i = myArray.Length; i --> 0; ) { //do something }
当我第一次阅读你的答案时,看起来它甚至都不会编译,所以我认为你是一个疯狂的人.但这正是我所寻找的:一种更好的方式来编写一个向后循环. (29认同)
这太模糊和混淆了.我永远不会在生产代码中写这样的东西...... (24认同)
我发现它"印刷上令人困惑".对我来说," - "看起来不正确,除非它与它影响的变量相邻. (14认同)
啊[转到运营商( - >)](http://stackoverflow.com/questions/1642028/what-is-the-name-of-this-operator?lq=1)就可以了! (9认同)
我想我 - > 0; 是故意的.这就是他所说的"印刷上令人愉悦"的意思 (3认同)
这很可爱,但可爱≠很好的风格.任何减慢阅读速度的东西都是个坏主意.而且,它的输入不仅仅是`for(int i = myArray.Length; i - ;){...}`. (3认同)
Johannes Sch.. 115
在C++中,您基本上可以选择迭代使用迭代器或索引.根据您是否具有普通数组或a std::vector
,您使用不同的技术.
C++允许您使用 std::reverse_iterator:
for(std::vector::reverse_iterator it = v.rbegin(); it != v.rend(); ++it) { /* std::cout << *it; ... */ }
通过返回的无符号整型std::vector
是不是永远std::size_t
.它可以更大或更小.这对于循环工作至关重要.
for(std::vector::size_type i = someVector.size() - 1; i != (std::vector ::size_type) -1; i--) { /* std::cout << someVector[i]; ... */ }
它起作用,因为无符号整数类型值是通过模数来计算它们的位数.因此,如果你正在设置-N
,你最终会(2 ^ BIT_SIZE) -N
我们正在使用std::reverse_iterator
迭代.
for(std::reverse_iteratorit(a + sizeof a / sizeof *a), itb(a); it != itb; ++it) { /* std::cout << *it; .... */ }
我们可以安全地使用std::size_t
这里,而不是上面,因为sizeof
总是std::size_t
按定义返回.
for(std::size_t i = (sizeof a / sizeof *a) - 1; i != (std::size_t) -1; i--) { /* std::cout << a[i]; ... */ }
实际上上面确定阵列大小的方法很糟糕.如果a实际上是一个指针而不是一个数组(这经常发生,并且初学者会混淆它),它将无声地失败.更好的方法是使用以下命令,如果给出指针,它将在编译时失败:
templatechar (& array_size(T(&)[N]) )[N];
它的工作原理是首先获取传递的数组的大小,然后声明返回对相同大小的char类型数组的引用.char
被定义为具有sizeof
:1.因此返回的数组将具有sizeof
:N*1,这是我们正在寻找的,仅具有编译时评估和零运行时开销.
而不是做
(sizeof a / sizeof *a)
更改您的代码,以便它现在可以
(sizeof array_size(a))
是的,这是它的意图:) new int [7]返回一个指针.所以sizeof(new int [7])不返回7*sizeof(int),但会返回sizeof(int*).array_size导致该情况的编译错误,而不是静默工作. (2认同)
Jay Bazuzi.. 53
在C#中,使用Visual Studio 2005或更高版本,键入"forr"并单击[TAB] [TAB].这将扩展到一个for
向后循环通过集合的循环.
这很容易出错(至少对我来说),我认为把这个片段放在一个好主意.
也就是说,我喜欢Array.Reverse()
/ Enumerable.Reverse()
然后更好地迭代前进 - 他们更清楚地说明意图.
虽然可以肯定有点模糊,但我会说这样做的印刷最令人愉悦的方式是
for (int i = myArray.Length; i --> 0; ) { //do something }
在C++中,您基本上可以选择迭代使用迭代器或索引.根据您是否具有普通数组或a std::vector
,您使用不同的技术.
C++允许您使用 std::reverse_iterator:
for(std::vector::reverse_iterator it = v.rbegin(); it != v.rend(); ++it) { /* std::cout << *it; ... */ }
通过返回的无符号整型std::vector
是不是永远std::size_t
.它可以更大或更小.这对于循环工作至关重要.
for(std::vector::size_type i = someVector.size() - 1; i != (std::vector ::size_type) -1; i--) { /* std::cout << someVector[i]; ... */ }
它起作用,因为无符号整数类型值是通过模数来计算它们的位数.因此,如果你正在设置-N
,你最终会(2 ^ BIT_SIZE) -N
我们正在使用std::reverse_iterator
迭代.
for(std::reverse_iteratorit(a + sizeof a / sizeof *a), itb(a); it != itb; ++it) { /* std::cout << *it; .... */ }
我们可以安全地使用std::size_t
这里,而不是上面,因为sizeof
总是std::size_t
按定义返回.
for(std::size_t i = (sizeof a / sizeof *a) - 1; i != (std::size_t) -1; i--) { /* std::cout << a[i]; ... */ }
实际上上面确定阵列大小的方法很糟糕.如果a实际上是一个指针而不是一个数组(这经常发生,并且初学者会混淆它),它将无声地失败.更好的方法是使用以下命令,如果给出指针,它将在编译时失败:
templatechar (& array_size(T(&)[N]) )[N];
它的工作原理是首先获取传递的数组的大小,然后声明返回对相同大小的char类型数组的引用.char
被定义为具有sizeof
:1.因此返回的数组将具有sizeof
:N*1,这是我们正在寻找的,仅具有编译时评估和零运行时开销.
而不是做
(sizeof a / sizeof *a)
更改您的代码,以便它现在可以
(sizeof array_size(a))
在C#中,使用Visual Studio 2005或更高版本,键入"forr"并单击[TAB] [TAB].这将扩展到一个for
向后循环通过集合的循环.
这很容易出错(至少对我来说),我认为把这个片段放在一个好主意.
也就是说,我喜欢Array.Reverse()
/ Enumerable.Reverse()
然后更好地迭代前进 - 他们更清楚地说明意图.
我总是喜欢清晰的代码来反对' 印刷上令人愉悦 '的代码.因此,我会一直使用:
for (int i = myArray.Length - 1; i >= 0; i--) { // Do something ... }
您可以将其视为向后循环的标准方法.
只是我的两分钱......
在C#中使用Linq:
foreach(var item in myArray.Reverse()) { // do something }
对于任何长度为有符号整数类型的数组来说,这绝对是最好的方法.对于长度为无符号整数类型的数组(例如,std::vector
在C++中),则需要稍微修改结束条件:
for(size_t i = myArray.size() - 1; i != (size_t)-1; i--) // blah
如果你刚才说i >= 0
,对于无符号整数,这总是正确的,所以循环将是一个无限循环.