1.回调函数是什么?
回调函数就是一个通过函数指针调用的函数
如果你把函数的指针作为参数传递给另外一个函数,当这个指针被用来调用其指向的函数时,被调用的函数就被称为回调函数 。以下将用代码解释回调函数。
例子为模拟计算机
在使用回调函数前:
# include <stdio.h>int add ( int a, int b){return a + b;}int sub ( int a, int b){return a - b;}int mul ( int a, int b){return a * b;}int div ( int a, int b){return a / b;}int main (){int x, y;int input = 1 ;int ret = 0 ;do{printf ( "******************printf ( " 1:addprintf ( " 3:mulprintf ( "******************printf ( " 请选择: " );scanf ( "%d" , &input);switch (input){case 1 :printf ( " 输⼊操作数: " );scanf ( "%d %d" , &x, &y)ret = add(x, y);printf ( "ret = %d\n" , rbreak ;case 2 :printf ( " 输⼊操作数: " );scanf ( "%d %d" , &x, &y)ret = sub(x, y);printf ( "ret = %d\n" , rbreak ;case 3 :printf ( " 输⼊操作数: " );scanf ( "%d %d" , &x, &y)ret = mul(x, y);printf ( "ret = %d\n" , rbreak ;case 4 :printf ( " 输⼊操作数: " );scanf ( "%d %d" , &x, &y)ret = div(x, y);printf ( "ret = %d\n" , rbreak ;case 0 :printf ( " 退出程序 \n" );break ;default :printf ( " 选择错误 \n" );break ;}} while (input);return 0 ;}
在使用回调函数后:
# include <stdio.h>int add ( int a, int b){return a + b;}int sub ( int a, int b){return a - b;}int mul ( int a, int b){return a * b;}int div ( int a, int b){return a / b;}void calc ( int (*pf)( int , int )){int ret = 0 ;int x, y;printf ( " 输⼊操作数: " );scanf ( "%d %d" , &x, &y);ret = pf(x, y);printf ( "ret = %d\n" , ret);}int main (){int input = 1 ;do{printf ( "******************printf ( " 1:addprintf ( " 3:mulprintf ( "******************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" );break ;default :printf ( " 选择错误 \n" );break ;}} while (input);return 0 ;}
2.qsort使用举例
2.1使用qsort函数排序整型数据
# include <stdio.h>//qosrt 函数的使⽤者得实现⼀个⽐较函数int int_cmp ( const void * p1, const void * p2){return (*( int *)p1 - *( int *) p2);}int main (){int arr[] = { 1 , 3 , 5 , 7 , 9 , 2 , 4 , 6 , 8 , 0 };int i = 0 ;qsort(arr, sizeof (arr) / sizeof (arr[ 0 ]), sizeof ( int ), int_cmp);for (i = 0 ; i< sizeof (arr) / sizeof (arr[ 0 ]); i++){printf ( "%d " , arr[i]);}printf ( "\n" );return 0 ;}
2.2 使用qsort排序结构数据
struct Stu // 学⽣{char name[ 20 ]; // 名字int age; // 年龄};// 假设按照年龄来⽐较int cmp_stu_by_age ( const void * e1, const void * e2){return (( struct Stu*)e1)->age - (( struct Stu*)e2)->age;}//strcmp - 是库函数,是专⻔⽤来⽐较两个字符串的⼤⼩的// 假设按照名字来⽐较int cmp_stu_by_name ( const void * e1, const void * e2){return strcmp ((( struct Stu*)e1)->name, (( struct Stu*)e2)->name);}// 按照年龄来排序void test2 (){struct Stu s [] = { { "zhangsan" , 20 }, { "lisi" , 30 }, { "wangwu" , 15 } };int sz = sizeof (s) / sizeof (s[ 0 ]);qsort(s, sz, sizeof (s[ 0 ]), cmp_stu_by_age);}// 按照名字来排序void test3 (){struct Stu s [] = { { "zhangsan" , 20 }, { "lisi" , 30 }, { "wangwu" , 15 } };int sz = sizeof (s) / sizeof (s[ 0 ]);qsort(s, sz, sizeof (s[ 0 ]), cmp_stu_by_name);}int main (){test2();test3();return 0 ;}
3.qsort函数的模拟实现
使⽤回调函数,模拟实现qsort(采⽤冒泡的⽅式)。
# include <stdio.h>int int_cmp ( const void* p1, const void * p2){return (*( int *)p1 - *( int *) p2);}void _swap( void *p1, void * p2, int size){int i = 0 ;for (i = 0 ; i< size; i++){char tmp = *(( char *)p1 + i);*(( char *)p1 + i) = *(( char *) p2 + i);*(( char *)p2 + i) = tmp;}}void bubble ( void *base, int count , int size, int (*cmp )( void *, void *)){int i = 0 ;int j = 0 ;for (i = 0 ; i< count - 1 ; i++){for (j = 0 ; j<count-i -1 ; j++){if (cmp (( char *) base + j*size , ( char *)base + (j + 1 )*size) > 0 ){_swap(( char *)base + j*size, ( char *)base + (j + 1 )*size, size);}}}}int main (){int arr[] = { 1 , 3 , 5 , 7 , 9 , 2 , 4 , 6 , 8 , 0 };int i = 0 ;bubble(arr, sizeof (arr) / sizeof (arr[ 0 ]), sizeof ( int ), int_cmp);for (i = 0 ; i< sizeof (arr) / sizeof (arr[ 0 ]); i++){printf ( "%d " , arr[i]);}printf ( "\n" );return 0 ;}
4.sizeof和strlen的对比
4.1sizeof
sizeof计算变量所占内存内存空间大小,单位是字节,如果操作数是类型的话,计算的是使用类型创建的变量所占内存空间的大小。
sizeof 只关注占⽤内存空间的⼤⼩,不在乎内存中存放什么数据。
比如:
#inculde <stdio.h>int main (){int a = 10 ;printf ( "%d\n" , sizeof (a));printf ( "%d\n" , sizeof a);printf ( "%d\n" , sizeof ( int ));return 0 ;}
最后输出的大小都是4
4.2 strlen
strlen是C语言库函数,功能是求字符串长度,函数的原型如下:
size_t strlen ( const char * str );
统计的是从
strlen
函数的参数
str
中这个地址开始向后,
\0
之前字符串中字符的个数。
strlen
函数会⼀直向后找
\0
字符,直到找到为⽌,所以可能存在越界查找。
# include <stdio.h>int main (){char arr1[ 3 ] = { 'a' , 'b' , 'c' };char arr2[] = "abc" ;printf ( "%d\n" , strlen (arr1));printf ( "%d\n" , strlen (arr2));printf ( "%d\n" , sizeof (arr1));printf ( "%d\n" , sizeof (arr1));return 0 ;}
4.3 sizeof和strlen的对比
sizeof:
1.
sizeof是操作符
2.
sizeof计算操作数所占内存的⼤⼩, 单位是字节
3.
不关注内存中存放什么数据
strlen:
1. strlen是库函数,使用需要包含头文件string.h
2.srtlen是求字符串⻓度的,统计的是 \0 之前字符的隔个数
3.关注内存中是否有\0,如果没有\0,就会持续的往后找,可能会越界