在没有标题的C语言函数中使用“ ...”参数

时间:2018-12-29 16:26:54

标签: c linux assembly x86-64

我正在使用自己的函数创建自己的C库,并帮助更好地理解C,而不仅仅是一切都依赖于GNU C库。

到目前为止,我已经运行了一些函数,但是我不会稍微调整我的printo函数来支持无限的参数(仅限于char,但是您的答案也可能支持传递整数参数)。这是printo代码:

#include "../GV.h"
#include "OtherUtils.h"

int print(char *WRITEOUT1){
  char *WRITEOUT=&WRITEOUT1[0];
  int AMOUNT=GetCharSize(WRITEOUT1);

  register int SYSCALLNO asm("rax")=SYSWRITE;
  register int FD asm("rdi")=STANDARDFD;
  register char *BUF asm("rsi")=WRITEOUT;
  register int BYTES asm("rdx")=AMOUNT;
  asm("syscall");

  return 0;
}

GetCharSize函数代码(如果有人需要的话):

#include "../GV.h" 

int GetCharSize(char *arg){
  for(i=0;arg[i]!='\0';i++){
  }
  return i;
}

GV.h具有定义为int i;

的变量

在我问这个问题之前,我研究了__VA_ARGS__之类的C预处理器,但是有点无法解决。

1 个答案:

答案 0 :(得分:3)

...表示法是C语言语法的一部分。它用于将函数的参数列表定义为最后一个参数,并且表示“后跟零个或多个任何类型的参数”。例如

int printf (char *format, ...);

以这种方式定义的函数现在可以使用所有必需参数以及任意数量的其他参数(例如printf)来调用。

以这种方式定义的函数必须具有一种知道多少个参数以及每个参数的类型的方法。 printf通过 format规范字符串printf唯一需要的参数)知道这一点。

假设一个使用堆栈传递参数的Intel系统,并且参数从右向左推入(最后一个参数推在前),因此 first 可选参数将直接为在堆栈上的格式规范字符串之后,printf现在进行如下操作:取格式规范字符串的地址,并以char *的大小递增该地址。这是可选参数的开始。现在看一下格式说明符字符串,以了解下一个参数的类型。从堆栈中获取该类型的参数,将其增加该参数的大小以获取下一个地址。这样做直到没有更多的格式说明符。