C语言---指针函数和函数指针

指针函数

返回值是一个指针,就称为指针函数,是一个函数

#inlcude
char *getWord(char c)
{
switch(c)
{
case 'A':return "Apple";
case 'B':return "Banana";
case 'C':return "Cat";
case 'D':return "Dog";
default: return "None";
}

}
int main()
{
char input;
scanf("%c",&input);
printf("%s\n",getWord(input));
return 0;
}

从getword函数中获得是一个字符串
通常没有一个类型来定义字符串,都是用char类型指针定义字符串,用char类型指针事实上指向一个字符,我们用它来指向字符串的第一个字符,而字符串约定俗成截止于空字符,也就是反斜杠0\0,所以知道了第一个字符就知道整个字符串,由编译器自己去找到整个字符串。

注意不要返回函数的局部指针

"apple"的作用域只存在于局部函数内,函数完了就销毁了
出了作用域就什么都不是
但返回一个字符串就是可以的,因为字符串的存储并不在函数的局部区域中
错误例子 将会报错,因为返回了局部指针:

#inlcude
char *getWord(char c)
{
char str1[] ="apple";
char str2[]="banana";
char str3[]="cat";
char str4[]="dog";
char str5[]="None";
switch(c)
{
case 'A':return str1;
case 'B':return str2;
case 'C':return str3;
case 'D':return str4;
default: return str5;
}
}
int main()
{
char input;
scanf("%c",&input);
printf("%s\n",getWord(input));
return 0;
}

正确例子(返回的是字符串):

#inlcude
char *getWord(char c)
{
switch(c)
{
case 'A':return "Apple";
case 'B':return "Banana";
case 'C':return "Cat";
case 'D':return "Dog";
default: return "None";
}

}
int main()
{
char input;
scanf("%c",&input);
printf("%s\n",getWord(input));
return 0;
}

函数指针

一个指向函数的指针,是一个指针
C语言---指针函数和函数指针_第1张图片
和数组指针,指针数组一样的规律
比如printf这个函数,经过求值之后就会变成printf函数的地址
所以在定义了函数指针后,给它传递一个已经被定义的函数名,就可以通过该指针进行调用了
函数名在c语言中经过运算后就能得到函数的地址,可以用指针指向
例子:

#include 

int square(int);
int square(int num)
{
    return num*num;
}
int main()
{
    int num;
    int (*fp)(int);//定义一个函数指针
    printf("请输入一个整数:");
    scanf("%c",&num);
    fp=squre;
    printf("%d*%d=%d\n",num,num,(*fp)(num));
    return 0
}

可以利用函数指针,把一个函数作为参数传入另一个函数

#include 

int add(int,int);
int sub(int,int);
int calc(int (*fp)(int,int),int,int);//传入一个函数指针

int add(int num1,int num2)
{
    return num1+num2;
}

int sub(int num1,int num2)
{
    return num1-num2;
}

int calc(int(*fp)(int,int),int num1,int num2)//传入一个函数作为参数
{

    return (*fp)(num1,num2);
}

int main()
{

    printf("3+5=%d\n",calc(add,3,5));
    printf("3-5=%d\n",calc(sub,3,5));
    return 0;
}

将函数指针作为返回值
C语言---指针函数和函数指针_第2张图片
错误写法:

int(*fp)(int,int) select(int,int);//事实上,编译器会认为是两个函数的定义,故会报错

正确操作:

#include
int add(int,int);
int sub(int,int);

int add(int num1,int num2)
{
return num1+num2;
}
int sub(int num1,int num2)
{
return num1-num2;
}

int calc(int(*fp)(int ,int),int num1,int num2)
{
return (*fp)(num1,num2);
}
int (*select(char op))(int,int)//正确的返回值为函数指针的写法
{
switch(op)
{
case '+':return add;
case '-':return sub;
}
}

int main()
{
int num1,num2;
char op;
int(*fp)(int,int);//定义一个函数指针来接受

printf("请输入一个式子(如1+3):");
scanf("%d%c%d",&num1,&op,,&num2);//根据op这个运算符决定调用add还是sub
fp=select(op);
printf("%d %c %d=%d\n",num1,op,num2,calc(fp,num1,num2));
}

int (*select(char op))(int,int)//正确的返回值为函数指针的写法
为什么这么写
根据优先级:括号是第一优先级,方向是从左到右
1.考虑*select(char) 输入的是char类型参数,返回的是一个指针
2.考虑这个指针指向的是什么
把函数名去掉,简化上式得到:
int (*)(int,int)
发现这个指针指向的就是一个函数指针,返回一个返回整型,并且带有两个整型参数的函数指针!

补充内容

1.若希望函数有时候返回整型指针,有时候返回字符指针,需要定义一个void* 类型的指针函数
例子

#include 

void *func(int n, int *ptr, char *str);

void *func(int n, int *ptr, char *str)
{
        if (n > 0)
        {
                return ptr;
        }
        else
        {
                return str;
        }
}

int main(void)
{
        int num = 520;
        char *str = "FishC";

        printf("%d\n", * (int *) (func(1, &num, str)));
        printf("%s\n", (char *) func(-1, &num, str));

        return 0;
}

2.返回局部变量的地址和形参的地址都是错误的,因为形参和局部变量在程序运行时都是存放在stack中,函数一旦结束调用,stack的空间立即释放。
3. 函数指针数组的定义方法
double (*func[4])(double,double)={add,sub,mul,divi};//add等都是函数名
访问方法

for (int i=0;i<4;i++)
{
res=(*func[i])(x,y);
}

例子:
C语言---指针函数和函数指针_第3张图片

#include 
#include 

#define EPSINON 0.000001 // 定义允许的误差

double add(double x, double y);
double sub(double x, double y);
double mul(double x, double y);
double divi(double x, double y);

double add(double x, double y)
{
        return x + y;
}

double sub(double x, double y)
{
        return x - y;
}

double mul(double x, double y)
{
        return x * y;
}

double divi(double x, double y)
{
        // 不要对浮点数进行==或!=比较,因为IEEE浮点数是一个近似值
        if (y >= -EPSINON && y <= EPSINON)
        {
                printf("除数不能为0\n");
                // 如果除数为0,调用exit()函数直接退出程序
                exit(1);
        }
        else
        {
                return x / y;
        }
}

int main(void)
{
        int i;
        double x, y, result;
        double (*func_table[4])(double, double) = {add, sub, mul, divi};

        printf("请输入两个数:");
        scanf("%lf %lf", &x, &y);

        printf("对这两个数进行加减乘除后的结果是:");
        for (i = 0; i < 4; i++)
        {
                result = (*func_table[i])(x, y);
                printf("%.2f ", result);
        }
        putchar('\n');

        return 0;
}

你可能感兴趣的:(C语言,指针函数,函数指针)