swap addresses ?

Discussion in 'C Programming' started by pras.vaidya, Jul 23, 2005.

  1. pras.vaidya

    pras.vaidya Guest

    hi, please help me with this problem : -

    how to swap two addresses .For eg variable i is located at 2000 and j
    at 3000 . Now i call swap function . Result should be that i should be
    now having address 3000 and j should be having 2000.

    Is it the normal swapping of two number ? if no please help me out.

    Thanks in advance
     
    pras.vaidya, Jul 23, 2005
    #1
    1. Advertisements

  2. pras.vaidya

    osmium Guest

    Something like this:

    int i, j,temp;
    /* give values to i and j*/
    temp = i;
    i = j;
    j = temp;

    That is the *right* way to do it. A question such as this may invoke some
    so called "cute" digressions.

    Note that we didn't swap the address, we swapped the variables. I followed
    your description, not your message title. The numbers 2000 and 3000 have
    nothing to do with it - high level programmers are not supposed to know the
    numbers of addresses. They deal in variable *names*.
     
    osmium, Jul 23, 2005
    #2
    1. Advertisements

  3. pras.vaidya

    Malcolm Guest

    Nearly.
    If you use the identifiers "i" and "j" for your variables in C you have no
    control over the address.

    temp = i;
    i = j;
    j = temp;

    will swap them

    If you have pointers to the variables, such that ptr2k holds the address
    "2000" and ptr3k holds the address "3000", in your platform-dependent
    machine representation, then you can do this.

    int temp = *ptr2k;
    *ptr2k = *ptr3k;
    *ptr3k = temp;

    That will swap the contents of those addresss
     
    Malcolm, Jul 23, 2005
    #3
  4. pras.vaidya

    Joe Wright Guest

    And if you really want to swap addresses..

    void *temp = ptr2k;
    ptr2k = ptr3k;
    ptr3k = temp;
     
    Joe Wright, Jul 23, 2005
    #4
  5. pras.vaidya

    Sorav Bansal Guest

    Perhaps, this will qualify as a "cute" digression. But nonetheless, the
    following code is more efficient in terms of both space and time:

    void
    swap (int i, int j)
    {
    i = i ^ j ;
    j = i ^ j ;
    i = i ^ j ;
    }
     
    Sorav Bansal, Jul 23, 2005
    #5
  6. pras.vaidya

    Sorav Bansal Guest

    Perhaps, this will qualify as a "cute" digression. But nonetheless, the
    Oops, the function should be replaced by a macro (since all parameters
    are call-by-value in C):
    something like:

    #define swap(i,j) do { i=i^j; j=i^j; i=i^j; } while (0)
     
    Sorav Bansal, Jul 23, 2005
    #6
  7. Are i and j the same type? Are they the same size? Is it certain
    that the location of i is suitably aligned for a value of j's type
    (and vice versas) ?
     
    Walter Roberson, Jul 23, 2005
    #7
  8. pras.vaidya

    Ben Pfaff Guest

    Please read the FAQ.

    20.15c: How can I swap two values without using a temporary?

    A: The standard hoary old assembly language programmer's trick is:

    a ^= b;
    b ^= a;
    a ^= b;

    But this sort of code has little place in modern, HLL
    programming. Temporary variables are essentially free,
    and the idiomatic code using three assignments, namely

    int t = a;
    a = b;
    b = t;

    is not only clearer to the human reader, it is more likely to be
    recognized by the compiler and turned into the most-efficient
    code (e.g. using a swap instruction, if available). The latter
    code is obviously also amenable to use with pointers and
    floating-point values, unlike the XOR trick. See also questions
    3.3b and 10.3.
     
    Ben Pfaff, Jul 23, 2005
    #8
  9. Sorav Bansal wrote on 23/07/05 :
    Lack of parenthesis around the parameters, multiple evaluation of the
    parameters, non portable code, you are cooked ! (^ works portably on
    unsigned integer types)

    --
    Emmanuel
    The C-FAQ: http://www.eskimo.com/~scs/C-faq/faq.html
    The C-library: http://www.dinkumware.com/refxc.html

    "Mal nommer les choses c'est ajouter du malheur au
    monde." -- Albert Camus.
     
    Emmanuel Delahaye, Jul 23, 2005
    #9
  10. pras.vaidya

    CBFalconer Guest

    It is a herd of errors waiting to trap you. Try calling it with:

    swap(a, a[j]);

    oh, you are going to make the passed items pointers. Alright, then
    try the same swap when i == j and see what you get. Read the FAQ.
     
    CBFalconer, Jul 24, 2005
    #10
  11. Several people have offered possible solutions, but I'm not sure that
    anybody understands what you're asking. I know I don't.

    A variable's address is determined when the variable is created, and
    doesn't change over the lifetime of the variable. Changing the
    address of a variable doesn't even make sense; if it has a different
    address, it's a different variable.

    Just to add to the confusion, you tell us that the addresses are 2000
    and 3000. It's important to keep in mind that addresses are not
    integers (though they might sometimes be represented that way).

    The closest thing I can think of to what you're asking for is to
    declare two variables, then declare two pointers that point to them.
    You can then swap the values of the pointer variables. Swapping two
    variables is (or should be) very straightforward, whether they're
    pointers or anything else; others have posted examples using a
    temporary variable.

    If you can clarify what you're asking for, perhaps we can help.
     
    Keith Thompson, Jul 24, 2005
    #11
  12. Nice Cajun-speak there. Well done, sir.
    I think it is perfectly clear what he is asking for.

    And that the answer is, as it is to most questions asked here, that it
    can't be done in standard C.
     
    Kenny McCormack, Jul 24, 2005
    #12
  13. On almost every single processor that I've ever worked on, that is
    simply false. Additionally, it will give the wrong result when both
    variables have the same value.

    Put simply, don't do it.
     
    Clark S. Cox III, Jul 25, 2005
    #13
  14. pras.vaidya

    Antonio Guest

    <added code we're talking about>

    i ^= j;
    j ^= i;
    i ^= j;
    Wrong. It still works if both variables have the same value. See the
    breakdown just below:

    int a = SOME_VALUE_WE_DONT_CARE_ABOUT;
    int i = a;
    int j = a;

    i ^= j; // Effectively i = i ^ j = a ^a = 0. So after this step i = 0,
    j = a;
    j ^= i; // j = j ^ i = a ^ 0 = a; After this step i = 0, j = a;
    i ^= j; // i = i ^ j = 0 ^ a = a; Finally i = a, j = a;

    As you can see it still works if both variables have the same value.

    The problem arises when the two variables are the same variable, as in
    the following code:

    void swap (int *i, int *j) {
    *i ^= *j;
    *j ^= *i;
    *i ^= *j;
    }

    int main (int argc, char **argv) {
    int a = SOME_VALUE_WE_DONT_CARE_ABOUT;

    swap (&a, &a);
    printf("%d\n", a);
    }

    In this case in the swap function we have:

    *i ^= *j; // ==> a ^= a ==> a = a ^ a = 0;
    *j ^= *i; // ==> a ^= a ==> a = a ^ a = 0 ^ 0 = 0;
    *i ^= *j; // ==> a ^= a ==> a = a ^ a = 0 ^ 0 = 0;

    So we end up with a 0 in a, not the initial value as was intended.
    Agreed.
     
    Antonio, Jul 25, 2005
    #14
  15. pras.vaidya

    Chris Dollin Guest

    It certainly is, since it can be optimised to

    void swap( int i, int j ) {}

    and this is futher subject to cheap inlining.

    However, it's semantics are a tad unlike any kind of swap function.
     
    Chris Dollin, Jul 26, 2005
    #15
    1. Advertisements

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments (here). After that, you can post your question and our members will help you out.