I need to create a swap function that takes 2 addresses as input and swaps them regardless what type they point to. Here's my swap function:
void swap(void* x,void* y){
void* temp=x;
x=y;
y=temp;
}
When I use it with integers it works fine and swaps them properly, but using strings the addresses seems to swap inside the function but when I try to call them from outside the function I notice they didn't change at all.
Here's my full code and the resulting output.
printf("before %s %s\n",(char*)array[i],(char*)array[j] );
swap(array[i], array[j]);
printf("after %s %s\n",(char*)array[i],(char*)array[j] );
I casted everything to string to understand what was wrong with them
void swap(void* x,void* y){
printf(" after IN %s %s\n",(char*)x,(char*)y );
void* temp=x;
x=y;
y=temp;
printf(" after IN %s %s\n",(char*)x,(char*)y );
}
OUTPUT
before fannullone falafel
after IN fannullone falafel
after IN falafel fannullone
after fannullone falafel
CodePudding user response:
To swap two objects in a function you need to pass them to the function by reference.
In C passing by reference means passing objects indirectly through pointers to them. So dereferencing the pointers the function gets a direct access to the original objects and can change them.
So for objects of the type void *
the function parameters will have the type void **
. The function will look like
void swap( void **x, void **y )
{
void *temp = *x;
*x = *y;
*y = temp;
}
Here is a demonstration program.
#include <stdio.h>
void swap( void **x, void **y )
{
void *temp = *x;
*x = *y;
*y = temp;
}
int main( void )
{
void *s1 = "Hello";
void *s2 = "World";
printf( "s1 = %s, s2 = %s\n", ( char * )s1, ( char * )s2 );
swap( &s1, &s2 );
printf( "s1 = %s, s2 = %s\n", ( char * )s1, ( char * )s2 );
}
The program output is
s1 = Hello, s2 = World
s1 = World, s2 = Hello
CodePudding user response:
It cannot be done with a function because there is no generic pointer to pointer in C. For example the type void**
is not compatible with char**
. Technically, those pointers could have different representation what would disallow dereferencing after casting or using memcpy()
.
Therefore, it is better to use a macro:
#define SWAP(a, b) \
do { \
void *tmp = *(a); \
*(a) = *(b); \
*(b) = tmp; \
} while (0)