C和指针 第十六章 习题
16.8 计算平均年龄
#include <stdlib.h> #include <stdio.h> #define MAX_LEN 512 int main() { int age; int totalAge; float avgAge; int peopleNum; FILE *file; char info[MAX_LEN]; char *infoPtr; file = fopen("D:/family.txt", "r"); //按行读取文件 while(fgets(info, MAX_LEN, file)){ infoPtr = info; peopleNum = 0; totalAge = 0; //strtol转换字符到数字 while((age = strtol(infoPtr, &infoPtr, 10)) > 0){ totalAge += age; peopleNum++; } //类型转换为float,然后计算平均年龄 avgAge = (float)totalAge / peopleNum; printf("%savg: %5.2f\n", info, avgAge); } return 0; }
运行:
16.9 计算相同生日概率
#include <stdlib.h> #include <stdio.h> #include <time.h> //比较元素 int compare(void const *birth1, void const *birth2){ return *(int *)(birth1) - *(int*)(birth2); } //打印数组 void print_arr(int *array, int len){ int idx = 0; while(idx <= len){ printf("%d ", array[idx]); idx++; } } //数组中是否有两个相同数 int count_same(int *array, int len){ int same = 0; while(len > 0){ if(array[len] == array[len - 1]){ return 1; } len--; } return 0; } int main() { int times = 0; int randBirthday[30]; int peopleCount; int sameCount = 0; srand((unsigned int)time(0)); while(times < 100000){ peopleCount = 29; while(peopleCount >= 0){ randBirthday[peopleCount] = rand() % 365; peopleCount--; } qsort(randBirthday, 30, sizeof(int), compare); sameCount += count_same(randBirthday, 29); times++; } printf("%f", (float)(sameCount) / 100000); return 0; }
运行:
16.10 插入排序
#include <stdio.h> #include <stdlib.h> #include <string.h> //插入排序 void insert_sort(void *array, unsigned int length, unsigned int size, int (*handle)(void const *num1, void const *num2)); //整型移动函数 //整型比较函数 int int_compare(void const *num1, void const *num2) { return (*(int *)num1 - *(int *)(num2)); } //打印数组 void print_arr(int *arr , int len){ for(int idx = 0 ; idx < len; idx++){ printf("%d ", arr[idx]); } } int main() { int array[10] = {4, 1, 17, 2, 8 , 9, 22, 12, 7, 5}; insert_sort(array, 10, sizeof(int), int_compare); print_arr(array, 10); return 0; } void insert_sort(void *array, size_t n_elements, size_t n_size, int (*handle)(void const *num1, void const *num2)) { //存放临时需要位移的元素 char *temp = malloc(n_size); //已排序的元素下标,从0开始,拿第二个元素和第一个对比 unsigned int sortIdx = 1; //元素游标和已排序元素游标 unsigned int idx, idy; //位移元素下面 unsigned int mov; //从第二位开始,依次拿出元素和之前的已排序元素比较 for(idx = 1; idx < n_elements; idx++){ //开始比较 for(idy = 0; idy < sortIdx; idy++){ if(handle(array + idy * n_size, array + idx * n_size) > 0){ //将元素和已排序元素依次比较,当遇到已排序元素,比当前元素大时,当前元素应该插入到该已排序元素位置,已排序元素应该后移一位 //位移会覆盖后面的值,所以需要先保存需要插入的值 memcpy(temp, array + idx * n_size, n_size); for(mov = sortIdx; mov > idy; mov--){ memmove(array + mov * n_size, array + (mov - 1) * n_size, n_size); } //元素插入 memcpy(array + idy * n_size , temp, n_size); } } //如果需要插入的值,正好比已排序的值中最大的还要大,那么不需要移动,只要增加已排序的值得下标即可 sortIdx++; } }
运行: