C++ 带有size\u t循环变量的反向循环

C++ 带有size\u t循环变量的反向循环,c++,C++,以下是代码定义的行为,我的意思是,当I为0时,将始终是最大的无符号int,可以用size\u t表示,对吗?那么在我的代码中使用它是完全安全的吗 size_t NPOS = -1; for(size_t i = vec.size()-1; i!= NPOS; i--) 对于给定的整数类型T,所有这些值都是相同的,有符号或无符号: T a = -1; T b = 0 - 1; T c = 0; c = c - 1; T d = 0; d --; T e = 0; -- e; assert(a

以下是代码定义的行为,我的意思是,当I为0时,将始终是最大的无符号int,可以用size\u t表示,对吗?那么在我的代码中使用它是完全安全的吗

size_t NPOS = -1;
for(size_t i = vec.size()-1; i!= NPOS; i--)

对于给定的整数类型
T
,所有这些值都是相同的,有符号或无符号:

T a = -1;
T b = 0 - 1;
T c = 0; c = c - 1;
T d = 0; d --;
T e = 0; -- e;

assert(a == b);
assert(a == c);
assert(a == d);
assert(a == e);

这涵盖了代码片段中的所有用法。整数的内部表示形式并不重要。有符号-1转换为类似无符号整数的最大值这一事实很有趣,但并不直接重要。以上是正确的,否则算术将停止工作。

对于给定的整数类型
T
,有符号或无符号,所有这些值都将是相同的值:

T a = -1;
T b = 0 - 1;
T c = 0; c = c - 1;
T d = 0; d --;
T e = 0; -- e;

assert(a == b);
assert(a == c);
assert(a == d);
assert(a == e);

这涵盖了代码片段中的所有用法。整数的内部表示形式并不重要。有符号-1转换为类似无符号整数的最大值这一事实很有趣,但并不直接重要。以上是正确的,否则算术将停止工作。

在class
std::basic_string
静态数据成员
npos
中定义如下

static const size_type npos = -1;
for ( std::vector<T>::size_type i = vec.size(); i != 0;  )
{
   //...
   // using expression vec[--i]
   // or
   //  --i
   // vec[i]
   //...
} 
考虑到成员函数
size()
的返回值类型是
size\u type
。所以你的代码是有效的

size_t NPOS = -1;
for(size_t i = vec.size()-1; i!= NPOS; i--)
前提是表达式
vec.size()-1
的值可以存储在类型
size\u t

因此,更有效的代码如下所示

for ( std::vector<T>::size_type i = vec.size()-1; i != std::vector<T>::npos; i-- )
for(std::vector::size_type i=vec.size()-1;i!=std::vector::npos;i--)
虽然我会用下面的方法编写循环

static const size_type npos = -1;
for ( std::vector<T>::size_type i = vec.size(); i != 0;  )
{
   //...
   // using expression vec[--i]
   // or
   //  --i
   // vec[i]
   //...
} 
for(std::vector::size_type i=vec.size();i!=0;)
{
//...
//使用表达式vec[--i]
//或
//--我
//vec[i]
//...
} 

类中的
std::basic_string
静态数据成员
npos
定义如下

static const size_type npos = -1;
for ( std::vector<T>::size_type i = vec.size(); i != 0;  )
{
   //...
   // using expression vec[--i]
   // or
   //  --i
   // vec[i]
   //...
} 
考虑到成员函数
size()
的返回值类型是
size\u type
。所以你的代码是有效的

size_t NPOS = -1;
for(size_t i = vec.size()-1; i!= NPOS; i--)
前提是表达式
vec.size()-1
的值可以存储在类型
size\u t

因此,更有效的代码如下所示

for ( std::vector<T>::size_type i = vec.size()-1; i != std::vector<T>::npos; i-- )
for(std::vector::size_type i=vec.size()-1;i!=std::vector::npos;i--)
虽然我会用下面的方法编写循环

static const size_type npos = -1;
for ( std::vector<T>::size_type i = vec.size(); i != 0;  )
{
   //...
   // using expression vec[--i]
   // or
   //  --i
   // vec[i]
   //...
} 
for(std::vector::size_type i=vec.size();i!=0;)
{
//...
//使用表达式vec[--i]
//或
//--我
//vec[i]
//...
} 

从技术上讲,它是有效的,因为将
-1
转换为 无符号类型保证产生尽可能大的 值,从
0开始递减。不过,这不是什么
我会考虑好的练习。如果你只是想迭代
在一个向量上反向:

for ( auto current = vec.rbegin(); current != vec.rend(); ++ current ) {
    //      Do something with *current
}
如果出于某种原因,您确实需要索引:

int i = vec.size();
while ( i != 0 ) {
    -- i;
    //      Do something with vec[i]
}
这个循环更干净,避免了任何未签名的问题 类型包装(尽管如果需要索引,可能 意味着您需要它作为算术值,因此您应该避免
从技术上讲,它是有效的,因为将
-1
转换为 无符号类型保证产生尽可能大的 值,从
0开始递减。不过,这不是什么
我会考虑好的练习。如果你只是想迭代
在一个向量上反向:

for ( auto current = vec.rbegin(); current != vec.rend(); ++ current ) {
    //      Do something with *current
}
如果出于某种原因,您确实需要索引:

int i = vec.size();
while ( i != 0 ) {
    -- i;
    //      Do something with vec[i]
}
这个循环更干净,避免了任何未签名的问题 类型包装(尽管如果需要索引,可能 意味着您需要它作为算术值,因此您应该避免
首先是未签名的类型。

这是使用Fableus goes to运算符的经典场景:

for (size_t i = vec.size(); i --> 0; )

这是一个经典的场景,用于使用精彩的goes-to操作符:

for (size_t i = vec.size(); i --> 0; )

如果您的平台使用2的补码来表示有符号整数,那么是的。@heinrichj,它还必须在1的补码中工作。参见C++11§4.7[转换积分]/2。也可能会引起一些兴趣。请改用
i-->0
:您知道vector有反向迭代器来执行此操作吗?@dalle为什么?要混淆,或者?如果您的平台使用2的补码来表示有符号整数,是的。@heinrichj,它还必须在1的补码中工作。参见C++11§4.7[转换积分]/2。也可能会引起一些兴趣。请改用
i-->0
:您知道vector有反向迭代器来执行此操作吗?@dalle为什么?混淆,还是?