目录

嵌入式初学-C语言-二二

函数指针与指针函数

函数指针

定义:

函数指针本质是指针,他是函数的指针(定义一个指针变量,变量中存储了函数的地址)。函数都有一个入口地址,所谓指向函数的指针,就是指向函数的入口地址。这里函数名就代表入口地址。

函数指针存在的意义:
  1. 让函数多了一种调用
  2. 函数指针作为形参,可以形式调用(回调函数)
语法:

返回值类型(*变量名)(形式参数列表)

定义格式:

返回值类型(*变量名)(形式参数列表);

举例:

int (*p) (int a,int b);

函数指针的初始化
  1. 定义同时赋值
cs 复制代码
// 得先有函数,才能定义这个函数的指针
int fun(int a,int b){..}
// 定义函数指针并给它赋值
int (*p) (int a,int b) = fun;// fun不能跟()
  1. 先定义后赋值
cs 复制代码
// 得先有函数,才能定义这个函数的指针
float fun(int a,double b,char c){..}
// 先定义函数指针
float (*p) (int a,double b,char c);
// 赋值
p = fun;

总结:

  1. 函数指针指向的函数要和函数指针定义的返回值类型,形参列表对应,否则报错
  2. 函数指针是指针,但不能指针运算,如p++,没有实际意义
  3. 函数指针作为形参,可以形成回调
  4. 函数指针作为形参,函数调用事实参只能是与之对应的函数名,不能带小括号
  5. 函数指针的形参列表中变量名可以省略

案例:

cs 复制代码
/**
* 函数指针:指向函数的指针变量就是函数指针
需求:求a,b两个数的最大值
*/
#include <stdio.h>
int max(int a,int b)
{
if(a > b)
{
return a;
}
return b;
}
int main()
{
int a = 3,b = 2,c;
// 普通函数调用
c = max(a,b);
printf("%d,%d两个数中的最大值是:%d\n",a,b,c);
// 通过指针变量访问它指向的函数
// 创建指针并初始化
int (*p)(int,int) = max;
// 调用函数指针
c = p(a,b);
printf("%d,%d两个数中的最大值是:%d\n",a,b,c);
// 调用函数指针
c = (*p)(a,b);
printf("%d,%d两个数中的最大值是:%d\n",a,b,c);
return 0;
}

指针函数

定义:

本质是函数,这个函数的返回值类型是指针,这个函数称为之指针函数

在C语言中,一个函数不仅可以返回整型、字符型、实型等值,也可以返回指针类型的值,即C语言中还允许定义返回指针值的函数,

语法:

指针的类型 函数名(形参列表)、

{

函数体;

return 指针变量;

}

注意:

在函数中不要直接返回一个局部变量的地址,因为函数调用完毕后局部变量会被回收,使得返回的地址不明确,此时返回的指针就是野指针

解决方案:

如果非要访问可以给这个局部变量添加static,可以延长它的生命周期,从而避免野指针(尽量少用,存在内存泄漏)

案例:

cs 复制代码
/**
* 指针函数:函数的返回值是指针类型
需求:有若干个学生的成绩(每个学生有4门课程),要求在用户输入学生序号以后,能输出该学生的全部成绩。用
指针函数来实现。
*/
#include <stdio.h>
/* 定义一个函数,传入学生的序号,返回这个学生的所有课程成绩 */
float *search(float (*p)[4],int n)
{
// 定义一个指针,用来接收查询到的某个学生的所有课程
float *pt;
pt = *(p+n);
return pt;
}
int main()
{
// 准备所有学生的成绩
float score[][4]={{60,70,80,90},{56,66,76,76},{35,68,90,37}};
int i,m;
float *p;
printf("请输入学生序号(0~2):\n");
scanf("%d",&m);
printf("第%d个学生的成绩:\n",m);
p = search(score,m);// 函数返回值为行的首地址
// 遍历
for(i = 0; i < 4;i++)
printf("%5.2f\t",*(p+i));
printf("\n");
return 0;
}

野指针

定义:

访问了一个已经销毁或者访问受限的内存区域外的指针,这个指针就被称为野指针。

野指针产生的场景:

  1. 变量未初始化,通过指针访问该变量
  2. 指针变量未初始化
  3. 指针指向的内存空间被(free函数)回收了
  4. 指针函数中直接返回了局部变量的地址。
  5. 指针指向数组以外的地址(下标越界)

如何避免野指针:

  1. 通过编码规范避免
  1. 指针变量要及时初始化,如果暂时没有对应的值,建议及时赋值为NULL
  2. 数组操作(便利,指针运算)时注意数组的长度,避免越界
  3. 指针指向的内存空间被回收,建议给这个指着年两赋值NULL
  4. 指针变量使用之前要检查他的有效性(需要做非空校验)

说明:NULL是空常量,它的值时0,NULL一般存放在内存中的0x00000000位置,这个地址只能存放NULL,不能被其他程序修改

空指针

空指针又被称作悬空指针,当一个指针值时NULL,这个指针被称为空指针,对空指针访问会运行报错(段错误)

本文是转载文章,点击查看原文
如有侵权,请联系 xyy@jishuzhan.net 删除
相关推荐
꧁坚持很酷꧂4 分钟前
Qt实现点击按钮弹出侧边框(可用于登录界面)
开发语言·qt
No0d1es9 分钟前
CCF GESP C++编程 五级认证真题 2025年3月
开发语言·c++·青少年编程·gesp·ccf·五级·2025年3月
shuaixio16 分钟前
【C++代码整洁之道】第九章 设计模式和习惯用法
c++·设计模式·设计原则·常见设计模式·习惯用法
独好紫罗兰18 分钟前
洛谷题单3-P1217 [USACO1.5] 回文质数 Prime Palindromes-python-流程图重构
开发语言·python·算法
独好紫罗兰24 分钟前
洛谷题单2-P1424 小鱼的航程(改进版)-python-流程图重构
开发语言·python·算法
加瓦点灯1 小时前
观察者模式:解耦对象间的依赖关系
开发语言·javascript·观察者模式
愚润求学1 小时前
Linux开发工具——apt
linux·服务器·开发语言
程序员小赵同学1 小时前
AI Agent设计模式二:Parallelization
开发语言·python·设计模式
zhmc1 小时前
Cortex-M系列MCU的位带操作
单片机·嵌入式硬件
时光话1 小时前
Lua:第1-4部分 语言基础
开发语言·lua