У меня есть два массива указателей на, удваивает это, я должен подкачать. Вместо того, чтобы просто копировать данные в массивах, было бы более эффективно только подкачать указатели на массивы. У меня всегда создавалось впечатление, что имена массива были по существу просто указателями, но следующий код получает ошибку компилятора:
double left[] = {1,2,3};
double right[] = {9,8,7};
double * swap = left;
left = right; // Error "ISO C++ forbids assignment of arrays"
right = swap; // Error "incompatible types in assignment of `double*' to `double[((unsigned int)((int)numParameters))]'"
Создание массивов динамично решило бы проблему, но не может быть сделано в моем приложении. Как я делаю эту работу?
Попробуйте это
double *right = (double[]){9,8,7};
double *left = (double[]){8,2,3};
Когда вы объявляете массив, имя является указателем, который нельзя изменить.
Пример:
int array[10];
int *p;
p = array; // legal
array = p; // illegal; array is a constant pointer which can't be altered.
Единственный способ добиться подкачки - это использовать новые указатели на массив.
Это должно вам помочь:
double array_one[] = {1,2,3};
double array_two[] = {9,8,7};
double *left = array_one;
double *right = array_two;
double * swap = left;
left = right;
right = swap;
Работает нормально.
редактировать: Определения array_one и array_two использовать не следует, а двойные left и double right должны быть такими же общедоступными, как и ваши исходные определения left и right.
Массивы - это не то же самое, что указатели, и их нельзя менять местами описанным вами способом. Чтобы выполнить трюк с заменой указателя, вы должны использовать указатели, либо динамически выделять память, либо использовать указатели для доступа к данным (как описал Дэниел).
Массивы в стиле C не являются указателями, но, как и большинство объектов, они могут быть заменены стандартным std :: swap ()
:
#include <iostream>
#include <utility>
int main()
{
double array_one[] = {1,2,3};
double array_two[] = {9,8,7};
std::swap(array_one, array_two);
std::cout << "array_one[0] = " << array_one[0] << '\n';
std::cout << "array_two[0] = " << array_two[0] << '\n';
}
На самом деле, похоже, что std :: swap () для массивов определен только в C ++ 0x (20.3.2), так что неважно. Правильный ответ для обоих массивов в области видимости и массивов как указателей на первые элементы:
std::swap_ranges(array_one, array_one + 3, array_two);
Вы можете передавать оба указателя на массивы по ссылкам, а если указатели не являются константными, вы можете просто поменять их местами:
void swap(char * & first, char * & second)
{
std::swap(first, second);
}
Один из самых простых способов убедить людей, что это не указатели, и их нелегко поменять местами, - это показать следующий код:
struct ex {
char c[4];
double d[3];
};
struct ex a = {"foo", {1.0, 2.0, 3.0} };
struct ex b = {"bar", {6,7,8} };
Теперь ясно, что a.d
и b.d
- это массивы. Поменять их местами будет сложно, так как массив {6,7,8} должен оказаться в памяти после a.c=="foo"
, а это означает копирование 3 двоек. На рисунке нет указателя.