c语⾔语法——c语⾔函数不定参数实现⽅式
c语⾔不定参数
va函数的定义和宏
va函数定义
typedef char* va_list;//x86平台下va_list的定义
type va_arg(va_list argptr, type);
void va_end(va_list argptr);
void va_start(va_list argptr, last_parm);
va_list
定义⼀个指针arg_ptr,⽤于指⽰可选的参数。
va_start(arg_ptr, argN)
使参数列表指针arg_ptr指向函数列表中的第⼀个可选参数,argN是位于第⼀个可选参数之前的固定参数(最后⼀个固定参数)。
va_arg(arg_ptr, type)
返回参数列表中指针arg_ptr所指的参数,返回类型为type。并使指针arg_ptr指向参数列表中下⼀个参数。返回的是可选参数,不包括固定参数。
va_end(arg_ptr)
清空参数列表
va宏
va的宏定义在stdarg.h中,有:va_list,va_start(),va_arg(),va_end()。
#define _INTSIZEOF(n) ((sizeof(n)+sizeof(int)-1)&~(sizeof(int) - 1)) //类型n的⼤⼩,这是考虑了字节对齐
#define va_start(ap,v) ( ap = (va_list)&v + _INTSIZEOF(v) ) //ap指向第⼀个不定参数地址
#define va_arg(ap,t) ( *(t *)((ap += _INTSIZEOF(t)) - _INTSIZEOF(t)) ) //下⼀个参数地址返回当前ap指向的值,并且增加ap
#define va_end(ap) ( ap = (va_list)0 ) // 将指针置为⽆效
读取可变参数的过程其实就是堆栈中,使⽤指针遍历堆栈段中的参数列表,从低地址到⾼地址⼀个⼀个地把参数内容读出来的过程。
1. 所有类型的固定参数都必须出现在参数列表的开始。
2. 在设计具有不定参数列表的函数的时候,我们有两种⽅法来确定到底有多少参数会被传递进来:
在类型固定的参数中指明后⾯有多少个参数以及他们的类型。printf就是采⽤这种⽅法,它的format参数指明后⾯每个参数的类型。
指定⼀个结束参数。这种情况⼀般是不定参数拥有同样的类型,我们可以指定⼀个特定的值来表⽰参数列表结束。
va函数⾃定义printf
通过va函数和系统函数write简单实现了打印整型,浮点型,字符和字符串的功能。
#include <stdio.h>
#include <stdlib.h>
sizeof 指针#include <stdarg.h>
#include <unistd.h>
#include <string.h>
int print(char* format,...){
va_list args;
va_start(args, format);
char* formatChild = format;
char* tmp = formatChild;
//char* buff;
while(1){
if(*formatChild ==0){
break;
}
if(!strstr(formatChild,"%")){
write(2, formatChild,strlen(formatChild));
break;
}
tmp = formatChild;
formatChild =strstr(formatChild,"%");
write(2, tmp, formatChild-tmp);
switch(*(formatChild+1)){
case'd':{
int itmp =va_arg(args,int);
char buff[32];
sprintf(buff,"%d", itmp);
write(2, buff,strlen(buff));
formatChild +=2;
break;
}
case'f':{
float ftmp =(float)va_arg(args,double);
char buff[32];
sprintf(buff,"%f", ftmp);
write(2, buff,strlen(buff));
formatChild = formatChild+2;
break;
}
case'c':{
char ctmp =va_arg(args,int);
write(2,&ctmp,sizeof(char));
formatChild = formatChild+2;
break;
}
case's':{
char* strTmp =va_arg(args,char*);
write(2, strTmp,strlen(strTmp));
formatChild = formatChild+2;
break;
}
}
}
va_end(args);
}
int main(int argc,char* arg[]){
print("%d %f %c %s",1,1.0,'1',"11111111"); }
运⾏结果:
1 1.000000 1 11111111
版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系QQ:729038198,我们将在24小时内删除。
发表评论