本文共 3167 字,大约阅读时间需要 10 分钟。
通过什么来区分两个不同的函数?
一个函数在编译时被分配一个入口地址,这个地址就称为函数的指针,函数名代表函数的入口地址。 函数三要素: 名称、参数、返回值。C语言中的函数有自己特定的类型。 c语言中通过typedef为函数类型重命名:typedef int f(int, int); // f 为函数类型typedef void p(int); // p 为函数类型
这一点和数组一样,因此我们可以用一个指针变量来存放这个入口地址,然后通过该指针变量调用函数。
注意:通过函数类型定义的变量是不能够直接执行,因为没有函数体。只能通过类型定义一个函数指针指向某一个具体函数,才能调用。typedef int(p)(int, int);void my_func(int a,int b){ printf("%d %d\n",a,b);}void test(){ p p1; //p1(10,20); //错误,不能直接调用,只描述了函数类型,但是并没有定义函数体,没有函数体无法调用 p* p2 = my_func; p2(10,20); //正确,指向有函数体的函数入口地址}
int my_func(int a,int b){ printf("ret:%d\n", a + b); return 0;}//1. 先定义函数类型,通过类型定义指针void test01(){ typedef int(FUNC_TYPE)(int, int); FUNC_TYPE* f = my_func; //如何调用? (*f)(10, 20); f(10, 20);}//2. 定义函数指针类型void test02(){ typedef int(*FUNC_POINTER)(int, int); FUNC_POINTER f = my_func; //如何调用? (*f)(10, 20); f(10, 20);}//3. 直接定义函数指针变量void test03(){ int(*f)(int, int) = my_func; //如何调用? (*f)(10, 20); f(10, 20);}
函数指针数组,每个元素都是函数指针。
void func01(int a){ printf("func01:%d\n",a);}void func02(int a){ printf("func02:%d\n", a);}void func03(int a){ printf("func03:%d\n", a);}void test(){ #if 0 //定义函数指针 void(*func_array[])(int) = { func01, func02, func03 };#else void(*func_array[3])(int); func_array[0] = func01; func_array[1] = func02; func_array[2] = func03;#endif for (int i = 0; i < 3; i ++){ func_array[i](10 + i); (*func_array[i])(10 + i); }}
函数参数除了是普通变量,还可以是函数指针变量。
//形参为普通变量void fun( int x ){ }//形参为函数指针变量void fun( int(*p)(int a) ){ }函数指针变量常见的用途之一是把指针作为参数传递到其他函数,指向函数的指针也可以作为参数,以实现函数地址的传递。//加法计算器int plus(int a,int b){ return a + b;}//减法计算器int minus(int a,int b){ return a - b;}//计算器#if 0int caculator(int a,int b,int(*func)(int,int)){ return func(a, b);}#elsetypedef int(*FUNC_POINTER)(int, int);int caculator(int a, int b, FUNC_POINTER func){ return func(a, b);}#endif
注意:函数指针和指针函数的区别:
C通过运行时堆栈来支持递归函数的实现。递归函数就是直接或间接调用自身的函数。
void funB(int b){ printf("b = %d\n", b);}void funA(int a){ funB(a - 1); printf("a = %d\n", a);}int main(void){ funA(2); printf("main\n"); return 0;}
函数的调用流程如下:
void fun(int a){ if (a == 1){ printf("a = %d\n", a); return; //中断函数很重要 } fun(a - 1); printf("a = %d\n", a);}int main(void){ fun(2); printf("main\n"); return 0;}
函数的调用流程如下:
递归实现给出一个数8793,依次打印千位数字8、百位数字7、十位数字9、个位数字3。
void recursion(int val){ if (val == 0){ return; } int ret = val / 10; recursion(ret); printf("%d ",val % 10);}
int reverse1(char *str){ if (str == NULL) { return -1; } if (*str == '\0') // 函数递归调用结束条件 { return 0; } reverse1(str + 1); printf("%c", *str); return 0;}char buf[1024] = { 0 }; //全局变量int reverse2(char *str){ if (str == NULL) { return -1; } if ( *str == '\0' ) // 函数递归调用结束条件 { return 0; } reverse2(str + 1); strncat(buf, str, 1); return 0;}int reverse3(char *str, char *dst){ if (str == NULL || dst == NULL) { return -1; } if (*str == '\0') // 函数递归调用结束条件 { return 0; } reverse3(str + 1); strncat(dst, str, 1); return 0;}
转载地址:http://szxmi.baihongyu.com/