指针函数
返回值是一个指针,就称为指针函数,是一个函数
#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;
}
函数指针
一个指向函数的指针,是一个指针
和数组指针,指针数组一样的规律
比如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;
}
将函数指针作为返回值
错误写法:
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);
}
例子:
#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;
}
本帖子中包含资源
您需要 登录 才可以下载,没有帐号?立即注册