Я пытаюсь написать функцию подкачки, используя указатель (особенно пустой указатель) по ссылке, но мой код не работает. Вот мой код:
void swap(void *p1,void *p2)
{
int temp;
temp=*((int*)p2);
p2=p1;
p1=&temp;
}
int main()
{
int i=4;
int j=5;
cout<<i<<j<<endl;
swap(&i,&j);
cout<<i<<j<<endl;
return 0;
}
Куда я иду не так?
Код не работает, потому что вы не разыменовываете указатели на назначения. Так должно быть
*((int*)p2)=*((int*)p1);
*((int*)p1)=temp;
Обратите внимание, что вы делаете предположение, что void*
указывает на int
что, очевидно, не всегда так. По сути, вы могли бы также заменить void*
с int*
и избавиться от слепков.
Более общий случай API должен выглядеть следующим образом:
void swap(void *p1,void *p2, size_t sz)
Внутренне API должен выделить буфер размера sz
, делать memcpy
в него, а затем сделать обмен, снова используя memcpy
,
В теле функции вы меняете значения p1
а также p2
; ты не хочешь этого делать. Вы хотите поменять значения того, что p1
а также p2
указать на:
void swap(int *p1, int *p2)
{
int tmp = *p1;
*p1 = *p2;
*p2 = tmp;
}
Я знаю, что ты хотел использовать void *
за ваши аргументы. Не. Вы должны были бы привести их к соответствующему типу цели, чтобы выполнить назначения так или иначе:
int tmp = *(int *) p1;
*(int *) p1 = *(int *) p2;
*(int *) p2 = tmp;
Тьфу. Вы ничего не спасаете, приводя аргументы void *
,
Поскольку вы, очевидно, пишете на C ++, вы можете сделать функцию универсальной, используя шаблон:
template<typename T>
void swap(T *p1, T *p2)
{
T tmp = *p1;
*p1 = *p2;
*p2 = tmp;
}
Еще лучше использовать шаблон и Рекомендации, так что вы вообще не имеете дело с указателями:
template<typename T>
void swap(T &p1, T &p2)
{
T tmp = p1;
p1 = p2;
p2 = tmp;
}
используя функции памяти
void swap (void *vp1, void *vp2, const int size) {
char *buffer = (char *)malloc(sizeof(char)*size);
memcpy(buffer, vp1, size);
memcpy(vp1, vp2, size);
memcpy(vp2, buffer, size);
free(buffer);
}
int main()
{
int a = 10, b = 20;
printf("%d %d"a,b);
swap(&a, &b, sizeof(int));
printf("%d %d"a,b);
}
Output is:
10 , 20
20 , 10
если мы не знаем тип данных, тогда мы используем void.
Вы изменяете копии указателей, а не их содержимое.
Вы должны сделать что-то вроде этого (просто показать вам идею, это не будет работать без приведения, и это все равно не будет хорошей идеей):
temp = *p2
*p2 = *p1;
*p1 = temp;
Вам понадобятся указатели на указатели, если вы хотите поменять местами указатели:
void swap(void** ptr1, void** ptr2);
или ссылки на указатели:
void swap(void*& ptr1, void*& ptr2);
Или, поскольку вы, очевидно, используете C ++, вы можете использовать ссылки и шаблоны для обмена данными любого типа. Но вы уверены, что поняли все основы языка?
Удачи
Попробуй это:
#include <iostream>
using namespace std;
void swap( void *a, void *b ) {
int tmp = *( ( int* )a );
*( ( int* )a ) = *( ( int* )b );
*( ( int* )b ) = tmp;
}
int main() {
int a, b;
cin >> a >> b;
swap( &a, &b );
cout << a << " " << b;
return 0;
}
Прежде чем разыменовывать указатели a и b, вы должны сначала преобразовать их в int*
, После этого вы просто выполняете обмен.
Замечания: Вам не нужно проходить void*
в качестве параметра. Если вы пройдете int*
с, это будет также правильно (и более читабельным).
Заметка 2]: Поскольку вы программируете на C ++, вы можете использовать вместо ссылок указатели.
попробуйте ниже код:
#include <iostream>
using namespace std;
void Swap(int **ptr1, int **ptr2){
// Swapping the contents of p1 and p2 in the driver function
int *temp;
temp = *ptr1;
*ptr1 = *ptr2;
*ptr2 = temp;
// Swapping the contents of x and y in the driver function
int temp;
temp = **ptr1;
**ptr1 = **ptr2;
**ptr2 = temp;
}
int main(){
int x = 10, y = 15;
int *p1 = nullptr;
p1 = &x;
int *p2 = nullptr;
p2 = &y;
cout << x << ' ' << y << endl;
cout << *p1 << ' ' << *p2 << endl;
Swap(&p1,&p2);
cout << x << ' ' << y << endl;
cout << *p1 << ' ' << *p2 << endl;
}