?
? ? }
}
复制代码
?
?
结构练习
C没有类,要表达复杂的数据,就得用结构了, 结构也可以用指针来指,如果是结构变量 的话,引用成员用.,如果是指向结构的指针,引用成员用->
?
别的好像没啥特别的,注意动态分配结构数组后,指针滚动的边界,别使用了界外的 内存。如果结构的成员指向的内存是动态分配的花,也记得free。
?
没有结构,估计写不出大程序,结构应该会用的很多。
?
复制代码
struct customer {
? ? char* name;
? ? int age;
};
?
static void customer_manager() {
? ? // 直接在栈上分配结构体
? ? struct customer wawa;
? ? struct customer* p_wawa;
? ? struct customer* p_customers;
? ? int n = 2;
?
? ? char name[] = "wawa";
? ? // char* name = "wawa"; //splint warning
? ? char name2[] = "tiancai";
?
? ? // 直接用结构名访问成员?
? ? wawa.name = name;
? ? wawa.age = 30;
? ? printf("%s is %d years old\n", wawa.name, wawa.age);
?
? ? // 用指针访问结构成员
? ? p_wawa = &wawa;
? ? p_wawa->age = 31;
? ? printf("%s is %d years old\n", wawa.name, wawa.age);
?
? ? // 为员工数组动态分配内存
? ? p_customers = (struct customer*)malloc(sizeof(struct customer) * n);
? ? if (p_customers != NULL) {
? ? ? ? // 设置数组第一项
? ? ? ? p_customers->name = name;
? ? ? ? p_customers->age = 10;
?
? ? ? ? // 设置数组第二项
? ? ? ? p_customers++;
? ? ? ? p_customers->name = name2;
? ? ? ? p_customers->age = 30;
?
? ? ? ? // 滚动数组外面,然后反向循环到数组开始
? ? ? ? p_customers++;
? ? ? ? while(n-- > 0){
? ? ? ? ? ? p_customers--;
? ? ? ? ? ? printf("%s is %d years old\n", p_customers->name, p_customers->age);
? ? ? ? }
?
? ? ? ? // 释放动态分配的内存,这时候p_customers已经位于起始位置了
? ? ? ? // 结构体里的name1, name2是在栈上分配的,不用释放
? ? ? ? free(p_customers);
? ? }
}
复制代码
?
?
函数指针练习
好多语言都有高阶函数的特性,比如函数的参数或返回值还可以是个函数, C里也有函数指针可以达到类似的效果,用来做回调函数等。
?
但C的函数指针写起来比较诡异,不好记忆,不行就用typedef来重新命个名,写起来 简单一些。
?
下面用一个比较经典的冒泡排序来演示函数指针的使用,传递不同的比较函数可以 改变排序函数的行为,这是写复杂灵活逻辑的一种很方便的方式。
?
复制代码
// 函数指针练习, 排序
?
// 正序排序的比较函数
static int cmp_default(int a, int b){
? ? return a - b;
}
?
// 反序排序的比较函数
static int cmp_reverse(int a, int b){
? ? return b - a;?
}
?
// int类型的冒泡排序算法,可传入一个比较函数指针
// 类似回调函数,该函数需要两个int参数且返回int
static void sort(int* arr, int n, int (*cmp)(int, int)){
? ? int i, j, t;
? ? int *p, *q;
?
? ? p = arr;
?
? ? for (i = 0; i < n; i++, p++) {
? ? ? ? q = p;
? ? ? ? for (j = i; j < n; j++, q++) {
? ? ? ? ? ? // 调用函数指针指向的函数和使用函数一样,貌似是简单写法
? ? ? ? ? ? if (cmp(*p, *q) > 0) {
? ? ? ? ? ? ? ? t = *p;
? ? ? ? ? ? ? ? *p = *q;
? ? ? ? ? ? ? ? *q = t;
? ? ? ? ? ? }
? ? ? ? }
? ? }
}
?
// 测试排序函数
static void sort_test(){
? ? int arr[] = {4, 5, 3, 1, 2};
? ? int i, n = 5;
?
? ? // 正向排序, 传入cmp_default函数的地址,貌似不需要&取地址
? ? sort(arr, 5, cmp_default);
? ? for (i = 0; i < n; i ++) {
? ? ? ? printf("%d%s", arr[i], i == n - 1 ? "" : ", ");?
? ? }
? ? printf("\n");
?
? ? //反向排序,同上
? ? sort(arr, 5, cmp_reverse);
? ? for (i = 0; i < n; i ++) {
? ? ? ? printf("%d%s", arr[i], i == n - 1 ? "" : ", ");?
? ? }
? ? printf("\n");
}