Swapping in
|
In C, the mechanism above is what is used for parameters in the scanf function, which have the extra & (the "address of" operator) in front of them.
C Simple Swap Program -- Assignments | C Simple Swap Program -- Exclusive-Or |
---|---|
#include <stdio.h> int main() { int a = 23, b = 47; int t; printf("Before. a: %d, b: %d\n", a, b); t = a; a = b; b = t; printf("After. a: %d, b: %d\n", a, b); return 0; } | #include <stdio.h> int main() { int a = 23, b = 47; printf("Before. a: %d, b: %d\n", a, b); a ^= b; b ^= a; a ^= b; printf("After. a: %d, b: %d\n", a, b); return 0; } |
Runs of the two programs | |
% cc -o swap_simple0 swap_simple0.c % swap_simple0 Before. a: 23, b: 47 After. a: 47, b: 23 | % cc -o swap_simple1 swap_simple1.c % swap_simple1 Before. a: 23, b: 47 After. a: 47, b: 23 |
C Swap Program -- Fails | C Swap Program with Pointers -- Works |
---|---|
#include <stdio.h> void swap(int i, int j) { int t = i; i = j; j = t; } int main() { int a = 23, b = 47; printf("Before. a: %d, b: %d\n", a, b); swap(a,b); printf("After. a: %d, b: %d\n", a, b); return 0; } | #include <stdio.h> void swap(int *i, int *j) { int t = *i; *i = *j; *j = t; } void main() { int a = 23, b = 47; printf("Before. a: %d, b: %d\n", a, b); swap(&a, &b); printf("After . a: %d, b: %d\n", a, b); } |
Runs of the two programs | |
% cc -o swap0 swap0.c % swap0 Before. a: 23, b: 47 After. a: 23, b: 47 | % cc -o swap1 swap1.c % swap1 Before. a: 23, b: 47 After. a: 47, b: 23 |
With the program on the left, no swapping took place. The values of a and b are passed to swap, and the function does swap them, but when the function returns, nothing has changed in the main function.
To get an idea of what this code does, print it out, draw the two integers a and b, and enter 23 and 47 in them. Now draw the two pointers i and j, along with the integer t. When swap is called, it is passed the addresses of a and b. Thus, i points to a (draw an arrow from i to a) and j points to b (draw another arrow from b to j). Once the pointers are initialized by the function call, *i is another name for a, and *j is another name for b. Now run the code in swap. When the code uses *i and *j, it really means a and b. When the function completes, a and b have been swapped.
Suppose you accidentally forget the & when the swap function is called, and that the swap line accidentally looks like this: swap(a, b);. This causes a segmentation fault. When you leave out the &, the value of a is passed instead of its address. Therefore, i points to an invalid location in memory and the system crashes when *i is used.
This is also why scanf crashes if you forget the & on variables passed to it. The scanf function is using pointers to put the value it reads back into the variable you have passed. Without the &, scanf is passed a bad address and crashes. Reference parameters are one of the most common uses of pointers in C. Another way to say this is to say that the calling function is telling the called function where to find the variable.
Java BubbleSort Program | Run of the Program |
---|---|
public class BubbleSort { // swap: interchange inside array static void swap(int[] a, int i, int j) { int t = a[i]; a[i] = a[j]; a[j] = t; } // bubbleSort: very short code, but ineffient static void bubbleSort(int[] a) { for (;;) { boolean sorted = true; for (int i = 0; i < a.length - 1; i++) if (a[i] > a[i+1]) { sorted = false; swap(a, i, i + 1); } if (sorted) break; } } static void printArray(int[] a) { for (int i = 0; i < a.length; i++) { if (i%4 == 0) System.out.println(); System.out.print(a[i] + " \t"); } System.out.println(); } public static void main(String[] args) { int size = Integer.parseInt(args[0]); System.out.println("Bubblesort, size = " + size); int[] r = new int[size]; for (int i = 0; i < size; i++) r[i] = (int)(Math.random()*size*10 + 1); long startTime =System.currentTimeMillis(); bubbleSort(r); System.out.println("Elapsed time(millis) "+ (System.currentTimeMillis()-startTime)); // printArray(r); } } | % javac BubbleSort.java % java BubbleSort 60 Bubblesort, size = 60 Elapsed time (millis) 1 5 7 9 18 21 27 41 44 67 104 104 109 116 118 151 151 170 175 181 182 196 196 207 220 231 240 241 242 244 247 251 274 279 290 302 325 329 339 341 363 366 369 376 380 385 411 435 440 471 484 492 504 505 547 556 559 564 583 588 591 % java BubbleSort 100 Bubblesort, size = 100 Elapsed time (millis) 3 % java BubbleSort 1000 Bubblesort, size = 1000 Elapsed time (millis) 394 % java BubbleSort 10000 Bubblesort, size = 10000 Elapsed time (millis) 39518 % java BubbleSort 20000 Bubblesort, size = 20000 Elapsed time (millis) 158317 % java BubbleSort 40000 Bubblesort, size = 40000 Elapsed time (millis) 646717 |
Java Swapping Using a Wrapper Class |
---|
// MyInteger: similar to Integer, but can change value class MyInteger { private int x; // single data member public MyInteger(int xIn) { x = xIn; } // constructor public int getValue() { return x; } // retrieve value public void insertValue(int xIn) { x = xIn;} // insert } public class Swapping { // swap: pass references to objects static void swap(MyInteger rWrap, MyInteger sWrap) { // interchange values inside objects int t = rWrap.getValue(); rWrap.insertValue(sWrap.getValue()); sWrap.insertValue(t); } public static void main(String[] args) { int a = 23, b = 47; System.out.println("Before. a:" + a + ", b: " + b); MyInteger aWrap = new MyInteger(a); MyInteger bWrap = new MyInteger(b); swap(aWrap, bWrap); a = aWrap.getValue(); b = bWrap.getValue(); System.out.println("After. a:" + a + ", b: " + b); } } |
% javac Swapping.java % java Swapping Before: a: 23, b: 47 After: a: 47, b: 23 |
C++ Swap Program Using References | |
---|---|
#include <iostream> using std::cout; void swap(int& i, int& j) { int t = i; i = j; j = t; } int main() { int a = 23, b = 47; cout << "Before. a: " << a << ", b: " << b << "\n"; swap(a, b); cout << "After. a: " << a << ", b: " << b << "\n"; return 0; } | |
Run of the program | |
% CC -o swap_CC swap.cpp % swap_CC Before: a: 23, b: 47 After: a: 47, b: 23 |
C Swap Program Using Preprocessor |
---|
#define swap(type, i, j) {type t = i; i = j; j = t;} int main() { int a = 23, b = 47; printf("Before swap. a: %d, b: %d\n", a, b); swap(int, a, b) printf("After swap. a: %d, b: %d\n", a, b); return 0; } |
Preprocessed Output |
% cc -E swap_p.c int main() { int a = 23, b = 47; printf("Before swap. a: %d, b: %d\n", a, b); { int t = a ; a = b ; b = t ; } printf("After swap. a: %d, b: %d\n", a, b); return 0; } |
Run of the program |
% cc -o swap_p swap_p.c % swap_p Before swap: a: 23, b: 47 After swap: a: 47, b: 23 |