【问题标题】:How do I allocate an array in a function that is at the same time an input argument?如何在同时是输入参数的函数中分配数组?
【发布时间】:2020-11-15 15:53:01
【问题描述】:

我正忙于一项任务,但我不知道如何解决问题。作为程序的一部分,我需要编写一个添加函数。该计划的目标是:

  • 从命令行读取两个整数值 n1 和 n2。

  • 分配两个整数数组array1和array2,大小分别为n1和n2

  • 用值 0,1....,n1-1 和 0,1....,n2-1 初始化两个数组

  • 写一个带有签名的add函数:

    void add(... array1, ... n1, ... array2, ... n2, ... array3, ... n3)

该函数应提供以下功能:

  • 分配一个整数数组array3,大小为n3 = max(n1,n2);
  • 将array1和array2这两个数组逐个元素添加到array3中;
  • 仅添加第一个 min(n1,n2) 元素,并在两个数组的长度不同时复制较长数组中的元素;
  • 分别通过第五个和第六个函数参数返回array3 及其长度n3。不要更改 add 函数的签名。

我卡在 add 函数的部分。我看不到 array3 必须是输入参数,但也需要在函数中分配。同样的困惑也适用于 n3。

我得到的提示是我需要使用双指针。

问题:如何实现函数的第一个功能点,同时保持函数签名不变?

提前非常感谢 :) 纳丁

编辑:

到目前为止我的代码:

// Include header file for standard input/output stream library
#include <iostream>

// Your implementation of the add functions starts here...

void add(int *array1, int *array2, int **array3){
    array1[5] = 20;
}


// The global main function that is the designated start of the program
int main(int argc,char* argv[]){


    // Read integer values n1 and n2 from the command line
    //int n1;
    //int n2;
    //n1 = atoi(argv[1]);
    //n2 = atoi(argv[2]);

    

    // Allocate and initialize integer arrays array1 and array2
   int n1 = 10;
   int n2 = 10;

   int* array1  = NULL;
   array1  = new int[n1];

   int* array2  = NULL;
   array2  = new int[n2];
   

   for (int x = 0; x<n1; x++)
   {
       array1[x] = x;
   }
   
   for (int y = 0; y<n2; y++)
   {
       array2[y] = y;
   }


   int *array3;

    // Test your add function

   add(array1, array2, &array3);
  
   
    delete[] array1;
    delete[] array2; 
    delete[] array3;

  
    

    // Return code 0 to the operating system (= no error)
    return 0;
}

【问题讨论】:

  • 我的建议是把问题分解成你能理解的部分。
  • 分配动态数组的首选c++方式是使用std::vector
  • 虽然它不是学校介绍课程的首选类型.. @drescherjm
  • 教学无能。而不是教 c++ 仍然教 c 的课程应该在 2 多年前被放弃。
  • 当对作业的要求感到困惑时,与给你的人交谈。只需与您的老师交谈。没有必要去网上找陌生人,希望他们能猜出你老师想要什么。

标签: c++


【解决方案1】:

需要在函数内部分配数组,还要通过“输出参数”array3返回分配的数组。要通过输出参数返回一些东西,参数需要是一个指针;但是要返回一个数组,数组本身也是一个指针。所以我们需要的确实是一个指向指针的指针:

void add(... array1, ... n1, ... array2, ... n2, int **array3, ... n3)

它会被这样调用:

// Caution: uninitialized pointer at this point! Do not dereference!
int *output;
// Pass the address of the pointer.
add(..., ..., ..., ..., &output, ...);
// Now output has been initialized, so *output is valid (same as output[0]).

output 是单个指针,因为它包含数组的地址。

当把它传递给函数add 时,我们写成&amp;output 而不是简单的output。您可以将其读作“输出地址”,即指针的地址,即数组地址的地址。这样add就可以写入指向的变量了。

add 中,您可以执行以下操作来分配数组:

*array3 = new int[n3];

注意这里额外的*:我们希望将新分配的数组的地址存储在array3指向的位置,而不是array3本身(毕竟, 不是指向数组而是指向指针)。


如果函数返回单个 float 而不是 int *,所有这些可能会变得更容易理解:

void approximate_pi(float *out) {
    *out = 3.14;
}

int main() {
    float pi;
    approximate_pi(&pi);
}

该函数接受指向float 的指针,并将输出写入指针指向的位置。调用函数时,我们传递所需输出位置的地址。

【讨论】:

  • 引用也可以,并且可以避免一些双指针混淆。尽管再次阅读了这个问题,但 OP 或多或少被告知他们应该使用双指针。
  • 问题是“我得到的提示是我需要使用双指针。”这里有一些关于指针的事情要说:从额外的&amp; 调用站点很清楚,参数不是通过值或常量引用传递的,因此它可能会被函数改变。
  • @Nadine 我扩大了我的答案,希望对您有所帮助!
  • @Thomas 是的,我想我更了解它。谢谢!
【解决方案2】:
// I am also doing that course, here is my code
// I past current self-test
// But I mistakenly clicked spec test twice before, so I only get one chance left
// Could you try the spec test on your Weblab and let me know the result?

// Include header file for standard input/output stream library
#include <iostream>
// Your implementation of the add functions starts here...
void add(int* array1, int n1, int* array2, int n2, int** array3, int& n3)
{
    n3 = std::max(n1, n2);
    *array3 = new int[n3];
    for (int i=0; i<n3; i++)
    {
        if (i >= n1) {*(*array3+i) = array2[i];}
        else if (i >= n2) {*(*array3+i) = array1[i];}
        else {*(*array3+i) = array1[i] + array2[i];}  
    }
}

// The global main function that is the designated start of the program
int main()
{
    // Read integer values n1 and n2 from the command line
    int n1 = 9;
    int n2 = 10;

    // Allocate and initialize integer arrays array1 and array2
    int* array1 = new int[n1];
    for (int i =0; i<n1; i++) {*(array1+i) = i;}
    int* array2 = new int[n2];
    for (int i =0; i<n2; i++) {*(array2+i) = i;}
    int* array3 = NULL;
    int n3 = 0;

    // Test your add function
    add(array1, n1, array2, n2, &array3, n3);
    std::cout<<"Array3 = " << std::endl;
    for (int i=0; i < n3; i++) {std::cout<<array3[i]<<std::endl;}
    std::cout<<"The length of array3 = "<< n3 << std::endl;
    delete[] array1, 
    delete[] array2;
    delete[] array3;
    array1 = nullptr;
    array2 = nullptr;
    array3 = nullptr;
    // Return code 0 to the operating system (= no error)
    return 0;
}
 

【讨论】:

  • 为什么在添加签名中包含int& n3?你为什么不选择只做n3? @ZhouyuanWang
  • 传值不会改变主函数中n3的值。我想输出n3的大小。
  • 还没有,因为我不完全同意命令行部分的阅读
  • 好吧,当我知道规范测试没有限制时,我尝试了自己。
猜你喜欢
  • 1970-01-01
  • 2016-04-01
  • 2021-09-18
  • 1970-01-01
  • 2022-12-05
  • 2020-12-30
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多