1. 指针函数
指针函数是指一个函数的返回值为地址量的函数
指针函数的定义的一般形式如下:
<数据类型> * <函数名称>(<参数说明>){
语句序列;
return(<返回值>);
}
返回值:
全局变量的地址,static变量的地址,字符串常量的地址,堆的地址
/*案例1:编写一个指针函数,删除一个字符串中的空格 demo2*/
#include <stdio.h>
char * del_space(char * data);
int main(int argc,char *argv[])
{
char str[] = " xi ao q i a ng";
puts(str);
puts(del_space(str));
return 0;
}
char * del_space(char * data){
char *p = data;
char *str = data;
while(*data != '\0'){
if (*data == ' ')
data++;
else{
*p = *data;
data++;
p++;
}
}
*p = '\0';
return str;
}
/*测试结果:
linux@ubuntu:~/C/day09$ gcc demo2.c -Wall
linux@ubuntu:~/C/day09$ ./a.out
xi ao q i a ng
xiaoqiang
*/
/*案例2:编写一个指针函数,实现字符串连接 demo3*/
#include <stdio.h>
char *strcat(char *dest,const char *src);
int main(int argc,char *argv[])
{
char a[40] = "xiaoqiang";
char b[] = " love xiaotian";
puts(a);
puts(b);
puts(strcat(a,b));
return 0;
}
char *strcat(char *dest,const char *src){
char * str = dest;
while(* dest != '\0') dest++;
while(* src != '\0'){
*dest = *src;
dest++;
src++;
}
*dest = '\0';
return str;
}
/*测试结果:
linux@ubuntu:~/C/day09$ gcc demo3.c -Wall
linux@ubuntu:~/C/day09$ ./a.out
xiaoqiang
love xiaotian
xiaoqiang love xiaotian
*/
/*案例3:编写一个指针函数,把整数123转化成字符串"123" demo4*/
#include <stdio.h>
char * itoa(int n);
int main(int argc,char *argv[])
{
int n;
char *s;
printf("input:");
scanf("%d",&n);
s = itoa(n);
puts(s);
return 0;
}
char *itoa(int n){
int r, i = 0, j;
static char p[50];
while(n){
r = n % 10;
n /= 10;
p[i] = r + '0';
i++;
}
p[i] = '\0';
j = i - 1;
i = 0;
while(j > i){
r = p[i];
p[i] = p[j];
p[j] = r;
i++;
j--;
}
return p;
}
/*运行结果:
linux@ubuntu:~/C/day09$ gcc demo4.c -Wall
linux@ubuntu:~/C/day09$ ./a.out
input:5201314
5201314
*/
2. 递归函数和函数指针
2.1 递归函数
递归函数是指一个函数的函数体中直接或间接调用了该函数自身
递归函数调用的执行过程分为两个阶段
递推阶段:从原问题出发,按递归公式递推从未知到已知,最终达到递推终止条件
回归阶段:按递归终止条件求出结果,逆向逐步代入递归公式,回归到原问题求解
/*案例1:用递归实现求n的阶乘*/
#include <stdio.h>
int fac(int n);
int main(int argc,char *argv[])
{
int n;
printf("input:");
scanf("%d",&n);
printf("%d\n",fac(n));
return 0;
}
int fac(int n)
{
if(n == 0 || n == 1)
return 1;
return n * fac(n - 1);
}
/*运行结果:
linux@ubuntu:~/C/day09$ gcc demo5.c
linux@ubuntu:~/C/day09$ ./a.out
input:5
120
*/
/*案例2:用递归实现斐波那契数列前20项*/
#include <stdio.h>
int fib(int n);
int main(int argc,char *argv[])
{
int n = 1;
while(n <= 20){
printf("%d ",fib(n));
n++;
}
puts("");
return 0;
}
int fib(int n){
if(n == 1)
return 1;
if(n == 2)
return 1;
return fib(n - 1) + fib(n - 2);
}
/*运行结果:
linux@ubuntu:~/C/day09$ gcc demo6.c -Wall
linux@ubuntu:~/C/day09$ ./a.out
1 1 2 3 5 8 13 21 34 55 89 144 233 377 610 987 1597 2584 4181 6765
*/
2.2 函数指针
函数指针用来存放函数的地址,这个地址是一个函数的入口地址
函数名代表了函数的入口地址
函数指针变量说明的一般形式如下:
<数据类型> (*<函数指针名称>)(<参数说民列表>);
<数据类型>是函数指针所指向的函数的返回值类型
<参数说明列表>应该与函数指针所指向大的函数的形参说明保持一致
(*<函数指针名称>)中,*说明为指针()不可缺省,表明为函数的指针
/*案例:调用C库中的qsort函数来实现整型数组的排序 demo7*/
#include <stdio.h>
#include <stdlib.h>
int compare(const void *,const void *);
int main(int argc,char *argv[])
{
int s[] = {11,32,71,4,98,31,54,64,221,34,59,61,75,2};
int n,i;
n = sizeof(s)/sizeof(int);
qsort(s, n,sizeof(int),compare);
for(i = 0;i < n;i++){
printf("%d ",s[i]);
}
return 0;
}
int compare(const void * p,const void * q){
return (*(int *)p - *(int *)q);
}
/*测试结果:
linux@ubuntu:~/C/day09$ gcc demo7.c -Wall
linux@ubuntu:~/C/day09$ ./a.out
2 4 11 31 32 34 54 59 61 64 71 75 98 221
*/
2.3 函数指针数组
函数指针数组是一个保存若干个函数名的数组
一般形式如下:
<数据类型> (*<函数指针数组名称>[<大小>])(<参数说明列表>)
其中,<大小>是指函数指针数组元素个数
其他同普通指针数组
/*案例:利用函数指针数组存储加减乘除四个函数,并通过函数指针数组的值去使用 demo8*/
#include <stdio.h>
int add(int a,int b){
printf("%d+%d=",a,b);
return a+b;
}
int sub(int a,int b){
printf("%d-%d=",a,b);
return a-b;
}
int mul(int a,int b){
printf("%d*%d=",a,b);
return a*b;
}
int div(int a,int b){
printf("%d/%d=",a,b);
return a/b;
}
int main(int argc,char *argv[])
{
int m = 30,n = 5,i;
int (*p[4])(int,int);
p[0] = add;
p[1] = sub;
p[2] = mul;
p[3] = div;
for(i = 0;i < 4;i++){
printf("%d\n",(*p[i])(m,n));
}
return 0;
}
/*测试结果:
linux@ubuntu:~/C/day09$ gcc demo8.c -Wall
linux@ubuntu:~/C/day09$ ./a.out
30+5=35
30-5=25
30*5=150
30/5=6
*/