news 2026/10/2 2:10:16

函数调用和变长参数

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
函数调用和变长参数

函数调用

  1. 函数参数传入寄存器(保护现场过程省略)或压栈
  2. 调用函数代码

函数中按预设的入栈顺序使用参数

调用惯例

基于函数调用过程中参数传递原理,函数调用方与被调用方对于传递和使用参数需要有一致的理解。因此需要调用惯例。

调用惯例:

  • 函数参数的传递顺序和方式
  • 栈的维护方式:函数调用时将所有函数参数压栈,在调用完成后需将所有参数出栈。出栈的工作可由函数的调用方完成,也可由函数本身(被调用方)完成。
  • 名字修饰的策略:在原函数名基础上按设定规则加上修饰,汇编代码中可查看

C语言默认调用惯例cdecl

// 选择调用惯例// 定义__attribute__((cdecl))voidfoo(inta,intb){printf("a=%d, b=%d\n",a,b);}// 声明__attribute__((cdecl))voidfoo(int,int);

x86-64 有统一的调用约定(System V AMD64 ABI), 不能自定义

变长参数函数

变长参数的标准库头文件:stdarg.h

实现不定参数的步骤:

  1. 定义函数:函数的最后一个参数使用省略号(…),省略号前可以有固定参数。
  2. 函数内创建va_list变量:这是一个在stdarg.h中定义的类型,用于访问参数列表。
  3. 初始化参数列表:使用va_start宏和最后一个固定参数来初始化va_list变量。
  4. 访问参数:使用va_arg宏和va_list变量来访问每个参数。
  5. 结束参数列表访问:使用va_end宏清理va_list变量。
#include<stdarg.h>#include<stdio.h>// 变长参数函数示例intfunc_name(intarg1,...){va_list ap;va_start(ap,arg1);intarg2=va_arg(ap,int);doublearg3=va_arg(ap,double);char*arg4=va_arg(ap,char*);printf("%d %lf %s\n",arg2,arg3,arg4);va_end(ap);returnarg1;}intmain(){func_name(3,1,1.5,"abc");return0;}

arg1是函数的第一个参数,省略号(…)表示后续的参数数量是可变的。
要使用这种机制,需要包含stdarg.h头文件,它提供了处理可变参数的宏和函数。

可见可变参数的函数的参数分为两种类型,固定参数(只表意)和不定参数,固定参数在前不定参数在后。

变长参数宏

##为宏字符串连接

// 1.gcc编译下的定义#definemprintf(arg...)fprintf(stdout,##arg)// 2.MSVC下的定义#definemprintf(...)fprintf(stdout,__VA_ARGS__)// 使用mprintf("%d %lf %s\n",1,1.5,"abc");
版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/10/2 2:04:51

h3.c开发者指南:用公开C API构建你自己的本地文生视频应用

h3.c开发者指南&#xff1a;用公开C API构建你自己的本地文生视频应用 【免费下载链接】h3.c MiniMax H3 inference engine for Mac computers 项目地址: https://gitcode.com/gh_mirrors/h3/h3.c h3.c&#xff08;又名 h3-metal&#xff09;是一个运行在 Apple Silicon…

作者头像 李华
网站建设 2026/10/2 2:01:37

AI Agent支付背后的七套协议:从TLS到MCP全解析

AI Agent支付&#xff0c;从2024年底开始就成了支付圈最热的关键词。但真正立案子去接支付协议时我才发现&#xff1a;所谓AI支付&#xff0c;根本没有一套现成的"AI支付协议"&#xff0c;它是在过去四十年的支付技术地基上&#xff0c;一层一层堆出来的。翻了一遍家…

作者头像 李华