在C ++循环中查找数组的结尾?

问题描述 投票:2回答:6

我想区分数组的结尾和其余元素(在for循环中),但是大多数示例在循环外部初始化变量,我认为这会使循环变得混乱。我实现的最短的例子是通过查看基于范围的for循环中的指针地址:

for(auto& x : arr){
    cout << x;
    if(&x != &*end(arr)-1)
        cout << ", ";
}

这不需要额外的变量,但我不能100%确定在C ++中使用指针的含义。

一个更多(或更少?)可读的例子,我在for-statement中初始化一个变量,看起来非常直观(编辑不提供对函数的可移植性):

for(int i{0}, len{sizeof(arr)/sizeof(*arr)}; i<l; i++){
    cout << arr[i];
    if(i!=len-1)
        cout << ", ";
}
  • 没有额外的包含,是否有更可读/更好/更短的方式来做到这一点?
  • 这些方法有任何缺点吗?
c++ arrays
6个回答
3
投票

为什么不这样做呢?

bool not_first_item = false;

for(auto x : arr){
    if (not_first_item) {
       cout << ", ";
       not_first_item = true;
    }
    cout << x;
}

除了第一个项目之外,它将在每个项目之前打印一个逗号。它将获得您需要的结果,而无需使用复杂的指针。


1
投票

如果只有一个指向数组中元素的指针,则没有可移植的方法来检测数组中该元素的位置。

备择方案;最好的第一:

  1. 使用std::vector。它具有与普通旧数组类似的语义,并具有携带大小的好处。
  2. 使用size_t类型将数组的大小作为附加参数传递。
  3. 使用魔术值表示数组的结尾。

请注意,使用&x是没有意义的,因为x是一个值副本。考虑auto& x而不是?


1
投票

这可能有所帮助

l=sizeof(arr)
for(int i{0}; i<l-1; i++){
    cout << arr[i];
    cout << ", ";
}
cout << arr[sizeof(arr)];

要么

 for(int i{0}; i<sizeof(arr)-1; i++){
        cout << arr[i];
        cout << ", ";
 }
 cout << arr[sizeof(arr)];

没有额外的条件。如果显示是主要意图


1
投票

我喜欢的简洁方式,没有额外的分支:

const char* sep = "";
for (const auto& x : arr) {
    std::cout << sep << x;
    sep = ", ";
}

是的,它使用额外的变量。


0
投票

作为一般规则,您不应丢弃所需的信息。当您使用基于范围的for循环时,您将抽象出容器中元素的位置(实际上是容器的形式)。因此,它不是最适合这项工作的工具。您可以使用索引或迭代器执行此操作,因为这些信息包含足够的信息,以告知您迭代的元素是否是最后一个元素。

标准库提供了两个有用的函数beginend,它们可以调用STL容器的成员函数beginend,也可以指向C样式数组的第一个和过去元素的指针。由于检查结束条件的方式,除了前向迭代器之外,您不需要任何其他内容。

assert(std::begin(arr) != std::end(arr));
for (auto it = std::begin(arr); it + 1 != std::end(arr); ++it) {
    std::cout << *it << ", ";
}
std::cout << *(std::end(arr) - 1) << '\n';

如果你知道你永远不会尝试打印空容器,上面的代码就可以了。否则,您需要额外的if声明来检查。请注意,即使您有一个随机访问迭代器并使用条件it < std::end(arr) - 1,您可能会认为它对于空数组也没问题,但它是未定义的行为,并且在启用优化时可能会导致一些意外错误。


0
投票

不是100%肯定我在寻找什么,但我认为真正的答案可能是检查像@ed_heel提议的起始项目,但我真的只需要改变我在基于范围的for循环中检查的内容它更整洁:

for(auto &x : arr)
{
    cout << (&x == arr ? "" : ", ") << x;
}

因为arr是一个数组(伪装的a.k.a.指针)。

© www.soinside.com 2019 - 2024. All rights reserved.