Programmieren in C Strukturen und Zeiger Prof. Dr. Nikolaus Wulff
Sortieren Im Praktikum wurde ein Modul zum Sortieren entwickelt. Es enthält verschiedene Sortieralgorithmen, die ausgewählt und erweitert werden können. Die Auswahl des jeweiligen Algorithmus geschah in einem switch-case Verteiler. Dies lässt sich allerdings auch mit Zeigern auf Funktionen bewerkstelligen, was Gegenstand dieser Lektion ist. Prof. Dr. Nikolaus Wulff Programmieren in C 2
Der switch-case Verteiler * dispatch according to preselected mode void sorter(int length, int array[]) { switch(mode) { case SELECTION_SORT: printf("using Selection Sort \n"); selection_sort(length,array); break; case BUBBLE_SORT: printf("using Bubble Sort \n"); bubble_sort(length,array); break; case QUICK_SORT: default: printf("using Quick Sort \n"); quick_sort(length, array); break; end switch Prof. Dr. Nikolaus Wulff Programmieren in C 3
Bubble Sort * bubble sort algorithm static void bubble_sort(int length, int array[]) { int i,sorted = FALSE; length--; while(!sorted) { sorted = TRUE; for(i=0;i<length;i++) { if (cmp(array[i+1],array[i])) { sorted = FALSE; swap(array,i,i+1); /* end i-loop /* end while-loop Vertausche benachbarte Elemente solange, bis alle die kleiner Relation erfüllen. Prof. Dr. Nikolaus Wulff Programmieren in C 4
Selection Sort * selection sort algorithm static void selection_sort(int length, int array[]) { int min; int i,j; for(i=0;i<length;i++) { min=array[i]; for(j=i;j<length;j++) { if (cmp(array[j],min)) { min = array[j]; swap(array,i,j); /* end j-loop /* end i-loop Finde das jeweils kleinste Element im Feld und verkürze dann die Feldlänge um eins. Prof. Dr. Nikolaus Wulff Programmieren in C 5
Quick Sort * recursive quick sort algorithm static void q_sort(int left, int right, int array[]) { int p; if (left >= right) return; /* we are done... p = quick_partion(left, right, array); q_sort(left, p-1,array); /* sort left part q_sort(p+1,right,array); /* sort right part static void quick_sort(int length, int array[]) { q_sort(0,length-1,array); Teilt das Feld in linke und rechte Hälfte und sortiert dieses rekursiv, durch wiederholte Feldteilung. Die eigentliche Arbeit erledigt die quick_partion Methode, um das Feld aufzuteilen. Prof. Dr. Nikolaus Wulff Programmieren in C 6
Partitionierung des Felds * return index p of pivot element such that * all members left of v[p] are <= v[p] static int quick_partion(int left, int right, int v[]) { int i, p; p = (left+right)/2; swap(v, left, p); /* store pivot element p = left; for(i=left+1; i<=right; i++) { if (cmp(v[i],v[left])) { /* compare to pivot swap(v, ++p, i); /* end i-loop swap(v, left, p); /* restore pivot element return p; /* v[left,...,p]<= v[p] Prof. Dr. Nikolaus Wulff Programmieren in C 7
Zeiger statt switch-case Anstatt des switch-case Verteilers ist es möglich mit Zeigern zu arbeiten. Voraussetzung: alle Sortiermethoden besitzen die selbe Schnittstelle/Methodensignatur. typedef void (*Sorter)(int length, int array[]); Sorter sorters[] = { selection_sort, quick_sort, bubble_sort; * dispatch according to preselected mode void sorter(int length, int array[]) { sorters[mode%3](length,array); Prof. Dr. Nikolaus Wulff Programmieren in C 8
Zeiger und Structure typedef void (*Sorter)(int length, int array[]); typedef struct sorter_struct { char *name; /* sorter name Sorter execute; /* sorting routine SortAlgorithm; SortAlgorithm sorters[] = { {"Selection Sort", selection_sort, {"Quick Sort", quick_sort, {"Bubble Sort", bubble_sort ; * dispatch according to preselected mode void sorter(int length, int array[]) { SortAlgorithm sorter = sorters[mode%3]; printf("sorting with %s \n",sorter.name); sorter.execute(length,array); Prof. Dr. Nikolaus Wulff Programmieren in C 9
Callback Methoden Zeiger und Strukturen werden häufig in graphischen Fenstersystemen verwendet, um sogenannte Callback-Methoden zu implementieren. Beispiel: Ein Button muss beim Drücken eine bestimmte Funktionalität ausführen. Der Entwickler der Button Routine weiß jedoch nicht in welchem Kontext der Button verwendet wird. Einmal ist damit ein FileOpenDialog assoziert, ein anderes Mal die Auswahl einer Farbe oder Schrift etc. Wie lässt sich ein solch unterschiedliches Verhalten realisieren? Prof. Dr. Nikolaus Wulff Programmieren in C 10
Buttons und Menus Die GUI Elemente sind Strukturen mit Platzhaltern für entsprechende Callback Methoden. typedef void (*Callback)(ActionEvent evt); typedef struct button_struct { char* text; Callback action; Button; typedef struct menu_struct { char* text; Callback action; Menu; Beim Betätigen eines Buttons wird die jeweilige Callback-Methode aufgerufen und die dahinter codierte Funktionalität ausgeführt. Prof. Dr. Nikolaus Wulff Programmieren in C 11
Dynamische Feldgröße int main(int argc, char *argv[]) { int i,len,mode,*array; printf("eingabe Feldgroesse: "); fflush(stdout);scanf("%d",&len); Allocate memory for array array = malloc(sizeof(int)*len); loop over sorting algorithms for(mode=0;mode<3;mode++) { srand(1); /* force unique seed for random for(i=0;i<len;i++) /* generate 0<=x<=100 array[i] = (100.0*rand())/RAND_MAX; printf("\n\nvor dem Sortieren: \n"); printintarray(array, len); setalgorithm(mode); sorter(len,array); printf("nach dem Sortieren: \n"); printintarray(array, len); Free allocated memory free(array); return 0; Prof. Dr. Nikolaus Wulff Programmieren in C 12
Laufzeitverhalten Werden in die Swap und Compare Methoden statische Zähler eingefügt, so lässt sich das Laufzeitverhalten der Sortieralgorithmen als Funktion der Feldlänge monitoren: n Bubble Sort Selection Sort Quick Sort 10 72 / 29 55 / 29 22 / 26 100 7029 / 2264 5050 / 1718 605 / 517 1000 961038 / 253476 500500 / 44435 11402 / 5175 10000 10 8 / 2*10 7 5*10 7 / 5*10 5 5*10 5 / 5*10 5 Die Anzahl an Schleifendurchläufen und Vergleichsoperationen. (cmp/swap). Prof. Dr. Nikolaus Wulff Programmieren in C 13