【问题标题】:How to fix for each loop in C++?如何修复 C++ 中的每个循环?
【发布时间】:2019-08-07 17:45:30
【问题描述】:

我目前正在尝试编写一个函数,该函数将在 C++ 中找到整数数组中元素的平均值。

我查看了new c++11 for loop causes: "error: ‘begin’ was not declared in this scope",但我不太明白这个问题以及如何解决它。

double avg(int arr[]) {
    double sum = 0;
    int size = 0;
    for (int i : arr) {
        sum += i;
        size += 1;
    }
    return sum / size;
}

它给我的错误是“'begin' 没有在这个范围内声明”和“'end' 没有在这个范围内声明”。 有人可以解释为什么会发生错误以及可能的解决方法吗?

【问题讨论】:

  • for (int i : arr) { 问题是 arr 的大小未知。它衰减成一个指针。
  • 您的数组没有大小,因此每个数组都无法工作,请改用std::vectorstd::array
  • 你是arr decaying to a pointer的受害者。
  • 使用std::array<int>,而不是愚蠢的常规数组。那么你就不会遇到现在看到的问题了。
  • 避免使用原始 C 样式数组。使用std::arraystd::vector 总是

标签: c++


【解决方案1】:

int arr[] 类型衰减为原始指针,因此无法获取它所引用的数组的大小。

与其使用原始数组,不如使用std::vector

double avg(std::vector<int> const& v) {
    double sum = 0;
    for(int i : v) 
        sum += i;
    return sum / v.size();
}

std::array,它的作用类似于 C 数组,但可复制且不会衰减为指针:

template<size_t N>
double avg(std::array<int, N> const& arr) {
    double sum = 0;
    for(int i : arr) {
        sum += i;
    return sum / N;
}

或者,如果您确实必须使用数组,请将大小作为参数传递:

double avg(int arr[], size_t size) {
    double sum = 0;
    for(int i = 0; i < size; i++) {
        sum += arr[i];
    }
    return sum / size;
}

利用 C++ 标准库

C++ 标准库有很多有用的函数,其中之一,accumulate,完美地完成了这项工作。它需要一个开始和结束迭代器,以及初始值,并计算范围内的总和:

#include <numeric>

double avg(std::vector<int> const& v) {
    return std::accumulate(v.begin(), v.end(), 0.0) / v.size();
}

double avg(int[] arr, size_t size) {
    return std::accumulate(arr + 0, arr + size, 0.0) / size;
}

【讨论】:

  • “如果你想变得花哨,你也可以使用 库” - 我不会称之为“变得花哨”,我会称之为“变得明智”。
  • 我认为你是对的。我更新了帖子以更好地解释和介绍accumulate
  • 如果向量为空怎么办?糟糕,除以 0。
  • 这将产生一个 NaN 值,我认为对于一个取空列表平均值的函数来说,这是一个可接受的返回值
  • 您可以使用 C++20 中的 std::span 代替 c-array 和大小(或使用反向端口)
【解决方案2】:

函数不能将数组作为参数。你在那里得到一个指针。尽管您可以将对数组的引用作为参数传递给函数。这是一个例子:

#include <iostream>

template <typename T, auto n>
void print(const T(&arr)[n]) {
  for (auto&& t : arr) {
    std::cout << t << ' ';
  }
  std::cout << '\n';
}

int main() {
  int arr[]{ 1, 2, 3, 4, 5 };
  print(arr);
}

输出:

1 2 3 4 5

【讨论】:

    【解决方案3】:

    如果您想实际传递一个数组,而不是切换到使用向量,您可以使用根据数组大小参数化的模板函数来完成,即

    template <int N>
    double avg(int (&arr)[N] ) {
        double sum = 0;
        int size = 0;
        for (int i : arr) {
            sum += i;
            size += 1;
        }
        return sum / size;
    }
    
    int main()
    {
        int ary[] = { 1,2,3,4,5,6 };
    
        std::cout << avg(ary);
    }
    

    【讨论】:

      猜你喜欢
      • 2016-11-22
      • 1970-01-01
      • 2021-03-31
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多