在使用一个音频芯片时,需要用到这样一个功能,即对音量进行调节。在厂家提供的驱动里面没有这样的功能函数,因此需要自行添加。注意到厂家提供的驱动里面包含了一个写入命令的函数,void Vol_Cmd(uint 8 vol), 其中vol是音量的数值,范围为0~255,这个函数的作用就是通过写入vol的值来改变音量。

因此实现音量调节的思路就有了:

把当前vol的值相应的增加或者减少,然后再调用Vol_Cmd()函数把它写入到芯片中,就实现了音量的增减。很简单吧。但是有一个问题,那就是要注意到Vol_Cmd()函数是没有返回值的,那么vol的值怎么样才能更新呢?也就是说,怎样才能获得vol的当前值呢?

我最开始的想法是构造这样两个函数(以音量增加为例,音量减少类似):

uint8 Vol_Inc(uint8 vol)

{ if(vol<=0xf0)

vol+=0x0f;          //以15作为增量,从音量最小到最大一共有16档

Vol_Cmd(vol);

return vol;

}

很明显,我的想法是在 Vol_Inc()函数中做两件事,一件事是把vol的值增加之后写入到芯片中,实现音量的增加,另一件事是把增加后的值返回,以便下次调用Vol_Inc()函数的时候vol的值已经更新。那么调用这个函数就必须遵循这样的格式:

uint8 vol="120";          // 初始化为一个中间值

vol=Vol_Inc(vol);

当然这样是没有错误的,不过在板子上调试的时候却发现一个问题,那就是调用Vol_Inc()函数的次数不能连续超过六次,否则音量就变为0。Debug的时候单步跑到Vol_Inc()函数的时候就warning,然后error。研究了很长时间都没有解决这个问题。

同project leader沟通之后,他表示音量调节只需要5档就够了,但是最好还是要保持程序的flexibility。只需要5档?我把增量的值改为0x32之后放到板子上跑,这下就一切正常了,音量加减都没有问题。

问题看似解决了,但是我还是觉得不舒服。vol=Vol_Inc(vol);这个调用看来起很不舒服。抛开这个具体的问题,我想了一下函数调用的问题。想到指针的时候,我发现自己犯傻了。

C语言的函数调用采用的是传值调用,也就是说调用函数之后并不改变传递的原始参数的值,传递给子函数的只是一个副本,下面举例说明:

#include "stdio.h"

#include "stdlib.h"

void Vol_Inc(int p);

main()

{ int vol="100";

Vol_Inc(vol);

printf("vol=%d\n",vol);

system("pause");

}

void Vol_Inc(int p)

{ p+=15;

}

很明显,输出为vol=100;因为main在调用Vol_Inc()的时候只是把vol=100的一个副本传递给Vol_Inc(),调用之后vol的原本没有变,因此vol值并不会改变。但是这个音量加减程序要改变原本的值,怎么办? 很简单,用指针。与传值调用相对应的是引用调用(call by reference),C语言并不支持,只能通过使用指针参数来模仿。

#include "stdio.h"

#include "stdlib.h"

void Vol_Inc(int *p);

main()

{ int vol="100";

Vol_Inc(&vol);

printf("vol=%d\n",vol);

system("pause");

}

void Vol_Inc(int *p)

{ *p+=15;

}

这下输出就是vol=115了,也就是说我的目的达到了。按照这个思路修改了一下音量增减的函数,放在板子上运行,完全正常。难道以前的vol=Vol_Inc(vol)调用有问题?我怀疑是。不管了,我也没有精力去深究了,反正这个问题已经解决了。

经验教训:

这个问题是一个初级得不能再初级的C语言问题,自己怎么就在开始走了弯路呢。埋头做项目的时候,思路太窄,不能把以往学习的知识很好的应用起来。前天一个师兄在QQ群里也说道,大家都在做项目,几乎都没有怎么静下心看书,其实书上很多的地方都写得很清楚了……

*博客内容为网友个人发布,仅代表博主个人观点,如有侵权请联系工作人员删除。

c语言 函数调用 传值调用 引用调用 传地址调用,C语言中的传值调用和引用调用...相关推荐

  1. vue调用函数怎么传参_Vue(非)父子组件的传值以及方法调用

    1.vue父组件给子组件传值的方法 子组件中通过props接收传值 props:{ username:{ type:String, default:"" } } 2.vue父组件调 ...

  2. C/C++ 传值,传引用,传地址

    1,传值,当把值赋给函数形参时,是赋值的副本,在函数里做的任何改变都不会影响实参的值, eg: void swap(int a,int b) {int temp;temp = a;a = b;b = ...

  3. java值传递和引用传递_辨析Java方法参数中的值传递和引用传递

    小方法大门道 小瓜瓜作为一个Java初学者,今天跟我说她想通过一个Java方法,将外部变量通过参数传递到方法中去,进行逻辑处理,方法执行完毕之后,再对修改过的变量进行判断处理,代码如下所示. publ ...

  4. 计算机绝对引用公式是什么意思,会计电算化中公式里的绝对引用是指什?

    会计电算化就是在会计工作中以电子计算机代替手工方式对会计业务进行处理,并部分代替人对会计信息进行整理.加工.分析.预测及至对经济活动的决策.它是以计算机为核心,融系统论.会计学.计算机技术及信息技术为 ...

  5. html中哪个是正确引用外部样式表的方法,以下的HTML中( )是正确引用外部样式表的方法 答案:link rel=stylesheet type=text/css href=mystyl...

    相关问题 智慧,职教,list,style,type,属性,列表项,标记,类型,列表,中,列表项,默认,标记,列表项,旁边,实心,圆, 年金,现值,时,现值,函数,参数,中,type,值, 按钮,ty ...

  6. C++中的参数传递方式:传值、传地址、传引用总结

    指针:指针是一个变量,只不过这个变量中存储的是一个地址,指向内存中的一个单元. 引用:引用和原变量是同一个东西,只不过是原变量的一个别名. int a = 10; 定义一个整型变量aint *p = ...

  7. Java中的值传递和引用传递

    当一个对象被当作参数传递到一个方法后,此方法可改变这个对象的属性,并可返回变化后的结果,那么这里到底是值传递还是引用传递?      答:是值传递.Java 编程语言只有值传递参数.当一个对象实例作为 ...

  8. java 地址传递 返回值_Java中的值传递和引用传递

    这几天一直再纠结这个问题,今天看了这篇文章有点思路了,这跟C++里函数参数为引用.指针还是有很大区别. 当一个对象被当作参数传递到一个方法后,此方法可改变这个对象的属性,并可返回变化后的结果,那么这里 ...

  9. string 引用没有设置为 string 的实例。 参数名: s_Java中的值传递和引用传递,看完这篇终于终于明白了!...

    当一个对象被当作参数传递到一个方法后,此方法可改变这个对象的属性,并可返回变化后的结果,那么这里到底是值传递还是引用传递?  答:是值传递.Java 编程语言只有值传递参数.当一个对象实例作为一个参数 ...

  10. [转]java中的值传递和引用传递

    java中的值传递和引用传递 值传递:方法调用时,实际参数把它的值传递给对应的形式参数,方法执行中形式参数值的改变不影响实际参 数的值. 引用传递:也称为传地址.方法调用时,实际参数的引用(地址,而不 ...

最新文章

  1. nb移动udp_hwasy-geomagnetism-nbiot
  2. 【爬蟲】使用Jsoup解析文档
  3. java网络接口_java网络编程之识别示例 获取主机网络接口列表
  4. 椭圆极点极线性质_笔记:关于极点极线的一些思考
  5. SpringBoot 小技巧
  6. 21天jmeter打卡day5-完成对www.baidu.com的两条接口测试
  7. Node-ES6模块化
  8. 单目标决策---决策的分类
  9. Vulkan开发环境配置 Win10+VS2019
  10. 分享6款国内、外开源PHP轻论坛CMS程序
  11. android netd firewall 分析,第2章 深入理解Netd
  12. 经济均衡问题及其应用 (一):根据供需函数 确定市场的清算价格
  13. 电脑C盘怎么清理到最干净
  14. linux 网卡绑定解绑,网卡绑定开机绑定,关机解绑
  15. 25W三星快充协议芯片,支持支持USB PD 3.0
  16. 《点线SLAM系统》
  17. linux下同一个tomcat部署多个项目
  18. spring framework远程代码执行漏洞复现(CNVD-2022-23942 CVE-2022-22965)
  19. Qt编写安防视频监控系统52-颜色配置
  20. 京东平台研发:领域驱动设计(DDD)实践总结

热门文章

  1. 【剑指offer】面试题45:把数组排成最小的数
  2. python列表切片赋值_Python中对切片赋值原理分析
  3. Android pda出入库管理,出入库PDA管理系统软件
  4. python交叉验证函数_python – 在sklearn中使用交叉验证和AUC-ROC作为逻辑回归模型...
  5. C语言二维数组找出交集,【leetcode C语言实现】剑指 Offer 04. 二维数组中的查找...
  6. python处理报错_python3报错及解决方案/须注意的细节(持续更新)
  7. linux vim复制和粘贴
  8. Linux学习之如何在物理机上安装Linux发行版
  9. struts2服务端与android交互
  10. python 命令行 解析模块 optparse、argparse