Прозрачная замена указателей на символьные массивы в C ++
Вопрос
У меня есть массив двумерных символов:
char nm[MAX1][MAX2] = { "john", "bob", "david" };
Я хочу поменять местами два из этих элементов (без std::swap
) просто написав
swapPointers(nm[0], nm[1]);
где swapPointers
выглядит примерно так
void swapPointers(char *&a, char *&b)
{
char *temp = a;
a = b;
b = a;
}
Однако это не компилируется (и хотя добавление приведений приводит к его компиляции, указатели в конечном итоге указывают на неправильные / странные местоположения).
Кто-нибудь может помочь?
Спасибо!
Решение
Зан близок к этому, но его проблема в том, что его функция 'swap' может принимать любой указатель на символы.Это может вызвать проблемы при неправильном использовании.Вот более безопасная версия:
void swap(char (&x)[MAX2], char (&y)[MAX2])
{
char temp[MAX2];
memcpy(temp, x, MAX2);
memcpy(x, y, MAX2);
memcpy(y, temp, MAX2);
}
Существует также недопонимание со стороны плаката:"nm" - это двумерный массив символов.Здесь нет никаких указателей.нм[0], нм[2] и т.д...это также не указатели - они все еще являются (одномерными) массивами.Тот факт, что одномерные массивы неявно преобразуются в указатели, вызывает такого рода путаницу среди многих программистов на C и C ++.
Чтобы поменять местами данные в двумерном массиве, вы должны поменять местами блоки памяти размером MAX2 - как указано в обеих функциях "swap", которые мы с Заном написали.
Другие советы
Вы не можете поменять местами эти указатели, переназначив указатели, потому что эти указатели указывают на массив двумерных символов.
nm [a] и nm[b] очень сильно const
потому что nm - это действительно const
объект.Если бы это было не так, вы могли бы перемещать переменные C в оперативной памяти, переназначая их имена.
Только подумайте о хаосе!Так что ты не можешь этого сделать.:-)
Чтобы поменять местами то, на что указывают эти указатели, вам нужно поменять местами значения в этих расположениях массива.
swap(char *a, char *b)
{
char temp[MAX1];
memcpy(temp, a, MAX1);
memcpy(b, a, MAX1);
memcpy(a, temp, MAX1);
}
Ваш swapPointers()
меняет местами указатели, в то время как вы пытаетесь передать им массивы.
Если вы измените
char nm[MAX1][MAX2]
Для
char *nm[MAX1]
и исправьте небольшую ошибку в swapPointers()
(последняя строка должна быть b = temp;
), это работает.
Реальный смысл в том, что если вы используете c ++, то вместо std::vector вам следует использовать std::string:
std::vector<std::string> nm;
nm.push_back( "john" );
nm.push_back( "bob" );
nm.push_back( "david" );
std::swap( nm[0], nm[1] );
Примечание:не проверено.
void swapPointers(char** ppa, char** ppb)
{
char* ptemp = *ppa;
*ppb = *ppa;
*ppa = ptemp;
}
swapPointers(&nm[0], &nm[1]);