文末有一个嵌入式工程师也经常写出的bug,看看你能发现是什么bug吗?
这个月,部门内部做代码review的时候,竟然发现就有两个小伙伴,多个地方犯了这个错误。
在上一篇文章 =>,我们讲解了指针的相关知识,其中,提到
既然函数是地址,而指针又是地址变量,聪明的小伙伴,可能就有疑问了,如果一个指针变量的值是一个函数的地址,会是个什么情况?好问题,这就是函数指针
在学习嵌入式C语言的过程中,有小伙伴经常把“指针函数”与“函数指针”容易混淆。
今天我们一篇文章把它理解透彻...
首先弄清楚它们之间的本质和定义,万事万物透过现象看本质,才能游刃有余:
一、指针函数
指针函数是指带指针的函数,即本质是一个函数,函数返回类型指针。
定义如下:
类型标识符 *函数名(参数表)
int *f(int x);
首先它是一个函数,只不过这个函数的返回值是一个地址值。
示例:
int* fun(int *a)
{
return a;
}
int main(void)
{
int a = 3;
printf("%d", *(fun(&a))); //打印结果3
return 0;
}
二、函数指针
函数指针是指向函数的指针变量,即本质是一个指针变量。指向函数的指针包含了函数入口地址,
可以通过它来调用函数。
函数指针的定义:
类型说明符 (*函数指针) (参数)
int (*fp)(int x);
函数指针的赋值:(两种形式)
fp=&func;fp=func;
代码示例:
int fun(int i)
{
return i + 1;
}
int main(void)
{
int r;
int (*funP)(int); // 声明指针
funP = fun; // 给函数指针赋值,方法1
funP = &fun; // 给函数指针赋值,方法2
r = funP(5); // 函数指针调用
printf("%d ", r); // 打印结果6
return 0;
}
函数指针的调用:(两种形式)
fp(x);// 无法区分,这里fp是函数指针,还是一个真正的函数?
(*fp)(x);//清晰区分,这里fp是一个函数指针,而不是一个函数
int fun(int i)
{
return i + 1;
}
int main(int argc, char **argv)
{
int r;
int (*funP)(int); //声明指针
funP = fun; //给指针赋值
r = funP(5); //函数指针调用,方法1
r = (*funP)(5); //函数指针调用,方法2
printf("%d ", r); //打印结果6
return 0;
}
也就是说,除了声明的地方,fun()与(*fun)()的作用是一样的。
这样,也就让C语言容易实现回调函数的结构,示例代码如下:
int funA(int i)
{
return i + 1;
}
int funB(int i)
{
return i - 1;
}
void fun(int (*funP)(int), int i)
{
printf("%d ", funP(i));
}
int main(void)
{
int (*funP)(int); //声明指针
funP = funA; //给函数指针赋值,类似注册回调函数
fun(funP, 5); //打印结果6
funP = funB; //给函数指针赋值,类似注册回调桉树
fun(funP, 5); //打印结果4
return 0;
}
好,到此小伙伴应该对函数指针和函数指针了解透彻了,那咱们来看看下面这一段代码,你能发现
其中的bug吗?
int* funcA(void)
{
int a = 10;
return &a;
}
int* funcB(void)
{
int b = 20;
return &b;
}
int main(void)
{
int *x,*y;
x= funcA();
y= funcB();
printf("%d", *x); // 打印结果会是多少呢?
return 0;
}
答案和详细解释,后面的文章再讲解咯。
定期以通俗易懂的方式分享嵌入式知识,关注公众号,加星标,每天进步一点点。