0
  • 聊天消息
  • 系统消息
  • 评论与回复
登录后你可以
  • 下载海量资料
  • 学习在线课程
  • 观看威廉希尔官方网站 视频
  • 写文章/发帖/加入社区
会员中心
创作中心

完善资料让更多小伙伴认识你,还能领取20积分哦,立即完善>

3天内不再提示

C语言函数不改变形参内容的说明

聚丰开发 2018-10-29 11:01 次阅读

注:本文是作者以前发表在其个人博客,现在发布到“聚丰开发”专栏


这也是面试时常碰到的题,通常是把一个指针作为函数的输入参数,在函数内部会改变输入参数对应的指针,问面试者在函数调用过程中指针的具体内容。


这里我也设计一个这样的函数,功能是对输入参数指定的地址连续写入指定个数的指定内容。问在位置(1)(2)(3)指针p的值,在位置(4)(5)指针 buf的值。



答案是:


位置(1)指针p还没赋值为空指针0
位置(2)(3)指针p的值均为&data_buf[0]
位置(4)针buf值为&data_buf[0]
位置(5)指针buf值为&data_buf[100]

void fill_buffer(unsigned char* buf,unsigned char data,unsigned char size)
{ //位置(4)
unsigned char i;
for(i=0;i {
*buf=data;
buf++;
}
}//位置(5)

void main(void)
{
unsigned char data_buf[256];
unsigned char *p;
p=(char*)data_buf; //位置(1)
fill_buffer(p,0,100); //位置(2)
while(1); //位置(3)
}


可能有的人会疑惑,明明指针p作为函数的参数,在函数中有进行递增操作,为什么函数返回后在位置三还是保持内容为&data_buf[0]不变?


有这种想法的人理解的逻辑流程如下,看上去也好像有道理。


void main(void)
{
unsigned char data_buf[256];
unsigned char *p;
p=(char*)data_buf;
fill_buffer(p,0,100); p在这里是输入参数
//unsigned char i;
//for(i=0;i //{
// *p=data;
// p++; 执行到这里不就是改变了p吗?
//}
while(1); 函数返回p应该也改变了
}


这种理解自然不对,对于函数的参数,不能简单的在函数中进行替代理解,以这里的fill_buffer(p,0,100)为例子,函数中并不会对p进行任何处理,而是先将p的值用一个临时变量保存起来(也可以为寄存器),在函数中使用的是这个临时变量。


如果用汇编来表示 fill_buffer(p,0,100)的调用过程,参考流程如下:


;lda x 为把x装到A中
;sta x 为把A的内容存到装x中
;得到第一个参数
lda p
sta buf_para
;得到第二个参数
lda #0
sta data_para
;得到第三个参数
lda #100
sta size_para
;跳转到具体函数代码位置
jsr fill_buffer



从这个流程可以看出指针p实际上没有被改写,虽然p所指的位置会被函数写入指定的内容,函数只是从p得到一个起始地址,在函数内部是通过另外一个指针来改写这个地址开始位置的内容,在调试中观察到的写指针是另外那个指针,并不是p。这也是C函数指针可以做输入输出参数,而变量只能做输入参数的原因。


如func(char *p,char data),函数可以读p所指的地址内容,也可以向p所指的地址写入指定内容,但data只能供函数使用,不能将函数中的值反存到data中。


声明:本文内容及配图由入驻作者撰写或者入驻合作网站授权转载。文章观点仅代表作者本人,不代表电子发烧友网立场。文章及其配图仅供工程师学习之用,如有内容侵权或者其他违规问题,请联系本站处理。 举报投诉
  • C语言编程
    +关注

    关注

    6

    文章

    90

    浏览量

    21104
  • 面试题
    +关注

    关注

    1

    文章

    11

    浏览量

    7971
收藏 人收藏

    评论

    相关推荐

    LMX2595在不改变设定参数的情况下,能实现多宽范围的倍频?

    我想问一下LMX2595在倍频的过程中,在不改变设定参数的情况下,能实现多宽范围的倍频?
    发表于 12-12 07:05

    同样是函数,在CC++中有什么区别

    同样是函数,在 CC++ 中有什么区别? 第一个返回值。 C语言函数可以不写返回值类型,
    的头像 发表于 11-29 10:25 287次阅读

    使用C语言实现函数模板

      用C语言能不能实现一个通用的函数,既能完成整数的相加,又能完成浮点数的相加?
    的头像 发表于 11-09 11:38 383次阅读

    C语言中的socket编程基础

    数据 步骤6:关闭socket 创建socket 在C语言中,创建socket需要使用socket()函数。这个函数需要两个参数:域
    的头像 发表于 11-01 16:51 307次阅读

    AIC3106如何在不改变BCLK和LRCLK的情况下,能够调好?

    你好,请问:AIC3106现在配置为从设备、DAC采样率为16K、数据宽度为32位。现在主设备给的BCLK是2048K,LRCLK为16K,播放现在有问题,如何在不改变BCLK和LRCLK的情况下,能够调好?
    发表于 10-28 07:06

    有没有什么办法在不改变电源和功率的情况下来解决TPA311XD2失真的问题?

    换了大电源之后就没有失真了,有没有什么办法在不改变电源和功率的情况下来解决芯片失真的问题,谢谢!!!
    发表于 10-25 08:34

    手把手教学!HLK-LD2410B/C新手必看攻略!测试教程、模块调一文详解~

    HLK-LD2410B/C接线教程、参数解析、APP调教程、上位机调教程、常见异常情况自检等等内容,一文汇总。 不管是萌新小白还是资深玩家,都可以快速入门。
    的头像 发表于 05-31 14:48 5043次阅读
    手把手教学!HLK-LD2410B/<b class='flag-5'>C</b>新手必看攻略!测试教程、模块调<b class='flag-5'>参</b>一文详解~

    使用增量式编码器,在PI参数不改变情况下,为什么MCSDK初始定位后转速波动大?

    使用增量式编码器,第一次启动时,转速波动较大,然后第二次启动转速波动就平稳了,我想问一下,在PI参数不改变情况下,为什么MCSDK初始定位后转速波动大?
    发表于 03-20 06:03

    C语言内存泄漏问题原理

    内存泄漏问题只有在使用堆内存的时候才会出现,栈内存不存在内存泄漏问题,因为栈内存会自动分配和释放。C语言代码中堆内存的申请函数是malloc。
    发表于 03-19 11:38 521次阅读
    <b class='flag-5'>C</b><b class='flag-5'>语言</b>内存泄漏问题原理

    浅谈C语言中的函数定义

    如果函数要使用参数,则必须声明接受参数值的变量。这些变量称为函数的形式参数。 形式参数就像函数内的其他局部变量,在进入函数时被创建,退出函数
    发表于 03-11 10:09 386次阅读

    C语言中的可变参数介绍

    C 语言为这种情况提供了一个解决方案,它允许您定义一个函数,能根据具体的需求接受可变数量的参数
    发表于 02-28 14:00 309次阅读
    <b class='flag-5'>C</b><b class='flag-5'>语言</b>中的可变参数介绍

    output函数怎么用

    output 函数是一个通用的术语,并不特指某个具体的编程语言或软件工具。 如果你在使用 Python 编程语言,那么可能是指 print 函数。Python 中的 print
    的头像 发表于 02-23 14:21 1252次阅读

    C语言中的动态内存管理讲解

    本章将讲解 C 中的动态内存管理。C 语言为内存的分配和管理提供了几个函数。这些函数可以在 头文件中找到。
    的头像 发表于 02-23 14:03 393次阅读
    <b class='flag-5'>C</b><b class='flag-5'>语言</b>中的动态内存管理讲解

    c语言,c++,java,python区别

    C语言C++、Java和Python是四种常见的编程语言,各有优点和特点。 C语言
    的头像 发表于 02-05 14:11 2380次阅读

    如何解决C语言中的“访问权限冲突”异常?C语言引发异常原因分析

    如何解决C语言中的“访问权限冲突”异常?C语言引发异常原因分析  在C语言中,访问权限冲突异常通
    的头像 发表于 01-12 16:03 5663次阅读