Как скопировать значения из массива в новый?
Я уже целую неделю пытаюсь разобраться в этом, и у меня постоянно возникают проблемы.
Моя цель:
Напишите функцию, которая выделяет память для целого массива. Функция принимает в качестве аргумента целочисленный указатель, размер массива и 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
Вот что я сделал. Я чувствую, что я, возможно, обманул во второй части, когда я поставил 0 значений для "temp". Это было мое понимание того, что я собирался взять данные из предыдущего массива и поместить его в новый, а вместо этого я просто переделал его. (Поэтому он будет работать только с этим конкретным набором значений [только 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!
}
6 ответов:
Поскольку вы приложили некоторые усилия.
Напишите функцию, которая выделяет память для целого массива.
Прототип для этой функции был предоставлен вам:
int * arrayBuilder(int * arr, int size, int newSize);
Функция принимает в качестве аргумента целочисленный указатель, размер которого равен массив, и newSize, который будет выделен. Функция возвращает указатель на выделенный буфер.
Это ничего не говорит о том, чтобы делать что-либо с" старым " (переданным) массивом, поэтому мы должны предположить, что это его нужно оставить в покое.
При первом вызове функции размер будет равен нулю, а новый массив будет создан.
Приведенный выше текст не имеет смысла, учитывая контекст. Не стесняйтесь, скажите своему инструктору, что я так сказал. Если размер равен нулю, то как узнать, сколько элементов нужно выделить?
Если функция вызывается, когда размер массива больше нуля, a будет создан новый массив, а содержимое старого массива будет сохранено. скопировано в новый массив.
Хорошо, теперь кишки того, что нужно сделать (вы Так близки)
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! }
Вы уже получили ответ здесь:
Но после этого вы делаете еще несколько ошибок. Прежде всего, вам нужноmemcpy (temp, arr, size *sizeof(int));
return temp ;
Неreturn NULL ;
Но также вам не нужен цикл после
delete arr[] ;
Также не
delete arr[]
, Если размер равен нулю.
Просто чтобы помочь вам понять, почему первая попытка не сработала:
*arr = *temp;
Это присвоение значения старому массиву из нового массива. Это наоборот.
Но это просто нацеливание на первое значение,*arr
не меняется. Вы увеличиваете*temp
, но вам также нужно увеличить*arr
. (Кроме того, ручная манипуляция указателем, подобная этой ужасающей и memcopy (), намного лучше. Но это же для учебных целей, верно?)Кроме того, подумайте об этом петля:
for (int i = size; i < newSize; i++)
Это повторяется один раз для каждого бита, который newSize больше размера. Но ты делаешь здесь две вещи. 1) копирование данных и 2) инициализация новых данных. То, что у вас есть цикл for, хорошо подходит для просмотра новых данных, но это не тот цикл, который вы хотите скопировать поверх уже имеющихся данных. Это будет идти от нуля до размера, верно?
И когда вы закончите, вам нужно будет вернуть адрес массива, который вы построили.
return NULL; // default return value. No memory allocated!
Это только некоторые фиктивный макет кода. Это заполнитель от учителя. Это часть кода, который вы должны изменить.
За ваше обновление:
А что еще вы собирались туда положить? Вы копируете старые данные массива. Затем вы расширяете массив. Что входит на новую территорию? Нулевые значения по умолчанию вполне допустимы.Я чувствую, что я, возможно, обманул во второй части, когда я поставил 0 значений для "temp"
Существует ли по-другому я могу закодировать вторую часть, чтобы она работала универсально с любыми значениями, которые в нее брошены???
Ну да, но у вас действительно должно быть что-то, чтобы бросить в него. Ваша функция
ArrayBuilder
может принимать дополнительные аргументы, , возможно, как вариадическая функция, поэтому она знает, какие значения вводить в новые поля. Но в вашем объявлении функции этого нет. Все, что он делает, это делает массив больше.Кроме того, в последнем редактировании у вас есть эти два циклы, которые повторяются через
i
внутри цикла for, который также повторяется через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; } }
Вы также, вероятно, должны удалить комментарии, которые заставляют его звучать так, как будто кто-то другой написал ваш код для вас. Потому что кто-то другой сделал за тебя домашнее задание. Лучше всего
Наконец, ты должен СДЕЛАЙ ОТСТУП В СВОЕМ КОДЕКСЕ!
Это ужасно сложный код. Программирование-это все о снижении сложности.
Имея это в виду, вот правильное решение C++:
std::vector<int> arr = {1, 2, 3, 4, 5}; std::vector<int> copy = arr;
Вот и все. Я надеюсь, что это иллюстрирует, почему вы должны использовать стандартную библиотеку (или другие соответствующие библиотеки), а не заново изобретать колесо. Из кода, который вы опубликовали, я предполагаю, что вы изучили (или изучаете) C++ из ужасной книги или курса. Выбросьте это и получите правильную книгу. C++ - это достаточно сложный, как он есть, нет необходимости добавлять ненужную сложность.
Если я правильно понял назначение, то функция должна выглядеть следующим образом. Прежде всего я бы заменил объявление функции
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; }
Попробуйте это:
Код:
#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; }