There are two problems with the second function. One, Yu Hao had identified, but has since removed, is that you have the potential for signed integer overflow.
Assuming you are only dealing with numbers that do not cause overflow, the second problem is that if the two pointers point to the same object, the object will end up with the value of 0, regardless of what value it started with.
Suppose you have variable c initialized to 17, and you call swap with swap(&c, &c):
.-----------.
\|/ |
+--'----+ +---+ +---+
| c: 17 | | a | | b |
+--.----+ +---+ +---+
/|\ |
`--------------------'
Since inside swap(), both a and b point to c, the result of the last assignment will put the value 0 into c, because *a = *a - *b would be equivalent to c = c - c.
To fix the overflow issue, you can make sure the sum never overflows by making sure the arguments have opposite signs. To fix the "point to same object" issue, just check of that inside the swap function.
void swap (int *a, int *b) {
/*...as you had it...*/
}
void s (int *a, int *b) {
if (a != b) { /* not same object */
if (*a > 0 != *b > 0) {
swap(a, b); /* not same sign */
} else {
*a = -*a;
swap(a, b);
*b = -*b;
}
}
}
As you can see, this is already considerably more complicated than employing the first version of your swap function. If you are worried that using another variable might make the program deficient in some way, put those fears aside. Nearly all compilers used for commercial development will recognize a swap, and generate the optimal code for it.
intof local variable (which might be placed in a register anyway), you are paying a penalty in performance and clarity of code. You would do far better to use the simple swap code with a temporary variable than any messing around with additions and subtractions. If you want to speed the swap up, make it intostatic inline void swap(int *a, int *b)and let the compiler optimize.