正确的循环通过C ++数组的方式

时间:2013-11-27 05:51:51

标签: c++ arrays loops c++11

最近我发现了很多例子,其中大多数都是关于C ++ 98的,反正我已经创建了我的简单数组和循环(codepad):

#include <iostream>
using namespace std;

int main ()
{
   string texts[] = {"Apple", "Banana", "Orange"};
   for( unsigned int a = 0; a < sizeof(texts); a = a + 1 )
   {
       cout << "value of a: " << texts[a] << endl;
   }

   return 0;
}

输出:

value of a: Apple
value of a: Banana
value of a: Orange

Segmentation fault

除了最后的分段错误外,它工作正常。

我的问题是,这个数组/循环是否是一个好方法?我正在使用C ++ 11,所以我想确保它符合标准并且无法以更好的方式完成?

9 个答案:

答案 0 :(得分:71)

在C / C ++中sizeof。始终给出整个对象中的字节数,并将数组视为一个对象。注意:sizeof一个指针 - 指向数组的第一个元素或单个对象 - 给出指针的大小,而不是指向的对象。无论哪种方式,sizeof 都会给出数组中元素的数量(长度)。要获得长度,您需要除以每个元素的大小。例如,

for( unsigned int a = 0; a < sizeof(texts)/sizeof(texts[0]); a = a + 1 )

至于使用C ++ 11方式,最好的方法可能是

for(const string &text : texts)
    cout << "value of text: " << text << endl;

这让编译器可以计算出你需要多少次迭代。

编辑:正如其他人所指出的那样,{+ 1}}在C ++ 11中优于原始数组;但是,没有其他答案解决了为什么std::array失败的原因,所以我仍然认为这是更好的答案。

答案 1 :(得分:16)

string texts[] = {"Apple", "Banana", "Orange"};
for( unsigned int a = 0; a < sizeof(texts); a = a + 1 )
{
    cout << "value of a: " << texts[a] << endl;
}

不。完全是一种迭代数组的错误方法。 sizeof(texts)不等于数组中元素的数量!

现代的C ++ 11方式是:

  • 如果你想要一个在编译时已知大小的数组,请使用std::array;或
  • 如果std::vector的大小取决于运行时间,则使用#include <iostream> #include <array> int main() { std::array<std::string, 3> texts = {"Apple", "Banana", "Orange"}; // ^ An array of 3 elements with the type std::string for(const auto& text : texts) { // Range-for! std::cout << text << std::endl; } }

然后在迭代时使用range-for。

std::array

Live example


您可能会问,std::vector如何比ol'C数组更好?答案是它具有其他标准库容器的额外安全性和功能,大多与std::begin/end非常相似。此外,答案是它不具有衰减到指针的怪癖,从而丢失类型信息,一旦丢失原始数组类型,就不能在其上使用range-for或{{1}}。

答案 2 :(得分:8)

sizeof告诉你事物的大小,而不是它中的元素数量。更多的C ++ 11方法来做你正在做的事情:

#include <array>
#include <string>
#include <iostream>

int main()
{
    std::array<std::string, 3> texts { "Apple", "Banana", "Orange" };
    for (auto& text : texts) {
        std::cout << text << '\n';
    }
    return 0;
}

ideone demo:http://ideone.com/6xmSrn

答案 3 :(得分:1)

我系统上的

sizeof(texts)评估为96:数组及其字符串实例所需的字节数。

如其他地方所述,sizeof(texts)/sizeof(texts[0])会给出您期望的值3。

答案 4 :(得分:1)

为数组添加一个停止值:

#include <iostream>
using namespace std;

int main ()
{
   string texts[] = {"Apple", "Banana", "Orange", ""};
   for( unsigned int a = 0; texts[a].length(); a = a + 1 )
   {
       cout << "value of a: " << texts[a] << endl;
   }

   return 0;
}

答案 5 :(得分:1)

如果你有一个非常简短的元素列表,你可以使用C ++ 11中引入的std::initializer_list和auto:

#include <iostream>

int main(int, char*[])
{
    for(const auto& ext : { ".slice", ".socket", ".service", ".target" })
        std::cout << "Handling *" << ext << " systemd files" << std::endl;

    return 0;
}

答案 6 :(得分:1)

您需要了解std :: array :: size和sizeof()运算符之间的区别。如果您想循环以常规方式排列元素,则可以使用std :: array :: size。这将返回数组中的元素数量,但是如果您热衷于使用C ++ 11,则更喜欢下面的代码

for(const string &text : texts)
    cout << "value of text: " << text << endl;

答案 7 :(得分:0)

怎么样:

username@prepatcher-oel7 impala-crypto-udf-master $ make
[ 50%] Building CXX object CMakeFiles/udfcrypto.dir/udf-crypto.cc.o
In file included from /home/username/impala-crypto-udf-master/udf-crypto.cc:27:0:
/home/username/impala-crypto-udf-master/sm3.h:23:24: error: expected unqualified-id before numeric constant
class BOTAN_PUBLIC_API(2,2) SM3 final : public MDx_HashFunction
                        ^
/home/username/impala-crypto-udf-master/sm3.h:23:24: error: expected ‘)’ before numeric constant
/home/username/impala-crypto-udf-master/udf-crypto.cc:2133:1: error: expected ‘}’ at end of input
}
^
make[2]: *** [CMakeFiles/udfcrypto.dir/udf-crypto.cc.o] Error 1
make[1]: *** [CMakeFiles/udfcrypto.dir/all] Error 2
make: *** [all] Error 2

编译并与C ++ 11一起使用,并且没有“原始”循环:)

答案 8 :(得分:-1)

您可以按照以下步骤进行操作:

#include < iostream >

using namespace std;

int main () {

   string texts[] = {"Apple", "Banana", "Orange"};

   for( unsigned int a = 0; a < sizeof(texts) / 32; a++ ) { // 32 is the size of string data type

       cout << "value of a: " << texts[a] << endl;

   }


   return 0;

}