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

    浏览量

    21093
  • 面试题
    +关注

    关注

    1

    文章

    9

    浏览量

    7968
收藏 人收藏

    评论

    相关推荐

    使用C语言实现函数模板

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

    C语言中的socket编程基础

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

    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 4546次阅读
    手把手教学!HLK-LD2410B/<b class='flag-5'>C</b>新手必看攻略!测试教程、模块调<b class='flag-5'>参</b>一文详解~

    C语言内存泄漏问题原理

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

    浅谈C语言中的函数定义

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

    C语言中的可变参数介绍

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

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

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

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

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

    如何给C语言中的函数定义两个不同的名字?

    最近有位哥问我,如何给C语言中的函数定义两个不同的名字?就是这两个名字都是指向同一个函数,同一个地址,而且两个名字都可以当做函数来用的那种。
    的头像 发表于 12-19 16:21 757次阅读

    嵌入式C编码中函数的规范

    ◎ 一个函数仅完成一件功能 ◎ 重复代码应该尽可能提炼成函数说明:重复代码提炼成函数可以带来维护成本的降低。重复代码是不良代码最典型的特征之一。在“代码能用就
    的头像 发表于 12-07 14:33 341次阅读

    c语言源程序的基本单位

    C语言源程序的基本单位是函数函数是一组有关联的语句和表达式的集合,它们一起完成特定的任务。在C语言
    的头像 发表于 11-26 09:05 2025次阅读

    如何把c语言源程序变成应用程序

    的,并且通常以.c作为文件扩展名。源代码包括函数、变量和其他语句,它们被编译器翻译成机器代码,然后在计算机上执行。 编写C语言源代码时,需要遵循C
    的头像 发表于 11-26 09:04 3355次阅读

    一个c源程序至少包括一个函数

    一个C源程序至少包括一个函数C语言是一种广泛应用于嵌入式系统和操作系统的程序设计语言。它的基本构造块是
    的头像 发表于 11-26 09:01 1055次阅读