Прозрачная замена указателей на символьные массивы в C ++ - PullRequest
2 голосов
/ 24 сентября 2008

У меня есть двумерный массив символов:
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;  
}

Однако, это не компилируется (и хотя добавление приведений приводит к компиляции, указатели в итоге указывают на неправильные / странные места).

Кто-нибудь может помочь?
Спасибо!

Ответы [ 5 ]

4 голосов
/ 24 сентября 2008

Зан близок, но его проблема в том, что его функция '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» - это двумерный массив символов. Там нет указателей. nm [0], nm [2] и т. д. ... также не являются указателями - они по-прежнему (одномерные) массивы. Тот факт, что одномерные массивы неявно преобразуются в указатели, вызывает путаницу среди программистов на C и C ++.

Чтобы поменять местами данные в 2-мерном массиве, вам нужно поменять местами блоки памяти размера MAX2 - как указано в обеих функциях 'swap', написанных нами и Заном.

3 голосов
/ 24 сентября 2008

Вы не можете поменять эти указатели, переназначив указатели, потому что эти указатели указывают на двумерный массив символов.

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);
}
3 голосов
/ 24 сентября 2008

Ваши swapPointers() меняют указатели, а вы пытаетесь передать его массивам.

Если вы измените

char nm[MAX1][MAX2]

до

char *nm[MAX1]

и исправьте небольшую ошибку в swapPointers() (последняя строка должна быть b = temp;), все работает.

1 голос
/ 24 сентября 2008

Реальная точка зрения в том, что если вы используете 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] );

Примечание: не тестировалось.

0 голосов
/ 24 сентября 2008
void swapPointers(char** ppa, char** ppb)
{
    char* ptemp = *ppa;
    *ppb = *ppa;
    *ppa = ptemp;
}

swapPointers(&nm[0], &nm[1]);
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...