函数泛型Lecture09.pdfbubble_sort.ccount_matches.ccount_matches_soln.clive_session.cprint_array.cprint_array_soln.c

memset

image.png

Bubble Sort

image.png
image.png
image.png
image.png

  1. // This is a generic function to swap two variables of the same type.
  2. void swap(void *a, void *b, int elem_size_bytes) {
  3. char temp[elem_size_bytes];
  4. memcpy(temp, a, elem_size_bytes);
  5. memcpy(a, b, elem_size_bytes);
  6. memcpy(b, temp, elem_size_bytes);
  7. }
  8. // This is a standard comparison function for integers.
  9. int int_cmpfn(void *a, void *b) {
  10. return *(int *)a - *(int *)b;
  11. }
  12. // This is a standard comparison function for strings.
  13. int str_cmpfn(void *a, void *b) {
  14. char *str1 = *(char **)a;
  15. char *str2 = *(char **)b;
  16. return strcmp(str1, str2);
  17. }
  18. /* This is a generic bubble sort function to sort an array of any type.
  19. * It accepts a comparison function as a parameter to properly compare elements. */
  20. void bubble_sort(void *arr, int n, int elem_size_bytes, int (*cmpfn)(void *a, void *b)) {
  21. while (true) {
  22. bool swapped = false;
  23. for (int i = 1; i < n; i++) {
  24. void *p_prev_elem = (char *)arr + (i - 1) * elem_size_bytes;
  25. void *p_curr_elem = (char *)arr + i * elem_size_bytes;
  26. if (cmpfn(p_prev_elem, p_curr_elem) > 0) {
  27. swapped = true;
  28. swap(p_prev_elem, p_curr_elem, elem_size_bytes);
  29. }
  30. }
  31. if (!swapped) {
  32. return;
  33. }
  34. }
  35. }
  36. void test_sort() {
  37. int nums[] = {4, 2, 12, -5, 56, 14};
  38. int nums_count = sizeof(nums) / sizeof(nums[0]);
  39. bubble_sort(nums, nums_count, sizeof(nums[0]), int_cmpfn);
  40. for (int i = 0; i < nums_count; i++) {
  41. printf("%d ", nums[i]);
  42. }
  43. printf("\n");
  44. }
  45. void test_sort_args(char *args[], int nargs) {
  46. bubble_sort(args, nargs, sizeof(args[0]), str_cmpfn);
  47. for (int i = 0; i < nargs; i++) {
  48. printf("%s ", args[i]);
  49. }
  50. printf("\n");
  51. }
  52. int main(int argc, char *argv[]) {
  53. if (argc == 1) {
  54. test_sort();
  55. } else {
  56. test_sort_args(argv + 1, argc - 1);
  57. }
  58. return 0;
  59. }

Function Pointers

image.png
image.png

Example: Generic Printing

#include<stdio.h>
#include<stdlib.h>

/* This struct stores information about temperature info (in Fahrenheit)
 * for a given month, including average low and high temps.
 */
typedef struct month_temp_info {
    char *month;
    int avg_high_f;
    int avg_low_f;
} month_temp_info;

/* This function prints out the provided array using
 * the provided function that prints out one element of the array.
 */
void print_array(void *arr, size_t nelems, int elem_size_bytes,
                 void(*print_fn)(void *)) {
    for (int i = 0; i < nelems; i++) {
        void *elem_ptr = (char *)arr + i * elem_size_bytes;
        printf("%d: ", i + 1);
        print_fn(elem_ptr);
        printf("\n");
    }
}

void print_int(void *arr) {
    printf("%d", *(int *)arr);
}

void print_long(void *arr) {
    printf("%ld", *(long *)arr);
}

void print_temp_info(void *arr) {
    month_temp_info info = *(month_temp_info *)arr;
    printf("In %s, the average high was %doF, and the average low was %doF",
           info.month, info.avg_high_f, info.avg_low_f);
}

int main(int argc, char *argv[]) {
    // Print an array of ints
    int i_array[] = {0, 1, 2, 3, 4, 5};
    size_t i_nelems = sizeof(i_array) / sizeof(i_array[0]);
    print_array(i_array, i_nelems, sizeof(i_array[0]), print_int);
    printf("\n");

    // Print an array of longs
    long l_array[] = {0, 10, 20, 30, 40, 50};
    size_t l_nelems = sizeof(l_array) / sizeof(l_array[0]);
    print_array(l_array, l_nelems, sizeof(l_array[0]), print_long);
    printf("\n");

    // Print an array of temp info structs
    // data from https://www.usclimatedata.com/climate/winters/california/united-states/usca1252
    month_temp_info month_temps[3];
    month_temps[0] = (month_temp_info){"January", 56, 38};
    month_temps[1] = (month_temp_info){"April", 75, 49};
    month_temps[2] = (month_temp_info){"June", 92, 59};
    size_t temp_nelems = sizeof(month_temps) / sizeof(month_temps[0]);
    print_array(month_temps, temp_nelems, sizeof(month_temps[0]), print_temp_info);

    return 0;
}

Function Pointers As Variables

image.png

Generic C Standard Library Functions

image.png
image.png

Pre-lecture Quiz 4 Q1

image.png

Common code snippets

image.png

Function pointers as variables

image.png