Thread: single swap for char,short,int,float,double

  1. #1
    Big & Little Wong Tin-Bar Jackie Chan's Avatar
    Join Date
    May 2008
    Location
    Hong Kong
    Posts
    23

    single swap for char,short,int,float,double

    Code:
    #include <stdio.h>
    
    void swap(void *a, void *b) {
    	void *t;
    	t = a;
    	a = b;
    	b = t;
    }
    
    int main() {
    	int i, j;
    	double f, g;
    	i = 1;
    	j = 2;
    	f = 1.1;
    	g = 2.2;
    	printf("Before: %d, %d & %f, %f\n", i,j, f,g);
    	swap(&i, &j);
    	swap(&f, &g);
    	printf("After: %d, %d & %f, %f\n", i,j, f,g);
    	return 0;
    }
    I tried to write a generic swap() for char,short,int,long,float,double all the standard data types. But it is not working the way I thought it will

  2. #2
    Registered User
    Join Date
    Apr 2007
    Location
    Sydney, Australia
    Posts
    217
    I suppose you could do something like this:

    Code:
    void swap(void *a, void *b, size_t dataSize)
    {
      void *t = malloc(dataSize);
      memcpy(t, a, dataSize);
      memcpy(a, b, dataSize);
      memcpy(b, t, dataSize);
      free(t);
    }
    
    int a = 32;
    int b = 64;
    swap(&a, &b, sizeof(int));

  3. #3
    Super unModrator
    Join Date
    Dec 2007
    Posts
    321
    Jackie Chan: I think a,b,t are local pointers in swap() that's why your program is not working. You can do this by passing by reference.
    Last edited by abh!shek; 05-23-2008 at 03:53 AM.

  4. #4
    Ex scientia vera
    Join Date
    Sep 2007
    Posts
    477
    No, this is because you're just trying to swap the pointers.

    You would have to dereference the pointers and swap the values, but unfortunately, void pointers cannot be dereferenced.

    I'm not sure if it's even possible to create a generic swap function using void pointers - AFAIK, you'll be forced to cast the voids to some type and swap them.

    Maybe someone wiser than I can help you out.

    .. Cue matsp
    "What's up, Doc?"
    "'Up' is a relative concept. It has no intrinsic value."

  5. #5
    C++ Witch laserlight's Avatar
    Join Date
    Oct 2003
    Location
    Singapore
    Posts
    28,413
    If you wanted to write swap() to swap ints, you might write:
    Code:
    void swap(int *a, int *b) {
        int *t;
        *t = *a;
        *a = *b;
        *b = *t;
    }
    Changing int to void will not work since you cannot create objects of type void. I suspect that if you want a generic swap, you have to do something like this:
    Code:
    void swap(void *a, void *b, size_t size) {
        void *t = malloc(size);
        memcpy(t, a, size);
        memcpy(a, b, size);
        memcpy(b, t, size);
        free(t);
    }
    and assume and a and b point to objects of the same type.

    Update: oh, 39ster has the same idea, that's good.
    Last edited by laserlight; 05-23-2008 at 04:00 AM. Reason: The assumption should be of type, not size, only.
    Quote Originally Posted by Bjarne Stroustrup (2000-10-14)
    I get maybe two dozen requests for help with some sort of programming or design problem every day. Most have more sense than to send me hundreds of lines of code. If they do, I ask them to find the smallest example that exhibits the problem and send me that. Mostly, they then find the error themselves. "Finding the smallest program that demonstrates the error" is a powerful debugging tool.
    Look up a C++ Reference and learn How To Ask Questions The Smart Way

  6. #6
    Banned
    Join Date
    Nov 2007
    Posts
    678
    The IDEA given above is much better than what I was about to reply to.
    I know there are many C whiz kids on this block!

  7. #7
    Banned
    Join Date
    Nov 2007
    Posts
    678

    anyways ...

    Here is my version, very simple also:
    Code:
    #define SWAP(a, b, TYPE)  {\
                    TYPE t;\
                    t = a;\
                    a = b;\
                    b = t;}
    Works with standard data-types only.

  8. #8
    Kernel hacker
    Join Date
    Jul 2007
    Location
    Farncombe, Surrey, England
    Posts
    15,677
    Another possibility is to (ab)use macros:
    Code:
    #define SWAP(a, b, T) do { T t; t = a; a = b; b = t; } while(0)
    This works for all types that are assignable (so, essentially all but arrays).

    Usage something like this:
    Code:
    float x = 7f; 
    float y = 8f;
    SWAP(x, y, float);
    double d1 = 5.0;
    double d2 = 6.0;
    SWAP(d1, d2, double);
    If you have a compiler that supports typeof() [e.g. gcc], you could even do:
    Code:
    #define SWAP(a, b) do { typeof(a) t; t = a; a = b; b = t; } while(0)


    --
    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.

  9. #9
    Algorithm Dissector iMalc's Avatar
    Join Date
    Dec 2005
    Location
    New Zealand
    Posts
    6,318
    Bring on the auto keyword!
    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"

  10. #10
    and the hat of copycat stevesmithx's Avatar
    Join Date
    Sep 2007
    Posts
    587
    Quote Originally Posted by matsp View Post
    Another possibility is to (ab)use macros:
    Code:
    #define SWAP(a, b, T) do { T t; t = a; a = b; b = t; } while(0)
    This works for all types that are assignable (so, essentially all but arrays).

    Usage something like this:
    Code:
    float x = 7f; 
    float y = 8f;
    SWAP(x, y, float);
    double d1 = 5.0;
    double d2 = 6.0;
    SWAP(d1, d2, double);
    If you have a compiler that supports typeof() [e.g. gcc], you could even do:
    Code:
    #define SWAP(a, b) do { typeof(a) t; t = a; a = b; b = t; } while(0)


    --
    Mats
    Can somebody please explain why do{ }while(0) is used in the above code.
    I understand that it is used to make sure the code inside is executed atleast/atmost once.
    Can the same result can be got without it ?
    Not everything that can be counted counts, and not everything that counts can be counted
    - Albert Einstein.


    No programming language is perfect. There is not even a single best language; there are only languages well suited or perhaps poorly suited for particular purposes.
    - Herbert Mayer

  11. #11
    C++ Witch laserlight's Avatar
    Join Date
    Oct 2003
    Location
    Singapore
    Posts
    28,413
    Bring on the auto keyword!
    It already exists in C. I suspect that you are thinking of C++0x.

    Can somebody please explain why do{ }while(0) is used in the above code.
    I understand that it is used to make sure the code inside is executed atleast/atmost once.
    Can the same result can be got without it ?
    It is a trick to allow the macro to be used in contexts where it would otherwise be problematic. Consider:
    Code:
    if (x)
        swap(a, b, int);
    Quote Originally Posted by Bjarne Stroustrup (2000-10-14)
    I get maybe two dozen requests for help with some sort of programming or design problem every day. Most have more sense than to send me hundreds of lines of code. If they do, I ask them to find the smallest example that exhibits the problem and send me that. Mostly, they then find the error themselves. "Finding the smallest program that demonstrates the error" is a powerful debugging tool.
    Look up a C++ Reference and learn How To Ask Questions The Smart Way

  12. #12
    Big & Little Wong Tin-Bar Jackie Chan's Avatar
    Join Date
    May 2008
    Location
    Hong Kong
    Posts
    23
    Thank you 39ster, abh!shek, IceDane, laserlight, manav, matsp and others also who asked more questions to make it more clear.


  13. #13
    and the hat of copycat stevesmithx's Avatar
    Join Date
    Sep 2007
    Posts
    587
    Quote Originally Posted by laserlight View Post
    It is a trick to allow the macro to be used in contexts where it would otherwise be problematic. Consider:
    Code:
    if (x)
        swap(a, b, int);
    Sorry if I bothered you,but I still can't get it.
    The code you have mentioned runs just fine on
    my system even after I remove the do while(0).
    Code:
    #include <stdio.h>
    #include <string.h>
    #define SWAP(a, b, T) {T t; t = a; a = b; b = t;}
    
    int main()
    {
        float x = 7.0f;
        float y = 8.0f;
        double d1 = 5.0;
        double d2 = 6.0;
        int a=10;
        int b=6;
        if(x)
            SWAP(a,b,int);
        SWAP(x, y, float);
        SWAP(d1, d2, double);
        printf("%f %f\n",x,y);
        printf("%f %f\n",d1,d2);
        printf("%d %d\n",a,b);
        return 0;
    }
    Is there anything i am doing wrong here?
    Not everything that can be counted counts, and not everything that counts can be counted
    - Albert Einstein.


    No programming language is perfect. There is not even a single best language; there are only languages well suited or perhaps poorly suited for particular purposes.
    - Herbert Mayer

  14. #14
    Woof, woof! zacs7's Avatar
    Join Date
    Mar 2007
    Location
    Australia
    Posts
    3,459
    Anything wrong with a bitwise swap, along with a bit of macro abuse? (Hence no typeof() or 3rd var of the type required)

    Providing they're the same type isn't it valid? (I'd think so).
    Last edited by zacs7; 05-24-2008 at 06:30 AM.

  15. #15
    The larch
    Join Date
    May 2006
    Posts
    3,573
    Quote Originally Posted by stevesmithx View Post
    Sorry if I bothered you,but I still can't get it.
    The code you have mentioned runs just fine on
    my system even after I remove the do while(0).
    Try with
    Code:
    if(x)
        SWAP(a,b,int);
    else
        SWAP(x, y, float);
    The do... while(0) trick prevents a stray semicolon appearing in the statement. (It converts multiple statements into a single do...while statement.)

    Anything wrong with a bitwise swap, along with a bit of macro abuse? (Hence no typeof() or 3rd var of the type required)

    Providing they're the same type isn't it valid? (I'd think so).
    I think it has problems if swapping a variable with itself. It also wouldn't work for doubles and floats...?
    Last edited by anon; 05-24-2008 at 07:26 AM.
    I might be wrong.

    Thank you, anon. You sure know how to recognize different types of trees from quite a long way away.
    Quoted more than 1000 times (I hope).

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. linked list swap function
    By Axel in forum C Programming
    Replies: 32
    Last Post: 01-16-2011, 09:40 AM
  2. using swap to make assignment operator exception safe
    By George2 in forum C++ Programming
    Replies: 9
    Last Post: 01-10-2008, 06:32 AM
  3. Single Entry Single Exit
    By robwhit in forum C Programming
    Replies: 5
    Last Post: 11-11-2007, 01:34 PM
  4. Binary Search Trees Part III
    By Prelude in forum A Brief History of Cprogramming.com
    Replies: 16
    Last Post: 10-02-2004, 03:00 PM
  5. fancy strcpy
    By heat511 in forum C++ Programming
    Replies: 34
    Last Post: 05-01-2002, 04:29 PM