c语言指void函数的指针,C语言中的函数指针与指针函数

2023-05-16

函数是任何一门语言中必不可少的部分,正是由这些函数组成了程序。首先谈一下C语言中的函数指针与指针函数,再了解一下函数参数传递的相关原理。

1.函数指针与指针函数

(1) 函数指针 即指向这个函数的指针,定义为 数据类型 (*fun)(参数列表) ,()的优先级比*高,所以*fun加括号。如 void (*fun)(int*,int*);

(2)指针函数 即返回值是指针的函数,定义为 数据类型 * fun(参数列表). 如 char* fun(int*,int*);即返回值为char*型。

在C语言中,变量有它的地址,同理函数也是有地址的。那么把函数的地址赋给函数指针,再通过函数指针调用这个函数就可以了。

第一步: 定义函数指针,如 int (*pfun)(int*,int*);

第二步: 定义函数  如 int fun(int*,int*);

第三步: 把函数的地址赋给函数指针,即 pfun=fun;

第四步: 通过函数指针去调用这个函数 (*pfun)(p,q); //pfun是函数的地址,那么 *pfun当然就是函数本身了。

2.函数参数传递问题

在C语言中,有两种参数传递的方式 ,一种是值传递,另一种是指针传递。

值传递很好理解,即把实参的值传递给形参。

而指针传递传的是地址在C语言中,形参值的改变并不能改变实参的值,但形参所指向内容值的改变却能改变实参,这一点非常的重要,是指针传递的精华所在。

3. 指针函数

当函数的返回值为指针类型时,应该尽量不要返回局部变量的指针,因为,局部变量是定义在函数内部,当这个函数调用结束了,局部变量的栈内存也被释放了,因此,不能够正确的得到返回值。实际上,内存已经被释放了,但这个指针的地址已经返回过去了,但是这个地址已经是无效的了,此时,对这个指针的使用是很危险的。

4. 野指针

野指针并不是NULL,而是指向垃圾内存的指针。

有两种情况可以导致野指针:

(1) char* p;

(2)malloc,free

第一种情况是定义指针,但没有给指针赋地址,此时,对指针的使用是很危险的,因为你不知道它指向哪里,是个野指针。

第二种情况,malloc是在堆上分配内存,必须由用户手动释放,当释放之后,指针指向的内存已经释放掉了,但指针本身的地址还存在,即指向了一个无效的内存,所以这时的指针为野指针,必须把这个指针p=NULL.

5. 下面举个例子说明上述几种情况

#include

#include

#include

#include

void fun1(int*,int*);

void fun2(int*,int*);

char* fun(char*,char*);//指针函数,即返回值为指针的函数

int main(){

//定义3个函数指针

void (*pfun1)(int*,int*);

void(*pfun2)(int*,int*);

char*(*pfun)(char*,char*);//定义返回值为指针的函数指针

int *p;

int *q;

int a=10;

int b=20;

p=&a;//整形指针变量的初始化

q=&b;

printf("%d\n",*p);

printf("%d\n",*q);

pfun1=fun1;//把函数fun的地址赋值给函数指针pfun

pfun2=fun2;

(*pfun1)(p,q);//用函数指针去调用函数,pfun是fun的地址,那么*pfun当然就是函数本身了

printf("%d\n",*p);

printf("%d\n",*q);

//当交换两个指针时,发现值并没有发生改变

//在C语言中,形参的改变并不能改变实参,实参中p指向a的地址,q指向b的地址,在形参中,把两个地址互换,即形参的p指向b的地址,q指向a的地址,但并不能改变实参的值,除非改变地址中的内容值

(*pfun2)(p,q);

printf("%d\n",*p);

printf("%d\n",*q);

//此时p与q指向的值发生了变化,由于把地址中的内容交换了,所以交换了p,q

pfun=fun;

char* x="ab";

char* y="bc";

char* s=(*pfun)(x,y);

printf("%s\n",s);

//free(s);//s指向这个堆内存,所以malloc之后要释放

s=NULL;

if(s!=NULL){//释放掉这个内存后,指针仍然不为空,此时的指针称为野指针,所以要把s=NULL

printf("%s\n",s);

}

//对于野指针,有两种情况

//第一种情况: char* p;只声明了字符型指针,但没明确指向的地址,此时,用这个指针是很危险的,因为这个指针是野指针

//第二种情况: malloc()之后,没有free()之后,没有把指针设置为空,因为此时指针仍然存有地址,但是这个地址已经是无效的,所以对这个指针的使用是很危险的

return 0;

}

void fun1(int*p,int*q){

int* temp=p;

p=q;

q=temp;

}

void fun2(int*p,int*q){

int temp;

temp=*p;

*p=*q;

*q=temp;

}

char* fun(char*p,char* q){

//char a[]="abc";//定义一个内存空间,局部变量栈上内存

//char* s=a;

//return s;//在这函数结束之后,char型指针被释放掉,因此不能正确返回

//因此,最好别返回一个局部变量指针

//(1)解决方法:把数组变成静态,即 static char a[]="abc";静态内存在函数结束后不会被释放

//(2)申请堆内存

//(3)定义为常量区

//char *s=(char*)malloc(sizeof(char*)*10);

// strcpy(s,"abc");

char* s1="ssss"; //定义一个指针变量指向字符串,在C中,字符串被存放在常量区,静态存储区域,因此,在这个函数结束之后,这个地址仍然是有效的,即常量区的内存没有被释放掉,因此能够返回值

return s1;

}

1. fun1函数

fun1函数中交换地址,并不能交换两个指针指向的值,因为形参的改变不能引起实参的改变。

2. fun2函数

fun2函数交换的是地址里面的内容,所以能交换两个指针指向的值。

3. fun函数

(1)fun函数里面定义的a是个局部变量,在函数返回之后这块内存会被释放掉。因此,为了得到返回值,可以声明为 static char a[]=""abc";

(2)malloc申请的是堆内存,因此,可以得到返回值,但必须free掉这块内存,同时将p=NULL,避免野指针。

(3)可以定义char* s=字符串,在C语言中,字符串是存放是静态常量区,因此,函数结束后,那块内存不会被释放掉。可以得到返回值。

因此,不能返回局部指针变量。

C语言中,形参只有在传递时才分配内存单元,实参到形参的传递是单向传递,因此,形参的改变并不能引起实参的改变,另外,实参与形参占据着不同的内存单元。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

c语言指void函数的指针,C语言中的函数指针与指针函数 的相关文章

  • git 如何解决 (master|MERGING)

    git 如何解决 master MERGING git reset hard head 回退版本信息 git pull origin master 转载于 https www cnblogs com 651434092qq p 110188
  • linux ping 指定次数

    ping 192 168 0 1 c4 转载于 https www cnblogs com sea stream p 10345600 html
  • java 解决 java.lang.Integer cannot be cast to java.lang.String

    1 在执行代码打印map的value时 xff0c 提示错误java lang Integer cannot be cast to java lang String xff0c 这个错误很明显是类型转换错误 查看表字段的数据 解决方案 1
  • DBoW2应用

    图像对应的bag of words向量 v t 假设词典总共有 W 个单词 xff0c 那么每一幅图像能够用一个 W 维的向量表示 xff08 t 1 t 2 t 3 t W xff09 其中 t i 61 frac n id n nd l
  • 平衡车终于成功了

    说来惭愧2017 12 0118 13 27 并非原创 xff0c 代码资料也是从论坛搜刮的 自己做了适配性的调整 这个小车断断续续造了将近1个月 xff01 1 include 34 Wire h 34 96 2 include lt U
  • 彻底解决 Jenkins Slaver 节点无法执行 Git-LFS 命令

    最新配置新增一台iMac当作持续集成构建的Slaver节点 xff0c 添加节点很顺利 xff0c 但是拉取代码的时候发现无法正常 出现以下提示 xff1a hudson plugins git GitException Command 3
  • FreeRTOS

    在嵌入式领域中 xff0c 嵌入式实时操作系统正得到越来越广泛的应用 采用嵌入式实时操作系统 RTOS 可以更合理 更有效地利用CPU的资源 xff0c 简化应用软件的设计 xff0c 缩短系统开发时间 xff0c 更好地保证系统的实时性和
  • 使用固定的公网TCP端口地址远程桌面【内网穿透】

    文章目录 1 为远程桌面保留一个TCP地址2 配置远程桌面隧道2 1 登录cpolar web ui2 2 修改远程桌面隧道信息2 3 查看公网地址 3 使用固定TCP地址远程桌面总结 在上一篇文章中 xff0c 我们通过cpolar映射远
  • [Openwrt 项目开发笔记]:Openwrt平台搭建(一)补遗

    Openwrt项目开发笔记 系列文章传送门 xff1a http www cnblogs com double win p 3888399 html 正文 xff1a 昨晚上熬夜写了 Openwrt项目开发笔记 Openwrt平台搭建 xf
  • Mac下IDEA启动Springboot项目慢

    经过百度以及google查询发现 xff0c 启动时调用了java net InetAddress getLocalHost 方法 以此排查调用此方法慢的问题 网上的解决方法都是修改hosts xff0c 后来有人提出 xff0c 慢的原因
  • 关于varnish缓存

    目录 引言 xff1a 缓存的概念一 varnish缓存 1 简介2 总体结构 2 1 两个主进程2 2 Varnish的日志2 3 VCL varnish配置缓存策略的工具二 Varnish的工作模式 more 1 状态引擎的处理流程2
  • varnish6.X安装

    目录 1 rpm方式2 编译安装 2 1 依赖包2 2 编译Varnish 本文提供了两种安装方式 xff0c 但建议使用编译安装 官方链接 xff1a https varnish cache org 部署文档 xff1a https va
  • 安装ANSYS19.0的正确方法(附下载)

    安装ANSYS19 0的正确方法 卸载干净旧版本ANSYS 安装或重新安装之前必须先卸载干净 xff0c 安装过旧版本ANSYS的也要确保卸载干净 电脑环境准备参考以下内容 ANSYS 卸载后重装需要注意的问题 百度经验 https jin
  • 软件设计师 - 错题笔记

    2018 年 5 月 上午题 1 浮点数 浮点数对接时 xff0c 先对阶 xff0c 将小阶向大阶对齐 xff0c 同时尾数右移 n 位 xff08 n 为阶差的绝对值 xff09 2 流水线吞吐率 1 t 单位时间流水线处理的任务数 流
  • CAtia_打开提示:许可证过期怎么办

    CAtia 许可证过期怎么办 xff1a 进计算机管理 xff0c 点开服务和应用程序 xff0c 点服务 xff0c 找到DS License Server xff0c 在启动此服务的地方点启动 xff0c 从而开启DS License
  • 小米手机 fastboot 方式刷入 TWRP recovery 教程,以红米4X(santoni)为例

    最新版TWRP下载链接 xff1a https twrp me xiaomi xiaomiredmi4x html platform tools下载地址 xff1a https developer android google cn stu
  • 远程登录DSM,显示“您没有权限使用本项服务?

    远程登录DSM xff0c 显示 您没有权限使用本项服务 xff1f https www chiphell com thread 825297 1 1 html 有可能你单位用的是多wan接入 一般synology不让多个ip同一帐号同时接
  • 无人机寻迹要两个单片机吗_基于OpenMV的循迹无人机设计

    基于OpenMV的循迹无人机设计 发表时间 xff1a 2020 08 24 基于OpenMV机器视觉模块进行目标识别算法的研究 利用图像的滤波 二值化等算法对摄像头采集的图像进行预处理 利用边缘检测和形状识别算法获得引导线的路线信息 xf
  • linux 流量查看工具 iftop 配置

    linux 流量查看工具 iftop 配置 iftop是LINUX下查看网络流量的软件 iftop 官方网站 http www ex parrot com pdw iftop 1 iftop如何安裝 xff1a 首先查看自己的系统是否安裝
  • 技术系统进化法则是_技术系统进化论,模式七、系统由宏观向微观进化

    阿奇舒勒TRIZ理论三个核心思想 xff1a 1 无论是一个简单产品还是复杂的技术系统 xff0c 其核心技术的发展都是遵循着客观的规律发展演变的 xff0c 即具有客观的进化规律和模式 xff1b 2 各种技术难题和矛盾的不断解决是推动这

随机推荐

  • 吉他谱

    其实我是个诗人 01 得不到你 02 多想在平庸的生活拥抱你 03 往后余生 04 成都 转载于 https www cnblogs com zhangmingyan p 11603872 html
  • Openssl配置CA证书及https访问

    一 创建根秘钥对 1 创建目录 cd mkdir root ca cd root ca mkdir certs crl newcerts private chmod 700 private touch index txt echo 1000
  • Thread.currentThread().setContextClassLoader为什么不生效与java.lang.NoClassDefFoundError之Java类加载的Parent fir...

    众所周知 xff0c Java的类加载机制采用了双亲委派模型 xff0c 导致在进行类加载的时候会有多个加载器 xff0c 这种复杂的机制 xff0c 有时候会导致 Exception in thread main java lang No
  • C#编写的通过汉字得到拼音和五笔码

    public static class SpellAndWbConfig region 变量声明 XML文件读取实例 lt summary gt XML文件读取实例 lt summary gt private static XmlReade
  • 设置HTML5的video播放速度

    var speed 61 1 5 设置速度 var vdo 61 document getElementById 34 视频的id 34 获取id vdo playbackRate 61 speed 改变速度 合并一句 document g
  • uni-app 做路由拦截器

    插件市场 xff08 https ext dcloud net cn plugin id 61 159 xff09 吐槽 好多小伙伴跑来问我有没有Uni app视频教程 xff0c 收费的也行 各位uni app 你根本不需要买市面上几百块
  • 华为S5700交换机初始化和配置SSH和TELNET远程登录方法

    华为S5700交换机初始化和配置TELNET远程登录方法 xff1a 1 交换机开启Telnet服务 lt Huawei gt system view 进入系统视图 Huawei telnet server xff1f 查看有enable还
  • 方差的无偏估计如何计算?

    我们常常被问到 34 方差的无偏估计如何计算 xff1f 和有偏估计的区别是什么 xff1f 34 xff0c 心想 34 哎呀 xff0c 又忘了 34 本篇回归问题本质 xff0c 带你理解这些名词背后解决的实际问题 xff08 通过总
  • C++ for无限循环~

    无限循环 如果条件永远不为假 xff0c 则循环将变成无限循环 for 循环在传统意义上可用于实现无限循环 由于构成循环的三个表达式中任何一个都不是必需的 xff0c 您可以将某些条件表达式留空来构成一个无限循环 include lt io
  • VINS-Fuison调试笔记

    最近一直在断断续续的调试vins fuison xff0c odometry总是各种飘 xff0c 令人头大 记录一下调试过程 xff0c 供以后学习参考 首先选用一组可靠的视觉惯导传感器 xff0c 如Realsense D435i xf
  • 《C和指针》阅读笔记

    第9章 字符串 字符和字节 9 1 字符串基础 字符串就是一串 零个或多个字符 xff0c 并且以一个位模式为全0的NUL字节结尾 因此 xff0c 字符串所包含的字符内部不能出现NUL字节 NUL字节是字符串的终止符 xff0c 但它本身
  • 【蓝牙数据采集模块】-02-Sensor Controller 编写CC2650STK外设驱动

    上次说到把所有的传感器模块在Sensor Controller中实现读写 xff0c 并封装驱动 先来看一下CC2650STK的原理图 用红色方框标记的DIO 0 DIO 7 DIO 23 DIO 30是可以通过Sensor Control
  • ->:间接引用运算符

    gt 是一个整体 xff0c 它是用于指向结构体 C 43 43 中的class等含有子数据的指针用来取子数据 换种说法 xff0c 如果我们在C语言中定义了一个结构体 xff0c 然后申明一个指针指向这个结构体 xff0c 那么我们要用指
  • linux音频服务器,Linux声音系统

    TAG linux alsa oss pulseaudio esd aRts DATE 2013 08 13 Linux声音系统有些混乱 xff0c 它有三套音频驱动 OSS Open Sound System 商业版的OSS xff0c
  • android 网络调试工具,安卓网络调试助手

    安卓网络调试助手apk是一款内容比体积精彩得多的网络设置软件 安卓网络调试助手支持多种端口和协议 xff0c 而且安卓网络调试助手apk虽然功能很专业但是操作起来也不是很难 xff0c 很容易学会 xff01 软件介绍 安卓网络调试助手ap
  • 计算机非全日制硕士 选校,非全日制硕士研究生,到底值不值得报考?看完这篇就懂了!...

    网友一 xff1a 如果不是已经工作的 xff0c 不推荐报考 因为非全日制的待遇不如全日制 xff0c 同时公务员等体制很多要求全日制学历 同时学费也比全日制贵好几倍 加上本身作为新生事物 xff0c 就业市场的认可与否还很难讲 如果你已
  • android进入后台被杀死,Android后台杀死系列之一:FragmentActivity及PhoneWindow后台杀死处理机制...

    新Activity启动及旧Activity保存流程 App在后台久置后 xff0c 再次从桌面或最近的任务列表唤醒时经常会发生崩溃 xff0c 这往往是App在后台被系统杀死 xff0c 再次恢复的时候遇到了问题 xff0c 而在使用Fra
  • V4L2框架

    前言 在分析v4l2之前最好具有的知识 xff1a 1 字符设备 因为v4l2是被枚举为字符设备 2 内存分配和映射 比如相关数据结构的分配和buffer 3 DMA xff0c 因为v4l2的数据传输用到了DMA 4 I2C xff0c
  • linux串口命令UART,STM32串口通信UART使用

    STM32串口通信UART使用 uart使用的过程为 xff1a 1 使能GPIO口和UART对应的总线时钟 2 配置GPIO口的输出模式 3 配置uart口相关的基本信息 4 使能uart口的相关的中断 xff0c 如接收中断 空闲中断等
  • c语言指void函数的指针,C语言中的函数指针与指针函数

    函数是任何一门语言中必不可少的部分 xff0c 正是由这些函数组成了程序 首先谈一下C语言中的函数指针与指针函数 xff0c 再了解一下函数参数传递的相关原理 1 函数指针与指针函数 1 函数指针 即指向这个函数的指针 xff0c 定义为