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
Compilers can produce warnings - make the compiler programmers happy: Use them!
Please don't PM me for help - and no, I don't do help over instant messengers.
Compilers can produce warnings - make the compiler programmers happy: Use them!
Please don't PM me for help - and no, I don't do help over instant messengers.
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.
Last edited by iMalc; 02-02-2008 at 02:46 AM.
My homepage
Advice: Take only as directed - If symptoms persist, please see your debugger
Linus Torvalds: "But it clearly is the only right way. The fact that everybody else does it some other way only means that they are wrong"
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![]()
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
Compilers can produce warnings - make the compiler programmers happy: Use them!
Please don't PM me for help - and no, I don't do help over instant messengers.
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); }
Last edited by iMalc; 02-02-2008 at 07:41 PM.
My homepage
Advice: Take only as directed - If symptoms persist, please see your debugger
Linus Torvalds: "But it clearly is the only right way. The fact that everybody else does it some other way only means that they are wrong"
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!Originally Posted by iMalc
By switching to C++ and using templates.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![]()
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
Compilers can produce warnings - make the compiler programmers happy: Use them!
Please don't PM me for help - and no, I don't do help over instant messengers.
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![]()