通过函数修改数组的元素

时间:2014-06-21 23:53:17

标签: c++ visual-c++

我正在学习指针,但我无法使用此代码。这是我到目前为止所做的:

void incrementArray(int* a[]) {
    for(auto& x : a) {
        ++x;
    }
}

int _tmain(int argc, _TCHAR* argv[])
{
    int array[] = {0,1,2,3,4,5,6,7,8,9};

    for(auto x : array) {
        cout << x << '\n';
    }

    incrementArray(&array);

    for(auto x : array) {
        cout << x << '\n';
    }
}

我收到以下错误:

  

'incrementArray':无法将参数1从'int(*)[10]'转换为   'int * []'

我可以做些什么来修复我的代码?

4 个答案:

答案 0 :(得分:3)

C风格的数组语法很有趣。要将数组传递给函数,请使用int a[]这不复制数组并更改到函数内部的数组将修改外部数组。您只需拨打incrementArray(array); no&amp;需要

您可以尝试使用遵循更常规语法的std::array类。

答案 1 :(得分:2)

你有一个指针作为参数(对数组的引用),但你希望修改它所指向的实际内容,所以你必须改变* a,而不是a。

你可以使用一个数组,向量,列表等对象,这些对象已经有了与之相关的方法,可以完成你想要的大部分操作

答案 2 :(得分:1)

由于以int a[]作为参数的函数的签名不包含编写for-each循环所需的必要长度信息(即实例化{{1),因此您尝试执行的操作将无法工作。使用for-each语法所需的模板和begin()模板。海湾合作委员会的警告相当清楚地说明了这一点:

end()

我认为这可能适用于模板,但是。 。 。

编辑:

可以使用模板完成,只需花一点时间就可以了解语法。以下是您工作状况的示例:

Error:(14, 19) cannot build range expression with array function parameter 'a' since 
parameter with array type 'int *[]' is treated as pointer type 'int **'

答案 3 :(得分:1)

您可以采用几种方法来增加数组的元素,所有这些方法都需要知道从哪里开始以及在哪里结束。做你想做的事的简单方法是只传递起始和结束地址指针,但你也可以传递带有一些偏移量的起始地址。由于您使用的是C样式数组,因此int元素具有地址int*,因此std::begin(array)与第一个元素int*std::end(array) std::end()指向上次分配元素后的位置地址。在您的程序中,std::end()地址指向第10个分配元素后的内存位置。如果你有一个大小分配的数组(int other_arr [40]),std::end(other_arr)将指向分配后的第一个地址(std::begin(other_arr)+41将是std::begin())。 C ++最近在std::end()库中引入了非成员<iterator>#include <algorithm> // std::copy #include <iostream> // std::cout #include <iterator> // std::begin void increment_elements(int* begin, const int* end) { while (begin != end) { ++(*begin); ++begin; } } // An increment functor for std::transform int increase_element(int i) { return ++i; } int main() { int array[] = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9 }; for (const int x : array) { std::cout << x << ' '; } std::cout << '\n'; increment_elements(std::begin(array), std::end(array)); // Another way to write your print statement above std::copy(std::begin(array), std::end(array), std::ostream_iterator<int>(std::cout, " ")); std::cout << '\n'; // Transform array elements through increase_element() // and print result to cout. std::transform(std::begin(array), std::end(array), std::ostream_iterator<int>(std::cout, " "), increase_element); std::cout << '\n'; } ,它返回指向C-Array中相应元素位置的指针。

increment_elements()

<algorithm>函数的通用版本可以在std::transform()库中找到,作为函数using namespace std; documented here

由于您现在正在学习,这里有一些您可以开始使用的习惯:

请勿在全局级别使用std::。通过将标准库中的所有内容拉入全局命名空间,您可以使用可以在调用函数调用时调用的功能“污染”它,因为它不需要double distance(Point* p1, Point* p2)前缀限定。假设您要编写一个函数来计算两个(x,y)点之间的欧氏距离<vector>。您决定使用任何STL容器,例如<iterator>。容器使用std::distance(T*, T*)库,它有自己的std函数来计算内存中两个地址之间的距离。通过using namespace std;const引入全局命名空间,您现在在同一命名空间中拥有2个具有相同签名的函数,这两个函数完全不同。这非常糟糕但很容易避免。对于小型项目,这个一般准则可能是不必要的,但我仍然建议你不要为任何项目做这件事。如初。

const T&const您的只读操作。在进行操作时,如果您要提取数据以进行阅读而又不想修改数据,请使用const T&const进行初始化。 const T&本身对于原始数据类型(int,float,double,char)就足够了,但非原语需要Tconst T&是类型)。 const类型的值(称为const引用)是只读的(&)并直接访问({{1}})。