【问题标题】:How to copy values from an array into a new one?如何将数组中的值复制到新数组中?
【发布时间】:2016-12-17 22:18:34
【问题描述】:

我已经断断续续地尝试解决这个问题一个星期了,但我一直遇到问题。

我的目标:

编写一个为整数数组分配内存的函数。该函数将整数指针、数组大小和要分配的 newSize 作为参数。该函数返回一个指向已分配缓冲区的指针。首次调用该函数时,大小将为零,并且将创建一个新数组。如果在数组大小大于零时调用该函数,则会创建一个新数组并将旧数组的内容复制到新数组中。您的讲师提供了 arrayBuilder.cpp 作为此编程挑战的入门代码。此外,Lab9_1.exe 是该应用程序的可执行文件,您可以进行测试。

代码:

#include <iostream>
using namespace std;

int * arrayBuilder(int * arr, int size, int newSize);
void showArray(int * arr, int size);

int main()
{
int * theArray = 0;
int i;

cout << "This program demonstrates an array builder function." << endl << endl;

// create the initial array.  The initial size is zero and the requested size is 5.
theArray = arrayBuilder(theArray, 0, 5);

// show the array before values are added
cout << "theArray after first call to builder: " << endl;
showArray(theArray, 5);

// add some values to the array
for(int i = 0; i < 5; i++)
{
    theArray[i] = i + 100;
}

// show the array with added values
cout << endl << "Some values stored in the array: " << endl;
showArray(theArray, 5);

// expand the size of the array.  size is not the original size.  newSize
// must be greater than size.
theArray = arrayBuilder(theArray, 5, 10);

// show the new array with the new size
cout << endl << "The new array: " << endl;
showArray(theArray, 10);

cout << endl;

delete [] theArray; // be sure to do this a1t the end of your program!

system("pause");

return 0;
}

/*
FUNCTION: arrayBuilder
INPUTS Pointer to an array.  Size of the array. If size is zero, arr can be    NULL.
      Size of the new array.
OUTPUTS:  Returns a pointer to allocated memory.  If newSize is greater than size,
      an array of newSize is allocated and the old array is copied into the new
      array. Memory pointed to by the old array is deleted.  All new elements
      are initialized to zero.
*/


int * arrayBuilder(int * arr, int size, int newSize)
{
// TODO: Your code goes here


return NULL; // default return value.  No memory allocated!
}

/*
FUNCTION: showArray
INPUTS: Pointer to an array.  Size of the array. If size is zero, arr can be  NULL.
OUTPUTS:  Prints the contents of the array to the console.
*/


void showArray(int * arr, int size)
{
cout << "arr = ";

for(int i = 0; i < size; i++)
{
    cout << arr[i] << "  ";
}

cout << endl;

}

我的挣扎:我不知道如何切换“arr”和临时数组的值。

int * arrayBuilder(int * arr, int size, int newSize)
{
// TODO: Your code goes here
    int * temp = new int [newSize];

for (int i = size; i < newSize; i++)
{
        *arr = *temp;
        temp++;
}

return NULL; // default return value.  No memory allocated!
}

寻找答案时的另一次尝试:

int * arrayBuilder(int * arr, int size, int newSize)
{
// TODO: Your code goes here
int * temp = new int [newSize];
memcpy (temp, arr, size *sizeof(int));
// HINT: Design the function before writing it.
delete[]  arr;

for (int i = size; i < newSize; i++)
{
    temp[i] = i;
}

return NULL; // default return value.  No memory allocated!
}

基本上我的最终目标是让答案看起来像这样:

This program demonstrates an array builder function.

theArray after first call to the builder:
arr = 0 0 0 0 0

some values stored in the array:
arr = 100 101 102 103 104

the new array:
arr = 100 101 102 103 104 0 0 0 0 0

进展!!它不再崩溃了 :-) 这就是我现在所处的位置:

This program demonstrates an array builder function.

theArray after first call to builder:
arr = -842150451  0  0  0  0

Some values stored in the array:
arr = 100  101  102  103  104

The new array:
arr = -842150451  -842150451  -842150451  -842150451  -842150451  -842150451  -8
42150451  -842150451  -842150451  -842150451

Press any key to continue . . .

我会继续修修补补,如果我碰壁了,让大家知道!再次感谢大家!

好的!终于可以正常显示了:

This program demonstrates an array builder function.

theArray after first call to the builder:
arr = 0 0 0 0 0

some values stored in the array:
arr = 100 101 102 103 104

the new array:
arr = 100 101 102 103 104 0 0 0 0 0

这就是我所做的。当我为“temp”输入 0 值时,我觉得我可能在第二部分作弊了。我的理解是,我将从前一个数组中获取数据并将其放入新数组中,而我只是重新制作它。 (所以它只适用于这组特定的值[只有 0])。有没有一种不同的方式可以让我对第二部分进行编码,以便它可以普遍适用于抛出的任何值???

int * arrayBuilder(int * arr, int size, int newSize)
{
int i = size;
int * temp = new int [newSize];
// What if the size is 0?
if (size <= 0)
{
    while (i < newSize)
    {
        temp[i] = 0;
        i++;
    }
}
// Assuming the size _isn't_ 0
else 
{
// "a new array will be created"  (good)

for (i = 0; i < newSize; i++)
{
    // The contents of the "old" array (arr) will be
    // copied into the "new" array (temp)
    while (i < size)
    {
        temp[i] = arr[i];
        i++;
    }
    while (i >= size && i < newSize)
    {
        temp[i] = 0;
        i++;
    }
    // as a hint, you can address the elements in 
    // both arrays using the [] operator:
    // arr[i]
    // temp[i]

}
}

// "The function returns a pointer to the allocated buffer."
// So, NULL is wrong, what buffer did you allocate?
return temp; // default return value.  No memory allocated!
}

【问题讨论】:

    标签: c++ arrays pointers allocation


    【解决方案1】:

    既然你付出了一些努力。

    编写一个为整数数组分配内存的函数。

    这个函数的原型是为你提供的:

    int * arrayBuilder(int * arr, int size, int newSize);
    

    该函数将整数指针作为参数,该指针的大小 数组和要分配的 newSize。该函数返回一个指向 分配的缓冲区。

    这并没有说明对“旧”(传入的)数组做任何事情,所以我们应该假设它需要单独放置。

    当函数第一次被调用时,大小将为零并且新的 数组将被创建。

    鉴于上下文,上述文字毫无意义。随意告诉你的导师我是这么说的。如果大小为零,你怎么知道要分配多少个元素?

    如果在数组大小大于零时调用该函数,则 将创建新数组,旧数组的内容将是 复制到新数组中。

    好的,现在是需要做的事情的胆量(你如此接近)

    int * arrayBuilder(int * arr, int size, int newSize)
    {
        // What if the size is 0?
    
        // Assuming the size _isn't_ 0
        // "a new array will be created"  (good)
        int * temp = new int [newSize];
    
        for (int i = size; i < newSize; i++)
        {
            // The contents of the "old" array (arr) will be
            // copied into the "new" array (temp)
    
            // as a hint, you can address the elements in 
            // both arrays using the [] operator:
            // arr[i]
            // temp[i]
    
            // something is wrong here...
            *arr = *temp;
    
            // you definitely _don't_ want to do this
            temp++;
        }
    
        // "The function returns a pointer to the allocated buffer."
        // So, NULL is wrong, what buffer did you allocate?
        return NULL; // default return value.  No memory allocated!
    }
    

    【讨论】:

    • +1 很好的答案,因为它有助于理解,但不是复制&粘贴&完成模板。
    • 嗯,是的,在代码中添加 cmets 比试图用英语拼写出来更好。
    • +1 好答案。本来可以使用 memcpy,但这更明确地用于教学目的。
    • 哇!非常感谢,我将花一点时间来消化这个。我会回来希望让你知道我已经想通了。如果没有,我会带着更多问题回来,您或其他人可以帮助我解决。再次感谢!
    • 我是这个网站的新手,所以我不确定编辑我的帖子是否会通知你或任何事情,但希望这会。无论如何,我真的很感谢你的帮助,如果你不介意看看我更新的帖子,我将永远感激不尽
    【解决方案2】:

    你已经在这里得到了答案:

    memcpy (temp, arr, size *sizeof(int));
    

    但在那之后你又犯了其他几个错误。首先,您需要return temp ; 而不是return NULL ;

    但你也不需要delete arr[] ;之后的循环

    如果大小为零,也不要delete arr[]

    【讨论】:

    • 删除空指针是可以的,就像删除大小为 0 的 newed 数组一样。
    • 另一种可能性是将memcpy 替换为std::copy
    【解决方案3】:

    这是非常复杂的代码。编程就是降低复杂性。

    考虑到这一点,这里有一个合适的 C++ 解决方案:

    std::vector<int> arr = {1, 2, 3, 4, 5};
    std::vector<int> copy = arr;
    

    就是这样。我希望这能说明为什么您应该使用标准库(或其他适当的库)而不是重新发明轮子。从您发布的代码中,我假设您已经从一本糟糕的书或课程中学习(或正在学习)C++。垃圾邮件和get a proper book。 C++ 本身就足够复杂,无需添加不必要的复杂性。

    【讨论】:

    • 这看起来像是一项编程任务,他们必须学会自己努力完成。
    • @woolstar 杜尔。在我看来,这是一个可怕的任务。不是因为它本身不好,而是因为学生们显然还没有学会编写正确的 C++ 代码,所以它来得太早了。
    • 使用 STL 是不正确的。 很多示例说明您何时不应该使用 STL。例如,正如大多数专业人士所知,STL 不是线程安全的,不能用于多线程编程。人们应该在适当的时候使用 STL,而不是作为拐杖。学习复制基本数组仍然正确
    • STL不能在多线程程序中使用?天哪,我最好将我所有的应用程序都从市场上撤下......
    • @user2705235 这太荒谬了。不管这些警告如何,使用标准库正确的。它也可以在多线程环境中使用,您只需要提供自己的锁定。缺乏内置线程安全有充分的理由——即效率要求(以及 C++ 支持多线程之前的向后兼容性)。最后,无论如何,对公共数据结构的随意共享访问在适当设计的多线程环境中都没有立足之地。适当的多线程使用专用的同步通信通道来实现这一点。
    【解决方案4】:

    只是为了帮助您了解为什么第一次尝试没有成功:

    *arr = *temp;
    

    这是从新数组中为旧数组赋值。那是倒退。

    但它只是针对第一个值,*arr 不会改变。您增加*temp,但您还需要增加*arr。 (另外,像那种可怕的和 memcopy() 这样的手动指针操作要好得多。但是,嘿,这是为了学习目的,对吧?)

    另外,想想那个循环:

    for (int i = size; i < newSize; i++)
    

    对于 newSize 大于 size 的每一位都迭代一次。但是你在这里做两件事。 1)复制数据和2)初始化新数据。您拥有的 for 循环非常适合遍历新数据,但它不是您想要复制已有数据的循环。那会从零到大小,对吧?

    当你完成后,你需要返回你构建的数组的地址。

    return NULL; // default return value.  No memory allocated!
    

    这只是一些虚拟的模拟代码。这是老师的占位符。这是您应该更改的代码的一部分。

    根据您的更新:

    当我为“temp”输入 0 值时,我觉得我可能在第二部分中作弊了

    那你还打算放什么?您确实复制了旧的数组数据。然后你扩展数组。什么进入新领域?零值作为默认值是完全有效的。

    有没有一种不同的方式我可以对第二部分进行编码,以便它可以普遍适用于抛出的任何值???

    嗯,是的,但你实际上必须有一些东西可以扔给它。您的ArrayBuilder 函数可以接受额外的参数possibly as a variadic function,因此它知道将哪些值放入新字段。但是您的函数声明没有。它所做的只是使数组更大。

    另外,在您的最后一次编辑中,您有两个 while 循环,它们在一个 for 循环中遍历 i,它也遍历 i。这会起作用,但只是让你知道它有点……粗鲁。当事情变得更复杂时,这种事情会给你带来麻烦。

    你可以这样做:

    for (i = 0; i < newSize; i++)
    {
      if(i < size)
      {
        temp[i] = arr[i];
      }
      else // if(i >= size && i < newSize) //Wait a sec, this "if" is superfluous. It's conditions are enforced the the first if and the loop condition.
      {
        temp[i] = 0;
      }
    }
    

    您还应该删除那些听起来像是别人为您编写代码的 cmets。因为别人为你做了功课。最好是

    最后,你应该缩进你的代码!

    【讨论】:

      【解决方案5】:

      如果我正确理解了赋值,那么函数应该如下所示。 首先我会替换函数声明

      int * arrayBuilder(int * arr, int size, int newSize);
      

      int * arrayBuilder( const int *arr, size_t size, size_t newSize );
      

      这是它的定义

      int * arrayBuilder( int * arr, int size, int newSize)
      {
         int *tmp = 0;
      
         if ( newSize >= 0 )
         {
            tmp = new int[newSize] {};
      
            int copy_size = std::min( size, newSize );
      
            if ( copy_size > 0 ) std::copy( arr, arr + copy_size, tmp );
         }
      
         delete []arr;
      
         return tmp;
      }
      

      【讨论】:

        【解决方案6】:

        试试这个:

        代码:

        #include <iostream>
        
        using namespace std;
        
        int a[3] = 
        {
            1,
            2,
            3
        };
        
        int b[3];
        
        int main ()
        {
            cout << endl;
            cout << "Array #1 elements: " << endl;
            for(int i = 0; i < 3; ++i)
            {
                cout << a[i] << " ";
            }
        
            for(int i = 0; i < 3; ++i)
            {
                b[i] = a[i];
            }
            cout << endl << endl;
            cout << "Copying Array #1 elements to Array #2..." << endl;
            cout << endl;
            cout << "Array #2 elements: " << endl;
            for(int i = 0; i < 3; ++i)
            {
                cout << b[i] << " ";
            }
            cout << endl << endl;
            return 0;
        }
        

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2013-10-29
          • 1970-01-01
          • 2013-03-21
          • 2016-05-11
          • 1970-01-01
          • 2020-10-17
          相关资源
          最近更新 更多