c++ 如何在函数内部更改这个数组?

k2fxgqgv  于 2023-01-18  发布在  其他
关注(0)|答案(1)|浏览(138)

这段代码是为CS235类编写的,但是我是C++新手,我不知道他们想让我怎么做。grow函数的工作原理是接受一个数组,然后把它变成原来的两倍大。来自python,我猜这相当于改变数组?不管怎样,我不能让它对insert函数做同样的事情,我需要它来检查我们试图插入一个元素的位置是否在数组边界之外,并使数组足够大,以便它可以插入这个值。在函数内部一切正常。数组不维护函数外部的更改。我试过将它作为指针传入,作为(指针的引用?)像 *&数组,以及基本上任何我能想到的组合。

void grow(int *&original_array, unsigned int & capacity){
    int *temp = new int[capacity * 2];
    for (int i=0; i<capacity*2; i++){
        temp[i] = 0;
    }
    std::cout << "line 18: ";
    print_array(temp, capacity*2);
    for(int i=0; i<capacity; i++){
        temp[i] = original_array[i];
    }
    std::cout << "line 23: ";
    print_array(temp, capacity*2);

//    delete[] original_array;
    original_array = temp;
    std::cout << "line 27: ";
    print_array(original_array, capacity * 2);
    capacity = capacity * 2;
}

bool insert (int array[], unsigned int & maxSize, unsigned int & nFilled, unsigned int pos, int value){
    while (maxSize < pos){
        grow(array, maxSize);
        print_array(array, maxSize);
    }
    for(unsigned int i = nFilled - 1; i >= pos; i = i-1){
        array[i+1] = array[i];
    }
    array[pos] = value;
    print_array(array, maxSize);
    return true;
}

下面是一些示例输入和我的程序现在的输出:

int main() {
    unsigned int my_size = 4;
    int new_array[4] = {1,2,3,4};
    unsigned int nFilled = 4;

    insert(new_array, my_size, nFilled, 5, 15);
    print_array(new_array, my_size);
    return 0;
}

输出:

line 18: {0, 0, 0, 0, 0, 0, 0, 0}
line 23: {1, 2, 3, 4, 0, 0, 0, 0}
line 27: {1, 2, 3, 4, 0, 0, 0, 0}
{1, 2, 3, 4, 0, 0, 0, 0}
{1, 2, 3, 4, 0, 15, 0, 0}
{1, 2, 3, 4, -152629248, 32758, 0, 8}

倒数第二行在函数内部,最后一行在函数外部。2我需要它们相同
任何帮助都很感激-助教和教授们都不帮忙。
谢谢

jjjwad0x

jjjwad0x1#

你编写的代码有两个问题,第一个是你不能按照编写的那样在main中重新分配new_array的值,因为它不是动态分配的,所以你不能改变它,你需要改变它才能动态分配:

int* new_array = new int[4];

for(int x = 0; x < 4; ++x)
{
    new_array[x] = x + 1;
}

这将解决 * 一个问题 *,但是代码仍然不能工作,这与变量如何传递给insertgrow有关。
您的grow()函数将int*&作为指向integer指针的引用。这意味着传入 * 的基础值可以 * 更改。但是,您的insert()函数将int[]作为衰减为指向integer指针的integer数组,并且此处的更改不会反映在insert()的调用位置。
您可以通过添加更多调试语句来验证这一点:

bool insert (int array[],
    unsigned int & maxSize,
    unsigned int & nFilled,
    unsigned int pos,
    int value)
{

    // unchanged above...
    std::cout << "Inside insert: " << array << '\n';
    return true;
}

int main()
{
    // unchanged above...
    std::cout << "After insert: " << new_array << "\n";
    print_array(new_array, my_size);
    return 0;
}

您将得到 * 类似于 * 以下内容的输出:

line 18: {0 0 0 0 0 0 0 0 }
line 23: {1 2 3 4 0 0 0 0 }
line 27: {1 2 3 4 0 0 0 0 }
{1 2 3 4 0 0 0 0 }
{1 2 3 4 0 15 0 0 }
Inside insert: 0x548ed0
After insert: 0x548eb0
{1 2 3 4 0 0 49 0 }

请注意,数组“Inside insert”和“After insert”是不同的。
要解决这个问题,您需要确保向insert()传递了允许更改值的内容,类似于对grow()所做的操作。
该更改非常简单,只需更改insert()的签名,如下所示:

bool insert (int *&array,
    unsigned int & maxSize,
    unsigned int & nFilled,
    unsigned int pos,
    int value)

注意到insert()的第一个参数被修改为与grow()中的类型相匹配,一个指向integer指针的引用,现在当我们把指针new_array传递给insert()时,传递了一个指向该指针的引用(允许更改值),并且 * 也 * 传递给grow()(如果需要),允许它一直传播到调用点。
请注意,尽管这种方法存在 * 风格问题 *--不清楚的所有权语义、潜在的内存泄漏(出现在发布的代码中)等。
我还将警告说,“重新发明”这种类型的数据结构而不是使用std::vector是 * 不是一个好的做法 *,但它在教学环境中确实有它的用途。

相关问题