开发者学堂课程【你的第一门 C 语言课:指针函数和函数指针】学习笔记,与课程紧密联系,让用户快速学习知识
课程地址:https://developer.aliyun.com/learning/course/444/detail/5479
指针函数和函数指针
目录:
一、指针函数
二、函数指针
一、指针函数
1.函数的类型是函数的返回值根据需求一个函数可以返回整型,浮点型等等也可以返回指针类型的数据,定义的时候只需要定义指针变量,在后面加*号。
例:
char *getWord(char);
char *getiord(char c)
{
switch(c)
{
case'A':return"Apple";
case'B':return"Banana00";
case'C':return"Cat";
case'D': return“Dog”;
default:return "None";
}
}
int maia()
{
char input;
printf("请输入一个字母:");
scanf("%c, &input);
printf("%s\n",getWord(input));
return 0;
}
gcc test1.c && ./a.out
要从 getWord 这个函数获得字符串,通常是没有一个类型定义字符串,都是用char 类型的指针来定义字符串,因为 char 类型指针是指向一个字符,我们用来指向字符串的第一个字符,字符串约定是截止于空字符(\0),知道第一个字符就知道整个字符串。
2.用指针变量作为函数的返回值就称之为指针函数
3.注:不要返回局部变量的指针
为什么?
例:
char *getWord(char);
char *getiord(char c)
{ char str1[]="Apple";
char str2[]="Banana00";
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 maia()
{
char input;
}
编译程序: gcc test2.c && ./a.out
编译器报出5个 warning,但还是通过了,因为编译器也不确定这么做是故意还是人为,输入A发现什么也没有,因为这个函数现在返回的是局部变量的地址,因为用数组定义的函数变量,局部变量的作用域仅限于函数的内部,不可以出函数,所以Apple 这个字符串只存在于 getWord 里,把它的地址返回给 main,当程序执行到这获得地址时 Apple 已经被销毁。
4.为什么直接返回字符串没问题?
因为字符串没有定义到变量里,字符串在 c 语言里比较特殊,找到一个固定的存储区域来存放,字符串是不可变的,它存储的位置不在这个函数里。
二、函数指针
1.指针函数是一个函数,函数指针是一个指针。
与数组指针一样使用()将函数的指针和前面的*括起来
指针函数:int*p();
函数指针:int(*p)();
例:
int square(int);
{
return num * num;
}
int main()
{
int num;
int (*fp)(int);
printf("请输入一个整数")
scanf("%d",&num)
fp=square;
printf("%d * %d = %d\n",unm,num,(*fp)(num))
return 0;
}
gcc test3.c && ./a.out
2.函数指针作为参数
例:
int add(int,int);
int sub(int,int);
int calc(int (*fp)(int,int), int,int);
int add(int numl, int num2)
{
return numl + num2;
}
int sub(int numl, int num2)
{
return numl - num2;
}
int calc(int (*fp)(int, int), int numl, int num2)
{
return (*fp)(numl, num2);
}
i
nt
main()
{
printf("3
+
5 %d\n" calc(add, 3, 5));
printf("3
-
5 %d\n" calc(
sub,
3
,
5));
r
eturn
0;
}
3.函数指针作为返回值
比如这个函数的名字叫 select,它本身有两个参数,返回返回值是一个函数指针,这函数指针也有两个参数,并且其返回值为整型
例:现在让用户输入一个表达式,然后程序根据用户输入的运算符来决定调用 add 还是 sub 函数进行运算。
int add(int, int);
int sub(int,
int);
int calc(int(*)(int,int), int,int);
i
nt
(*select(char))(int,int);
i
nt
add(int numl, int num2)
{
return numl +num2;
}
int sub(intnuml, int num2)
{
return numl - num2;
}
i
nt
calc(int (*fp)(int, int), int num1, int num2)
{
return (*fp)(numl,num2);
}
int(*select(char op))(int,int)
{
switch(op)
{
case
’
+
’
:return add;
case
’
-
’:return sub;
}
}
int main()
{
int numl,num2;
char op;
int (*fp)(int,int);
printf("请输入一个式子(如1
+3
)
:
")
;
scanf("
%
d
%
c%d",&num1,&op,&num2)
;
fp = select(op)
printf(
“
%d %c %d=%d\n
”
,num1,op,num2,calc(fp,num1,num2));
return 0;
}
gcc test5.c&& ./a.out
因为运算符是有优先性的,运算方向从左到右。
把函数名和它对应的参数去掉之后发现是一个函数指针,所以 select 函数返回值是返回一个返回整型并且带有两个参数的函数指针。