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




// This is a generic function to swap two variables of the same type.void swap(void *a, void *b, int elem_size_bytes) {char temp[elem_size_bytes];memcpy(temp, a, elem_size_bytes);memcpy(a, b, elem_size_bytes);memcpy(b, temp, elem_size_bytes);}// This is a standard comparison function for integers.int int_cmpfn(void *a, void *b) {return *(int *)a - *(int *)b;}// This is a standard comparison function for strings.int str_cmpfn(void *a, void *b) {char *str1 = *(char **)a;char *str2 = *(char **)b;return strcmp(str1, str2);}/* This is a generic bubble sort function to sort an array of any type.* It accepts a comparison function as a parameter to properly compare elements. */void bubble_sort(void *arr, int n, int elem_size_bytes, int (*cmpfn)(void *a, void *b)) {while (true) {bool swapped = false;for (int i = 1; i < n; i++) {void *p_prev_elem = (char *)arr + (i - 1) * elem_size_bytes;void *p_curr_elem = (char *)arr + i * elem_size_bytes;if (cmpfn(p_prev_elem, p_curr_elem) > 0) {swapped = true;swap(p_prev_elem, p_curr_elem, elem_size_bytes);}}if (!swapped) {return;}}}void test_sort() {int nums[] = {4, 2, 12, -5, 56, 14};int nums_count = sizeof(nums) / sizeof(nums[0]);bubble_sort(nums, nums_count, sizeof(nums[0]), int_cmpfn);for (int i = 0; i < nums_count; i++) {printf("%d ", nums[i]);}printf("\n");}void test_sort_args(char *args[], int nargs) {bubble_sort(args, nargs, sizeof(args[0]), str_cmpfn);for (int i = 0; i < nargs; i++) {printf("%s ", args[i]);}printf("\n");}int main(int argc, char *argv[]) {if (argc == 1) {test_sort();} else {test_sort_args(argv + 1, argc - 1);}return 0;}
Function Pointers
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
Generic C Standard Library Functions
Pre-lecture Quiz 4 Q1
Common code snippets
Function pointers as variables



