函数的指针
当你创建一个函数test的时候,同时也会创建test的指针变量,变量中保存了函数的地址
创建函数指针
int(*warp_fn)(int); #创建warp_fn的变量,用来保存test()函数的地址
warp_fn = test;
warp_fn(4); #等同于调用test函数
char** (*names_fn)(char*, int); #创建一个names_fn的变量用来保存test函数
names_fn = test;
char** results = name_fn(1972);
函数指针应用
#include <stdio.h>
#include <string.h>
int NUM_ADS = 7;
char *ADS[] = {
"William:SBM GSON likes sport,TV,dining",
"Matt:SWM NS likes art,movies,theather",
"Luis:SLM ND likes books,theater,art",
"MIKE:DWM DS likes truncks,sports and bieber",
"Peter:SAM likes chess,working out and art",
"Josh:SJM likes sports,movies and theater",
"Jed:DBM likes theater,books and dining"
};
/**
* 都要定义哦
*/
void find();
int sports_no_bieber(char *s);
int sports_or_workout(char *s);
int ns_theater(char *s);
int main()
{
find(sports_no_bieber);
find(sports_or_workout);
find(ns_theater);
return 0;
}
/**
* 注意find中传入的参数是函数的指针
* char** 表示返回类型
* *func 表示指针变量
* char* 表示参数类型
*/
void find(char** (*func)(char*))
{
int i;
puts("Search results:");
puts("---------------------");
for(i=0;i<NUM_ADS;i++) {
if (func(ADS[i])) {
printf("%s\n", ADS[i]);
}
}
puts("----------------");
}
int sports_no_bieber(char *s)
{
return strstr(s, "sports") && !strstr(s, "bieber");
}
int sports_or_workout(char *s)
{
return strstr("s", "sports") || strstr(s, "working out");
}
int ns_theater(char *s)
{
return strstr(s, "NS") && strstr(s, "theater");
}
qsort使用
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
int compare_scores(const void * scores_a, const void * scores_b);
typedef struct {
int width;
int height;
} rectangle;
int compare_areas(const void* a, const void* b);
int compare_name(const void* a, const void* b);
int main()
{
int scores[] = {2,3,123,345,456,7,11,3,5,6};
qsort(scores, 10, sizeof(int), compare_scores);
int i;
for(i=0;i<10;i++) {
printf("%i\n", scores[i]);
}
int areas[] = {2,3,345,123,1};
qsort(areas, 5, sizeof(int), compare_areas);
int x;
for(x=0;x<5;x++) {
printf("%i\n", areas[x]);
}
char *names[] = {"c", "a","b"};
qsort(names, 3, sizeof(char*), compare_name);
int z;
for(z=0;z<3;z++) {
printf("%s\n", names[z]);
}
return 0;
}
/**
void指针可以保存任何类型数据的地址,但使用前必须把它转换成具体类型
*/
int compare_scores(const void * scores_a, const void * scores_b)
{
/**
int * 把void指针转换成整形指针
*(int *)获取获取scores_a中的整形值
*/
int a = *(int *)scores_a;
int b = *(int *)scores_b;
return b-a;
}
int compare_areas(const void *a, const void *b)
{
/**
把指针转换成相应的类型
*/
rectangle *ia = (rectangle*)a;
rectangle *ib = (rectangle*)b;
/**
矩形面积计算
*/
int area_a = (ia->width * ia->height);
int area_b = (ia->width * ia->height);
return area_a-area_b;
}
int compare_name(const void* a, const void* b)
{
/**
char** 代表的是指向字符指针的指针
*/
char** sa = (char**)a;
char** sb = (char**)b;
/**
strcmp接收的是char*的值,而char**是指针地址
*/
return strcmp(*sa, *sb);
}
函数指针
void(*function_name[])(response)={function_a,function_b};
void 声明返回类型
* 声明函数指针
function_name 变量名
[] 表明是函数数组
response 参数类型
例子:
#include <stdio.h>
enum response_type {DUMP, SECOND_CHANCE, MARRIAGE};
typedef struct {
char* name;
enum response_type type;
}response;
void dump(response r);
void second_chance(response r);
void marriage(response r);
int main()
{
response ra[] = {
{"test", DUMP},
{"test2", SECOND_CHANCE},
};
/**
定义函数数组
*/
void(*func_arr[])(response) = {dump, second_chance, marriage};
int i;
for (i=0;i<2;i++) {
/**
使用函数数组定义的方法
*/
(func_arr[ra[i].type])(ra[i]);
/**
受用switch的方法
*/
switch(ra[i].type) {
case DUMP:
dump(ra[i]);
break;
case SECOND_CHANCE:
second_chance(ra[i]);
break;
default:
marriage(ra[i]);
break;
}
}
return 0;
}
void dump(response r)
{
printf("hello,i'm dump, you are %s\n", r.name);
}
void second_chance(response r)
{
printf("hello,i'm second_chance, you are %s\n", r.name);
}
void marriage(response r)
{
printf("hello,i'm marriage, you are %s\n", r.name);
}
可变参数个数
在C标准库中有一组宏可以建立自己的可变参数函数,<stdarg.h>
例子
#include <stdio.h>
#include <stdarg.h>
void print_ints(int args, ...)
{
/*
保存传给函数的其他参数
*/
va_list ap;
/*
表示可变参数从哪开始
*/
va_start(ap, args);
int i;
/*
循环遍历所有其他参数,args保存了参数的数目
*/
for(i=0;i<args;i++) {
printf("argument:%i\n", va_arg(ap, int));
}
va_end(ap);
}
int main()
{
print_ints(3, 79, 101, 32);
}