前言
提示:这里可以添加本文要记录的大概内容: 例如:随着人工智能的不断发展,机器学习这门技术也越来越重要,很多人都开启了学习机器学习,本文就介绍了机器学习的基础内容。
提示:以下是本篇文章正文内容,下面案例可供参考
一、回调函数
1、 回调函数定义
回调函数就是一个通过函数指针调用的函数。如果你把函数的指针(地址)作为参数传
递给另一个函数,当这个指针被用来调用其所指向的函数时,我们就说这是回调函数。
回调函数不是由该函数的实现方直接调用,而是在特定的事件或条件发生时由另外的一
方调用的,用于对该事件或条件进行响应。
示例1:简易计算器
上节课已经通过函数指针数组创建了一个简易计算器函数,这次可以通过回调函数来修改函数。
#include <stdio.h>
void menu()
{
printf("**************************\n");
printf("** 1. add 2. sub **\n");
printf("** 3. mul 4. div **\n");
printf("** 5. xor 0. exit**\n");
printf("**************************\n");
}
int Add(int x, int y)
{
return x + y;
}
int Sub(int x, int y)
{
return x - y;
}
int Mul(int x, int y)
{
return x * y;
}
int Div(int x, int y)
{
return x / y;
}
int Xor(int x, int y)
{
return x ^ y;
}
void Calc(int (*pf)(int, int))
{
int x = 0;
int y = 0;
printf("请输入两个操作数:>");
scanf("%d%d", &x, &y);
printf("%d\n", pf(x, y));
}
int main()
{
int input = 0;
do
{
menu();
printf("请选择:>");
scanf("%d", &input);
switch (input)
{
case 1:
Calc(Add);
break;
case 2:
Calc(Sub);
break;
case 3:
Calc(Mul);
break;
case 4:
Calc(Div);
break;
case 0:
printf("退出\n");
;
default:
printf("选择错误\n");
break;
}
} while (input);
}
2、qsort函数
qsort函数是一个C语言内置函数,在<string.h>中,可以用来排序各种类型的数据,其思想主要是快速排序思想。 在C语言官网中可以查到这个函数的各种参数: C语言官网 或者在C语言标准库MSDN上也可以查找到。 在官网上是这样介绍的:
void qsort(void* base,
size_t num,
size_t width,
int( *cmp)(const void *e1, const void *e2)
);
示例2:利用qsort函数实现数据升序排列
#define _CRT_SECURE_NO_WARNINGS 1
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
struct Stu
{
char name[20];
int age;
};
int cmp_int(const void* e1, const void* e2)
{
return *(int*)e1 -*(int*)e2;
}
void test1()
{
int arr[10] = { 9, 8, 7, 6, 5, 4, 3, 2, 1, 0 };
int sz = sizeof(arr) / sizeof(arr[0]);
qsort(arr, sz, sizeof(arr[0]), cmp_int);
int i = 0;
for (i = 0; i < sz; i++)
{
printf("%d ", arr[i]);
}
}
int cmp_float(const void*e1, const void*e2)
{
return ((int)(*(float*)e1 - *(float*)e2));
}
void test2()
{
float f[] = { 9.0, 8.0, 7.0, 6.0, 5.0, 4.0 };
int sz = sizeof(f) / sizeof(f[0]);
qsort(f, sz, sizeof(f[0]), cmp_float);
int j = 0;
for (j = 0; j < sz; j++)
{
printf("%f ", f[j]);
}
}
int cmp_stu_by_name(const void*e1, const void* e2)
{
比较名字就是比较字符串
字符串比较不能直接用><=来比较,应该用strcmp函数
return strcmp(((struct Stu*)e1)->name, ((struct Stu*)e2)->name);
}
void test3()
{
struct Stu s[3] = { { "zhangsan", 20 }, { "lisi", 30 }, { "wangwu", 10 } };
int sz = sizeof(s) / sizeof(s[0]);
qsort(s, sz, sizeof(s[0]), cmp_stu_by_name);
}
int main()
{
test1();
test2();
test3();
return 0;
}
相信到这里,你已经对qsort函数有了一定了解,接下来,在做一个案例加深印象。 示例3:利用回调函数,采用冒泡排序法模拟qsort 曾经,我们做过一个案例,使用冒泡排序法实现整形数据升序排序,但这个冒泡排序法有缺陷,只能排序整形数据,现在,我们可以利用回调函数,采用冒泡排序法模拟qsort,使冒泡排序法可以排序所有类型的数据。
#define _CRT_SECURE_NO_WARNINGS 1
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
void bubble_sort(int arr[], int sz)
{
int i = 0;
for (i = 0; i < sz-1; i++)
{
int j = 0;
for (j = 0; j <sz-1-i; j++)
{
if (arr[j] > arr[j + 1])
{
int tmp = arr[j];
arr[j] = arr[j + 1];
arr[j + 1] = tmp;
}
}
}
}
void Swap(char* buf1, char*buf2, int width)
{
int i = 0;
for (i = 0; i < width; i++)
{
char tmp = *buf1;
*buf1 = *buf2;
*buf2 = tmp;
buf1++;
buf2++;
}
}
void bubble_sort(void*base, int sz, int width, int (*cmp)(void*e1, void*e2))
{
int i = 0;
for (i = 0; i < sz - 1; i++)
{
int j = 0;
for (j = 0; j < sz-1-i; j++)
{
if (cmp((char*)base+j*width, (char*)base+(j+1)*width) > 0)
{
Swap((char*)base + j*width, (char*)base + (j + 1)*width, width);
}
}
}
}
struct Stu
{
char name[20];
int age;
};
int cmp_int(const void* e1, const void* e2)
{
return *(int*)e1 -*(int*)e2;
}
void test4()
{
int arr[10] = { 9, 8, 7, 6, 5, 4, 3, 2, 1, 0 };
int sz = sizeof(arr) / sizeof(arr[0]);
bubble_sort(arr, sz, sizeof(arr[0]), cmp_int);
}
int cmp_stu_by_name(const void*e1, const void* e2)
{
return strcmp(((struct Stu*)e1)->name, ((struct Stu*)e2)->name);
}
void test5()
{
struct Stu s[3] = { { "zhangsan", 20 }, { "lisi", 30 }, { "wangwu", 10 } };
int sz = sizeof(s) / sizeof(s[0]);
bubble_sort(s, sz, sizeof(s[0]), cmp_stu_by_name);
}
int main()
{
test4();
test5();
return 0;
}
在本例中,最难实现的有两个部分,一个使冒泡排序函数形参设计,另一个是排序判断实现。
void bubble_sort(void*base, int sz, int width, int (*cmp)(void*e1, void*e2))
if (cmp((char*)base+j*width, (char*)base+(j+1)*width) > 0)
{
Swap((char*)base + j*width, (char*)base + (j + 1)*width, width);
}
二、指针数组分析
代码如下:
int main()
{
int a[] = { 1, 2, 3, 4 };
printf("%d\n", sizeof(a));
printf("%d\n", sizeof(a + 0));
printf("%d\n", sizeof(*a));
printf("%d\n", sizeof(a + 1));
printf("%d\n", sizeof(a[1]));
printf("%d\n", sizeof(&a));
printf("%d\n", sizeof(*&a));
printf("%d\n", sizeof(&a + 1));
printf("%d\n", sizeof(&a[0]));
printf("%d\n", sizeof(&a[0] + 1));
char arr[] = { 'a', 'b', 'c', 'd', 'e', 'f' };
printf("%d\n", strlen(arr));
printf("%d\n", strlen(arr + 0));
printf("%d\n", strlen(&arr));
printf("%d\n", strlen(&arr + 1));
printf("%d\n", strlen(&arr[0] + 1));
printf("%d\n", sizeof(arr));
printf("%d\n", sizeof(arr + 0));
printf("%d\n", sizeof(*arr));
printf("%d\n", sizeof(arr[1]));
printf("%d\n", sizeof(&arr));
printf("%d\n", sizeof(&arr + 1));
printf("%d\n", sizeof(&arr[0] + 1));
return 0;
}
|