COP 3223H meeting -*- Outline -*- * examples using pointers ** capturing patterns of assignments *** swap ------------------------------------------ SWAPPING PATTERN How do you swap the values of 2 variables x and y? int x; int y; // code to swap them ------------------------------------------ ... int temp = x; x = y; y = temp; Q: Is it annoying to have to do that several times in code? Yes Q: How can we fix annoying repeated code like that? write a function! ------------------------------------------ A FAILED ATTEMPT AT A FUNCTION #include #include // wrong! void wrong_swap(int x, int y) { int temp = x; x = y; y = temp; } // demonstrate problem with wrong_swap int main() { int a = 9; int b = 100; printf("a is %d and b is %d\n", a, b); printf("calling wrong_swap(a, b)\n"); wrong_swap(a, b); printf("a is %d and b is %d\n", a, b); return 0; } ------------------------------------------ Q: What's wrong with this? it only affects the locals x and y, not the caller's arguments ------------------------------------------ SWAP FUNCTION How can we swap the values in the caller's variables? void swap( ------------------------------------------ ... use pointers! ... void swap (int *px, int *py) { int temp; temp = *px; *px = *py; *py = temp; } See swap.c, test_swap.c. ------------------------------------------ INSERTION SORT Want to put the elements of an array of ints, a, into nondecreasing order so that if sz is the size of a, then for all 0 <= i < j < sz: a[i] <= a[j] Algorithm: compare all pairs a[i] and a[j], swap them if they are out of order #include "swap.h" // requires: a is allocated and has elements with indexes low to high-1 // ensures: result is true just when the elements a[low .. high-1] // are in non-decreasing order extern bool sorted(const int a[], int low, int high); // requires: a is allocated and has at least sz elements // assigns: a[*] // ensures: for all 0 <= i < j < sz: a[i] <= a[j] void bubble_sort(int a[], int sz) { int i = 1; ok(sorted(a, 0, i) && i <= sz, "for invariant"); for (i = 1; i < sz; i++) { int j = i; ok(sorted(a, j, i) && i <= sz && 0 <= j && j <= i, "init while invariant"); while (0 < j && a[j-1] > a[j]) { swap(&a[j-1], &a[j]); ok (a[j-1] < a[j], "swap restored order"); j -= 1; ok(sorted(a, j, i) && i <= sz && 0 <= j && j <= i, "while invariant again"); } ok(sorted(a, 0, i), "sorted to %d", i); ok(i <= sz, "i <= sz"); ok(sorted(a, 0, i) && i <= sz, "for invariant again"); } ok(sorted(a, 0, i) && i == sz, "for invariant"); ok(sorted(a, 0, sz), "postcondition"); } ------------------------------------------ draw pictures of this process and the invariant see bubble_sort.c ** multi-assign ------------------------------------------ MULTIPLE ASSIGNMENT Python has a statement of the form x,y = E1, E2 which evaluates E1 and E2, then assigns them to x and y. How can we write this in C? ------------------------------------------ ... /* requires: *px and *py are allocated and px != py assigns: *px and *py effect: *px == e1 and *py == e2; */ void multi_assign(int *px, int *py, const int e1, const int e2) { *x = e1; *y = e2; } Why the precondition px != py? It's impossible to achieve the postcondition if that is false!