- 1、本文档共5页,可阅读全部内容。
- 2、原创力文档(book118)网站文档一经付费(服务费),不意味着购买了该文档的版权,仅供个人/单位学习、研究之用,不得用于商业用途,未经授权,严禁复制、发行、汇编、翻译或者网络传播等,侵权必究。
- 3、本站所有内容均由合作方或网友上传,本站不对文档的完整性、权威性及其观点立场正确性做任何保证或承诺!文档内容仅供研究参考,付费前请自行鉴别。如您付费,意味着您自己接受本站规则且自行承担风险,本站不退款、不进行额外附加服务;查看《如何避免下载的几个坑》。如果您已付费下载过本站文档,您可以点击 这里二次下载。
- 4、如文档侵犯商业秘密、侵犯著作权、侵犯人身权等,请点击“版权申诉”(推荐),也可以打举报电话:400-050-0827(电话支持时间:9:00-18:30)。
- 5、该文档为VIP文档,如果想要下载,成为VIP会员后,下载免费。
- 6、成为VIP后,下载本文档将扣除1次下载权益。下载后,不支持退款、换文档。如有疑问请联系我们。
- 7、成为VIP后,您将拥有八大权益,权益包括:VIP文档下载权益、阅读免打扰、文档格式转换、高级专利检索、专属身份标志、高级客服、多端互通、版权登记。
- 8、VIP文档为合作方或网友上传,每下载1次, 网站将根据用户上传文档的质量评分、类型等,对文档贡献者给予高额补贴、流量扶持。如果你也想贡献VIP文档。上传文档
查看更多
C51参数可变函数.
C51中的参数可变函数
作为引导的例子:假设要编写一个函数,来求n个数中最大的一个。函数的声明像下面这样:
unsigned char max( unsigned n , … ) ;
本文的目标就是实做这个函数。
C语言栈空间的处理方式:我们很容易看懂这样的代码
int sum ( int a ,int b )
{
return ( a + b ) ;
}
void main ( void )
{
int x ;
x = sum ( 1 , 2 ) ; /*子函数的调用和返回*/
While( 1 ) ;
}
每一次子函数的调用和返回就伴随着一系列的压栈和出栈,但是“内存不可以泄露”,所以子函数返回后栈指针应该恢复到原来的位置,如下图所示:
有两种修正栈的办法:一种是在子函数sum内进行处理,另一种在调用子函数sum结束的地方处理。这也就是C语言函数的栈空间处理的两种方式_cdecl和_stdcall,您可以把_cdecl和_stdcall想象成两个函数,一调用就修正栈指针,如下图
_stdcall方式sum函数一旦编写好以后,修正栈的方法就固定了,以后函数的形参个数不能随意变化。如下图所示:
这个函数在调用结束后要把盏指针回调3个单位,调节指针的工作固定在sum子函数的代码内。
_cdecl方式sum函数内不做修正栈的工作,每次调用sum函数当返回时,编译器都重新帮助sum函数再修正一次栈空间,这样就允许了sum函数形参个数变化,反正这时sum函数又不操心入栈出栈的问题,它只关心运算处理,编译器知道这次调用入栈了多少,应该出栈多少,如下图示:
_stdcall方式节约了ROM(计算机专业的人叫代码段),但是却让sum函数的形参个数不可以变化。_cdecl方式浪费了ROM,但是函数的形参个数可以变化。所以我们在VC++里会看到printf这样重要的函数,都是_cdecl方式的,但是动态链接库的函数一般都是_stdcall方式的。前者是实际需要,形参必须可以变化;后者因为大量被使用,必须考虑节约ROM(代码段)。
但是在单片机里大家不必操心这些,KeilC51有自己的入栈出栈方式,参数可变函数能够成功运行。
栈的指针:想象一下假设我们编写好了一个参数可变函数,然后去调用它为我们工作。就像这样function( a , b , c , d , e ),调用前形式参数被压入栈内,在function代码内部可以用栈指针去寻找这些参数,然后去使用。一提到栈的指针,大家马上就想到了sp,但是这样不好。要动用汇编指令,更麻烦的是汇编和C语言的结合,这是我们不想看到的场面。
C语言里有其他办法解决这个问题,那就是利用标准库stdarg.h。这里面的一个数据类型和三个“函数”是我们最关心的:
va_list //注意这是一个数据类型,就如同char
va_start( 形参1 ,形参2 );
va_arg( 形参1 ,形参2 ) ;
va_end( 形参 ) ;
它们的用途马上就解释。
实做unsigned char max( unsigned n , … )函数:
这个函数就像他的名字所描述的一样,求n个数中最大的一个。假设我们编写好了这个函数,我们就可以去调用了:
void main( void )
{
unsigned char M ;
M = max( 5 , 20 , 45 , 55 , 80 , 95 );
while(1); //51单片机停机
}
M自然是返回95,调用这个函数前,5、20、45、55、80、95先被压栈,如下图所示:
要操作这些数据,我们需要一个指向栈空间的指针pStack,我们可以利用下面方法定义这个指针:
va_list pStack;
下面我们想让pStack指向20,如下图:
方法是,调用函数va_start( pStack , n ) 。您也许很诧异倒低n是什么,那么我把全部的代码拷贝过来给您看看吧,它是这样的:
va_start( pStack , n )很古怪,但是这个函数确实就是这么用的,这倒不是需要n的值,而是需要n这个符号。这样pStack马上就指向了n后续的参数。然后您一定想引用这个指针(*pStack)了吧?不行,都不知道pStack指向了什么类型的数据。我们需要利用函数
va_arg( pStack , unsigned
您可能关注的文档
- C14042期权进阶知识(一)100分..docx
- C14042期权进阶知识(一)习题汇总..doc
- C15005答案..doc
- C15034对冲基金投资80分..doc
- C15032对冲基金运营练习+考试..doc
- C15069课后测验100分..doc
- C172标准操纵程序..doc
- C17受限因变量模型和样本选择纠正..docx
- C1小车驾照(场地九选三)考试技巧精华版..doc
- C1教练员操作理论教学法..doc
- 2024临床执业医师高分题库含完整答案详解(全优).docx
- 基本公共卫生服务覆盖率及资源分布不均问题探讨.docx
- 海洋牧场运维母船行业经营分析报告.docx
- 2025年金融风控欺诈交易风险管理与案例分析报告.docx
- 工业大数据平台建设项目在提升企业管理效率与决策水平中的应用研究报告.docx
- 2024临床执业医师高分题库附参考答案详解(综合题).docx
- 2025年跨境电商物流时效解决方案:智能化技术驱动策略解析.docx
- 跨境宠物医疗市场2025年健康大数据分析平台技术创新与市场前景分析.docx
- 2025年绿色建筑XX项目投资可行性及节能减排分析报告.docx
- 工业互联网平台安全标准制定2025年趋势与挑战报告.docx
最近下载
- 用人单位劳动合同模板.doc VIP
- 华熙生物-投资价值分析报告:全球最大透明质酸生产商的产业链延伸.pdf VIP
- 20200522-中信证券-华熙生物-688363-投资价值分析报告:研发驱动,服务美好生活.pdf VIP
- 医药生物行业:华熙生物,全球透明质酸领军企业.docx VIP
- 2025年校园监控系统方案(四篇).pdf VIP
- 2025广西公需科目考试答案(3套涵盖95-试题)一区两地一园一通道建设人工智能时代的机遇与挑战.docx VIP
- 华熙生物-投资价值分析报告-透明质酸,供需双振_20200413.pdf VIP
- 2025年校企合作实训项目设计与实施案例报告.docx
- 华熙生物-投资价值分析报告-全球透明质酸龙头,积极延伸医疗美妆终端.pdf VIP
- 重庆市巴蜀初一入学分班语文试卷版.doc VIP
文档评论(0)