Templates of course:
Code:template<typename T> void Swap(T& Arg1, T& Arg2)
{
T Temp = Arg1;
Arg1 = Arg2;
Arg2 = Temp;
}
Printable View
Yes, but it's only (a little bit) handier than the macro I wrote:
Yes, the do-while stuff is a bit ugly, but that's about it.Code:#define SWAP(T, A, B) do { T temp = (A); (A) = (B); (B) = temp; } while(0)
And of course, you have to specify the type, and it doesn't work with arrays, before anyone else points that out.
--
Mats
But then you also have to specify type and it doesn't work with arrays, so C is still somewhat limited when it comes to stuff like this :)
And as we all know, debugging macros can be a pain, for one...
It's easier, at least...
But I'm guessing that's not standard, so if you want to rely on compiler specific extensions, then sure.Quote:
By the way gcc for example supports a typeof, so you can do:
Code:#define SWAP(A, B) do { typeof(A) temp = A; A = B; B = temp } while(0)
That can work with arrays, you just have to use the type of item in the array for T instead of the array type, and use the [] syntax for A and B.
However, it's still far inferrior to what you would use in C++:
if A or B have side effects then they get executed twice.
No support for copying of objects since you can't define an assignment operator.
Macros are evil and polluting.
You have to tell it the type, instead of letting the compiler handle that.
Explicit specialisations of swap can be given in C++ to allow certain objects to be swapped more efficiently. The caller doesn't have to care about this.
Debugging template code is not really harder than non-templated code, but debugging macros is much worse! (It's the compile-time errors that are the tricker part when it comes to template code)
Having said that, if I were forced to use C, I would do the same as above.
I tried the following function which was suggested:
and found that it doesn't work as expected. I understand why too. Anyway I changed it, and now it looks like this with changes highlighted (sorry I changed variable names too):Code:void Swap(void** pA, void** pB)
{
void** pTemp = pA;
*pA = *pB;
*pB = *pTemp;
}
The problem before was that in the first case, was that by doing pTemp=pA the other two lines became essentially: *pA=*pB and *pB=*pTemp=*pA=*pB (where the last two equals signs are in the mathematical sense and not assignment operators) due to the previous line and so essentially what you are doing is:Code:void Swap_VTP(void **App,void **Bpp)
{
// Declare variables
void *Cpp
// Perform pointer swap
Cpp=*App;
*App=*Bpp;
*Bpp=Cpp;
}
which doesn't achieve the swap. My changed version solves that issue. Just thought I would point that out in case someone else reads this thread in the future.Code:*pA=*pB;
*pB=*pB;
Philipp
PS It's almost impossible to format your posts how you want to with these editors!!
I believe that's how it should be, yes? That's what happens when you post code that you don't test...Code:void Swap(void** pA, void** pB)
{
void* pTemp = *pA;
*pA = *pB;
*pB = pTemp;
}
Btw, use Firefox + Tab in Textarea extension. This will allow you to use tabs in the editor!
Otherwise just write the code in your IDE and copy it here.
As I said earlier, I am trying to take this further to write a general purpose sort routine. The swapping works fine, but another problem has arisen. I need a criteria by which the data is sorted. I'm assuming that for whatever I will be sorting the < and > operators will be defined (like for char,__intn,double etc...). The only problem is that I don't know how I am actually supposed to compare two data entries as I am only working with void pointers (Array_Ptr would be a pointer to a void so I can't do Array_Ptr[i]). Here is (basically) the normal bubblesort function/algorithm:
If I try to change this so that the function is compatible for any type of data to sort, I can use void pointers and add an argument 'size_t Size' so that I can still perform the swap, but I don't know what to do with the highlighted section.Code:do
{
Done=true;
for(i=0;i<Num_of_Elem-1;i++)
{
if(Array_Ptr[i]>Array_Ptr[i+1])
{
Swap(Array_Ptr+i,Array_Ptr+i+1);
Done=false;
}
}
}
while(!Done);
Any ideas?
Thx,
Philipp :confused:
I'd say that without knowing what type of data you're sorting, you can't sort. Or at least I'm tempted to say so. It will probably behave wrong when sorting one type and right when sorting one.
The way that the library function qsort() solves this problem is by calling back to a function that compares the two items - just pass the address of your two items to the a functionThis function should return an integer that is less than, equal to or greater than zero if a is less than, equal to or greater than b.Code:int comparefunc(void *a, void *b);
Sine the compare function is given by the caller, you don't have to pass a size, as the caller of the sort function should know what type to cast a and b into.
--
Mats
You can improve Bubblesort beyond using a mere boolean flag!
In C++ I'd do it like this:Code:template <class T>
void BubbleSort(T a[], int n) {
int sinker = n-1;
do {
int floater = 0;
for (int i = 0; i < sinker; ++i) {
if (a[i + 1] < a[i]) {
Swap(a[i], a[i + 1]);
floater = i;
}
}
sinker = floater;
} while (sinker > 0);
}
My programming environment is C/C++, meaning that I can write a mash of the two, so I tried to create a basic test template function and it worked. That should mean that everything becomes much much easier to do and I can write my sort function. The rest of my program is still in C tho.
Looks like that is what I did!! Never expected that I would really take that advice did you! lol!:DQuote:
Originally Posted by iMalc
By switching to C++ and using templates.Quote:
Originally Posted by starcatcher
I would like to expand on this function so that it can be used with parameters which are pointers to any type. That is, I would like to create a function that can swap two objects of any type pointed to by two pointers. In the above example only integers can be swapped. What would be the easiest way of doing that?
Hey, it's the truth - there isn't any easier way!
Thank you everyone who helped me and I hope that that finally puts this subject to rest!
Philipp:cool:
Bear in mind that your effort to sort things will always be rather a learning experience than an improvement on anything existing - the C environment has a qsort/heapsort implemented in the standard library, and C++ has a couple of sort mechanisms "ready to use" already too. It's quite unlikely that you will improve on these two - but it's a great learning experience to try it out, especially to make it work for "all types".
--
Mats
I have realised that. I would like to compare my sort function(s) against those that are inbuilt to see really how much slower they are so I get an idea. Again, it's a formative excercise, and what do you know, I've already learnt about templates and void pointers and all that, which I think is great.
Philipp;)