tags:

views:

126

answers:

4

I have this code fragment

int i = 5;
int k = 7;
int * iPtr;
int * jPtr;
int * kPtr;

iPtr = &i;
kPtr = &k;

I am required to swap i and k using the pointers. This is how I'm doing it:

*jPtr = *kPtr ;
*kPtr = *iPtr ;
*iPtr = *jPtr ;

Is this the best way to do it, or is there a better way?

+4  A: 

You just forgot to allocate space for the temporary variable:

int i = 5; 
int k = 7; 
int * iPtr; 
int * jPtr = new int;
int * kPtr; 

iPtr = &i; 
kPtr = &k; 
...
*jPtr = *kPtr ; 
*kPtr = *iPtr ; 
*iPtr = *jPtr ; 

delete jPtr;
AraK
Of course, the *better* way would be to make an `int j` and not make it a pointer, but I suppose that breaks the rules.
Brendan Long
yeah....its to clear concepts of Pointers (for a class), so we have to use pointers
xbonez
@Brendan The *best* way is to use `std::swap`: `std::swap(i, k);`.
AraK
@Arak no, `std::swap()` will swap the pointers, such that the `i` pointer will point to the `k` pointer and the `k` pointer will point to the `i` pointer. The original integers will still hold the same values. What you need to swap the underlying values is `std::iter_swap()`.
wilhelmtell
+4  A: 

Just for fun, this will do it without a third variable...

*iPtr ^= *kPtr;
*kPtr ^= *iPtr;
*iPtr ^= *kPtr;

It's an old assembly language trick: XOR swap algorithm

egrunin
It continues to irk me that more people seem to know about (and use) this trick than std::swap. It's a neat trick, yes, but as the wikipedia article mentions, using a temporary is very often more efficient. And really, if you crave bit twiddling, there are plenty of more interesting things in e.g. Hacker's Delight or Bit Twiddling Hacks or the like. (+1 anyway, as it's "just for fun"; I'm just being cranky.)
leander
I'm pretty sure I remember reading somewhere too that on modern CPUs with modern compilers this old hack is actually slower than declaring the new variable and using that. I haven't measured it myself of course.
Stewart
@leander - I would *never* do this in anything but assembly. The whole point of a high level language is clarity, and this is 100% opaque.
egrunin
@Stewart: yeah, if you look at the disasm, it's usually worse, provided the compiler can find a spare register. The wikipedia article that was linked here mentions this.
leander
@egrunin: Agreed. My frustration: we have a screening test for incoming candidates that asks them to fill in the body for something like `void inplace_reverse( char * null_terminated_string )` -- mostly we use this on candidates coming from 3rd and 4th year of college -- and about 80% of them jump to the XOR trick once they've set up to iterate from the beginning and end of the string. It makes me want to tear my hair out. (The problem is really intended to test for edge-case handling, not "can you swap two bytes".)
leander
+7  A: 

The best way to do that in C++, in my opinion, is with std::iter_swap():

#include<algorithm>

// ...
int *iPtr = &i, *kPtr = &k;
std::iter_swap(iPtr, kPtr);

You may think that's an overkill, but I'd disagree if you include <algorithm> anyway. Of course, in the case of a homework this answer only holds if the instructor's intent is to familiarize you with the STL. If the intent is to introduce you to pointers then the best solution is to introduce a temporary variable, j:

int j;
int *iPtr = &i, *kPtr = &k, *jPtr = &j;
*jPtr = *kPtr;
*kPtr = *iPtr;
*iPtr = *jPtr;
wilhelmtell
+1, most helpful answer.
greyfade
+1  A: 

The reason your teacher told you to use pointer is for you to be familiarized with passing address(pointer) of variables to function. So you can do this sort of thing:

void add_bonus_points(int *x)
{
    *x = *x + 100;
}

void main()
{
    int a = 2;

    printf("%d", a); // 2

    add_bonus_points(&a);
    printf("%d", a); // 102

}

Regarding swap, here's the code:

void swap(int *x, int *y)
{
    int temp;
    temp = *x;
    *x = *y;
    *y = temp;
}

void main()
{
    int a = 5;
    int b = 7;

    swap(&a, &b);
    printf("%d %d", a, b);
}
Michael Buen