【问题标题】:Cout a whole array in c++在 C++ 中计算整个数组
【发布时间】:2016-01-31 01:27:14
【问题描述】:

我对 c++ 还很陌生,在 c++ 中有没有一种方法,除了通过 for 循环进行迭代之外,我们还可以计算出整个静态数组吗?

int arra[10] = {1,2,3,4};
std::cout << arra << std::endl;

我试过了,但这是数组中第一个元素的打印地址。

【问题讨论】:

标签: c++ c++11 visual-c++


【解决方案1】:

以下不使用(明确)循环:

std::copy(std::begin(arra),
          std::end(arra),
          std::ostream_iterator<int>(std::cout, "\n"));

但循环似乎更容易读/写/理解:

for (const auto& e : arra) {
    std::cout << e << std::endl;
}

【讨论】:

  • 是的,第二个在所有方面都胜出 :) (至少在 C++11 可用时)
  • @Antonio:就目前而言,第一个也需要 C++11(C++03 没有 std::beginstd::end,尽管您可以自己编写类似物)。
  • @JerryCoffin 是的,但我(个人)看到在第二个版本中更突出地删除 C++11 所暗示的开销。
  • @Antonio:很公平。我确实期待一个带有 Ranges 的标准库——最好是带有构造函数的标准库,它可以让第一个变成类似:std::copy(arra, {std::cout, "\n"});。现在我想起来了,我很想看看 1) Eric Neibler 的库现在是否支持它,以及 2) 如果支持,请弄清楚我是否可以让它工作。
  • 你不想也不需要std::endl这里;如果行缓冲,则无论如何都会在每行之后刷新 iostream 缓冲区,如果不是,则对性能非常不利。
【解决方案2】:
#include<iostream>        
using namespace std;

int main(){ 诠释我;

int myarr[5]={9,84,7,55,6};
for(i=0;i<5;i++){

    cout<<myarr[i]<<endl;
}

}

【讨论】:

  • 欢迎来到stackoverflow!请务必在发布答案之前仔细阅读问题,OP 明确要求提供一种不使用 for 循环的方法。
【解决方案3】:

您将如何访问数组的每个元素以显示内容。这可以长形式或使用循环来完成。幸运的是,我们可以使用std::copy 来定义循环并显示数组。

int arr[] = {1,2,3,4,5};
std::copy(std::begin(arr), std::end(arr), std::ostream_iterator<int>(std::cout, " "));

Live Example

【讨论】:

  • 这是你在现实生活中会做的事情吗? std::copy 到 ostream_iterator?
  • @SergeyA 是的,我经常使用这个成语进行调试(参见例如this answer
  • @SergeyA 是的。它没有任何问题,它属于现代 C++ 的算法风格。
【解决方案4】:

你需要遍历数组

int arra[10] = {1,2,3,4};
for (int i = 0; i<sizeof(arra)/sizeof(arra[0]); ++i)
{
    std::cout << arra[i] << std::endl;
}

或使用

std::copy(std::begin(arra), std::end(arra), std::ostream_iterator<int>(std::cout,"\n"));

【讨论】:

  • 有一种方法可以不使用循环。
  • 重复“10”是非常危险的(考虑第一次数组的大小会改变),我宁愿选择std::end(arra) 之类的东西,或者至少将数组大小定义为常数
【解决方案5】:

当您要求在没有数组的情况下执行此操作时,您可以轻松地执行此操作:

std::copy(arra, arra + 10,
            std::ostream_iterator<int>(cout, "\n"));

如果你想写出好的代码,你可以使用 std::array 然后简单地写arra.begin()arra.end()

【讨论】:

  • 它在库中的隐式循环中。此外,OP 也可以将 beginend 与内置数组一起使用。
  • 使用+10意味着找麻烦。首选std::end(arra)
【解决方案6】:

基本上有两种方式。第一个是某处的循环。循环可以是显式的 - 在您的代码中 - 或者它可以通过库是隐式的。库循环示例:

std::for_each(cbegin(arra), cend(arra), [](int i) {std::cout << "i ";});

第二种打印数组的方法是使用递归。以下是代码示例:

void print_element(const int* head, const int* tail) {
    if (head == tail)
       return;

    std::cout << *head << " ";
    print_element(head + 1, tail);
}

....
print_element(arr, arr + sizeof(arr) / sizeof(*arr));

关于递归解决方案的几句话。根据您的优化,它可以产生不同的结果。递归的性能将大致等同于 AMD64 ABI 在任何优化级别上的循环性能。这样做的原因是函数的参数是通过寄存器传递的(而不是压入堆栈),并且帧指针不用于任何优化。考虑到这一点,与循环相比,唯一的 CALL/RET(推送/弹出 RIP)会减慢执行速度,但这种退化是不可测量的。然而,真正的问题是,可以在给定系统上进行的递归调用数量有限(通常约为数千个),因此打印一个包含 1000000 个元素的数组肯定会导致应用程序崩溃。

随着涉及尾调用优化的更高级别的优化,递归调用将被转换为纯 jmps,性能将与循环调用完全相同。它还将消除最大递归级别的问题 - 以便可以打印任何大小的数组。

【讨论】:

    【解决方案7】:

    这是打印地址,因为您指向的是一个数组,而不是它的元素。 试试这个-

    void printArray(int arr[], int n) 
    
    /* n is size here*/
    
    { 
        for (int i = 0; i < n; i++) 
    
            cout << arr[i] << " "; 
        } 
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2016-05-06
      • 1970-01-01
      • 1970-01-01
      • 2017-09-20
      相关资源
      最近更新 更多