4

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

当我在 C++ 中编程并使用for循环时,我给出的参数是

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

这是正确的前进方向,但是..这给了我编译警告,例如:

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

现在浏览书籍和在线阅读大多数for循环示例都是这种结构。

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

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

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

还有什么好处或技术上有什么显着差异.....?

我为什么要用这个

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

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

4

5 回答 5

4

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

我怀疑something是未签名的。

如果你有

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

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

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

于 2013-04-01T22:29:13.017 回答
3

您的语句中的类型和类型之间只是signed/unsigned不匹配:isomething

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

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

bool b = i < something;

会给你同样的警告。

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

因此,要修复它,只需将for循环更改为使用相同类型的 fori和 for something,例如:

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

ifsomething是类型size_t

于 2013-04-01T22:29:46.713 回答
3

从广义上讲,C++ 中有两种整数类型:有符号无符号。对于每个大小的整数,都有一个有符号和无符号版本。不同之处在于它们的范围:n位的有符号整数的范围为 -2 n - 1到 +2 n - 1  - 1;无符号整数,从 0 到 2 n  - 1。

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

例如,1u < -1是真的。u是一个后缀,告诉编译器将1视为一个unsigned int值。

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

除了使用索引,您还可以使用不存在此类转换问题的迭代器:

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

auto在 C++11 中可以更简洁:

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

如果您只是迭代整个容器,请使用 C++11 range-based for

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

如果要修改值,请使用参考:

for (int& i : v)
    ++i;
于 2013-04-01T22:30:56.580 回答
3

我为什么要用这个

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

也就是说,如果您认为代码过于冗长,则不必使用它。

像这样的代码:

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

也可以这样写。

for ( int val : myvector )
于 2013-04-01T22:31:39.193 回答
1

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
于 2013-04-01T22:29:55.483 回答