C ++ for循环结构

时间:2013-04-01 22:17:45

标签: c++

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

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

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

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

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

现在浏览书籍并在线阅读最多的循环示例就是这种结构。

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

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

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

这些技术的好处还是有什么显着差异.....?

我为什么要用这个

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

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

5 个答案:

答案 0 :(得分:4)

不要忽略警告。他们试图告诉你一件事。

我怀疑something是无符号的。

如果你有

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

如果忽略警告,并且没有将编译器设置为将警告视为错误,那么这将编译正常,但您将无法获得预期的结果。

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

答案 1 :(得分:3)

您的陈述中signed的类型与unsigned的类型之间只有i / something不匹配:

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

答案 2 :(得分:3)

从广义上讲,C ++中有两种整数类型: signed unsigned 。对于每个大小的整数,都有一个有符号和无符号的版本。区别在于它们的范围: 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()的结果为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;

答案 3 :(得分:3)

  

我为什么要用这个

由于signed int和无符号值(如size_t)具有不同的范围,如果某个值包含无法用另一个值表示的值,则可能无法获得预期结果。

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

这样的代码:

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

也可以这样写。

for ( int val : myvector )

答案 4 :(得分:1)

something必须为int,否则会收到警告。或i必须为unsigned int,具体取决于您的需求。
假设一个32位整数,如果签名任何高于0x7FFFFFFF2,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