c++ for循环结构

C++ for loop structure

本文关键字:结构 循环 for c++      更新时间:2023-10-16

希望这不是一个蹩脚的问题,但我必须问这个:)

当我用c++编程并使用for循环时,我给出的参数为

for(int i = 0; i< something; i++)

这是正确的前进方式,但是…这会给我编译警告,例如:

1>c:main.cpp(185): warning C4018: '<' : signed/unsigned mismatch 

现在通过书籍和在线阅读大多数for循环的例子都是这种结构。

我总是忽略警告,因为我的程序总是工作并做他们应该做的事情,直到我对这个警告感兴趣并做了一个小研究....通过复制这个警告并谷歌它,发现最好使用这个结构来避免警告:

for(vector<int>::size_type i= 0; i < something; i++ )

现在我的问题是为什么......如果初始结构有效,并且在许多书籍和在线资源中描述和记录。

在技术上有什么好处或者有什么显著的不同.....?

为什么我要用这个

for(vector<int>::size_type i= 0; i < something; i++ )

除了摆脱警告.....?

不要忽视警告。他们想告诉你一些事情。

我怀疑something是unsigned.

如果你有

unsigned int something = 0;
something--;  // Now something is a really large positive integer, not -1

如果您忽略警告,并且您没有将编译器设置为将警告视为错误,那么这将编译得很好,但您不会得到您期望的结果。

如果警告消失,您可能会看到vector<int>::size_typeunsigned int

您的语句中i的类型与something的类型之间存在signed/unsigned不匹配:

for(int i = 0; i < something; i++)

所以这与for结构无关,而是与比较有关。

bool b = i < something;

也会给出同样的警告。

如果您使用int i并将其与size_t变量进行比较(这就是std::vector::size()给您的),则可能出现这种情况。

因此,要解决这个问题,只需将for循环更改为isomething使用相同的类型,例如:
for(size_t i = 0; i < something; i++)
如果something的类型是size_t

为什么我要用这个

因为signed int和像size_t这样的无符号值有不同的范围,如果其中一个包含一个不能被另一个表示的值,你可能得不到预期的结果。

也就是说,如果你认为代码太啰嗦,你不必使用它。

代码如下:

for(vector<int>::size_type i= 0; i < myvector.size(); i++ )
{
    int val = myvector[i];

也可以这样写。

for ( int val : myvector )

一般来说,c++中有两种整型:有符号无符号。对于每一个大小的整数,都有一个有符号的和一个无符号的版本。不同之处在于它们的取值范围:n位的有符号整数的取值范围从& -;2n & -; 1到+2n & -; 1 & -; 1;n & -; 1.

当将有符号整数类型与无符号整数类型进行比较时,有符号值转换为无符号值;负值将包裹,并被视为较大的正值。这样做的结果是,与<的比较可能不会达到您期望的效果,因此许多编译器会对此类比较发出警告。

例如,1u < -1为true。u是一个后缀,告诉编译器将1作为unsigned int的值来处理。

这样,含义就清楚了:int是有符号类型,vector<T>::size_type是无符号类型。由于vector<T>::size()的结果是vector<T>::size_type,您希望使用它或其他无符号类型(如size_t)来确保您的比较具有您想要的行为。

除了使用索引,还可以使用迭代器,它不会有这样的转换问题:

for (vector<int>::iterator i = v.begin(); i != v.end(); ++i)
    cout << *i << 'n';

可以用c++ 11中的auto更简洁:

for (auto i = v.begin(); i != v.end(); ++i)
    cout << *i << 'n';

如果你只是在整个容器上迭代,使用c++ 11基于范围的for:

for (int i : v)
    cout << i << 'n';

如果你想修改值,使用引用:

for (int& i : v)
    ++i;

something必须是int,否则会收到警告。或者i必须是unsigned int,这取决于您的需要。
假设是32位整数,如果0x7FFFFFFF (2,147,483,647 decimal)以上的任何符号值将被解释为负,而unsigned int将被解释为正。

编译器发出一个警告,告诉你比较邮件会导致意想不到的结果。

32 bits integers range from −2,147,483,648 to 2,147,483,647.
32 bits unsigned integers range from 0 to 4,294,967,295