2008-09-24 2 views
2

у меня есть 2D массив символов:
char nm[MAX1][MAX2] = { "john", "bob", "david" };
Я хочу поменять два из этих элементов (без std::swap) просто писать
swapPointers(nm[0], nm[1]);
где swapPointers выглядит следующим образомПрозрачной замены указателей на символьные массивы в C++

void swapPointers(char *&a, char *&b) 
{ 
    char *temp = a; 
    a = b; 
    b = a; 
} 

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

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

ответ

4

Zan близок, но его проблема в том, что его функция «swap» может принимать любые указатели на символы. Это может вызвать проблемы при неправильном использовании. Вот более безопасная версия:

void swap(char (&x)[MAX2], char (&y)[MAX2]) 
{ 
    char temp[MAX2]; 

    memcpy(temp, x, MAX2); 
    memcpy(x, y, MAX2); 
    memcpy(y, temp, MAX2); 
} 

Существует также непонимание со стороны плаката: «нм» является 2-мерный массив символов. Нет указателей. nm [0], nm [2] и т. д. также не являются указателями - они все еще (одномерные) массивы. Тот факт, что одномерные массивы неявно конвертируемы в указатели, вызывает такой путаницу среди многих программистов на C и C++.

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

0
void swapPointers(char** ppa, char** ppb) 
{ 
    char* ptemp = *ppa; 
    *ppb = *ppa; 
    *ppa = ptemp; 
} 

swapPointers(&nm[0], &nm[1]); 
+0

Хммм, не совсем, Пол: `Ошибка: невозможно преобразовать параметр 1 из 'char (*) [10]' в 'char **'` Я получаю ту же ошибку с исходным кодом, который я опубликовал (и введите- кастинг создает ошибки логики во время выполнения в обоих случаях). – Cameron 2008-09-24 02:49:32

3

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

нм [a] и nm [b] очень сильно const, потому что nm - это действительно const объект. Если это не так, вы можете переместить переменные С в ОЗУ, переназначив их имена.

Просто подумайте о хаосе! Поэтому вы не можете этого сделать. :-)

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

swap(char *a, char *b) 
{ 
    char temp[MAX1]; 
    memcpy(temp, a, MAX1); 
    memcpy(b, a, MAX1); 
    memcpy(a, temp, MAX1); 
} 
+0

нм [a] и nm [b] не const. Кроме того, функция swap, которую вы написали, не очень безопасна, поскольку она позволяет любому указателю на символ. – Kevin 2008-09-24 04:38:01

+0

Если nm [a] не const, то позвольте мне видеть, как вы меняете его значение. :) – 2008-09-24 06:01:38

+0

Я думаю, что ваше объяснение могло бы быть усилено, если бы вы упомянули, что char nm [MAX1] [MAX2] фактически преобразуется компилятором в char [MAX1 * MAX2], который является просто смежной частью памяти, хранящей только символы , Забудьте о const! В массиве просто нет указателей. – Alexander 2008-09-25 22:28:19

3

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

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

char nm[MAX1][MAX2] 

в

char *nm[MAX1] 

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

1

Реальная точка, если вы используете C++, то вы должны использовать зЬй :: вектор станд :: строку вместо:

std::vector<std::string> nm; 
nm.push_back("john"); 
nm.push_back("bob"); 
nm.push_back("david"); 
std::swap(nm[0], nm[1]); 

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

Смежные вопросы