文章详情

  • 游戏榜单
  • 软件榜单
关闭导航
热搜榜
热门下载
热门标签
php爱好者> php文档>变长参数列表

变长参数列表

时间:2010-04-06  来源:light511

这里有一个陷阱需要避免:
va_arg宏的第2个参数不能被指定为char、short或者float类型。
因为char和short类型的参数会被转换为int类型,而float类型的参数会被转换为double类型 ……
例如,这样写肯定是不对的:
c = va_arg(ap,char);
因为我们无法传递一个char类型参数,如果传递了,它将会被自动转化为int类型。上面的式子应该写成:
c = va_arg(ap,int);
                ——《C陷阱与缺陷》p164
在C语言中,调用一个不带原型声明的函数时:
调用者会对每个参数执行“默认实际参数提升(default argument promotions)”。

同时,对可变长参数列表超出最后一个有类型声明的形式参数之后的每一个实际参数,也将执行上述提升工作。
提升工作如下:
——float类型的实际参数将提升到double
——char、short和相应的signed、unsigned类型的实际参数提升到int
——如果int不能存储原值,则提升到unsigned int

然后,调用者将提升后的参数传递给被调用者。

下面是我自己写的代码示例,主要是模仿printf函数生成日志文件: #include<stdio.h>
#include<stdlib.h>
#include<stdarg.h> int writelog(char * first,...)
{
 //该日志函数的参数只处理5种常用的数据类型:int (%d) , unsigned int (%u), char(%c), char * (%s), float (%f)
 int i=0,flag=0;
 int const SIZE=1024;
 char tmp1[1024]={'\0'};
 char tmp2[1024]={'\0'};
 char *pf=first;
 char *ps=first;
 char * tt ;
 va_list marker;
 FILE *cfptr;
 va_start( marker, first );
 printf("first=%s\n",first);
 strcpy(tmp2,"LOG...   ");
 while((ps-first)<strlen(first))
 {
  pf=ps;
  if((ps=strstr(pf,"%"))!=NULL)
  {
   ps++;
   switch( *ps )
   {
   case 'd':
    {
     flag=1;
     memset(tmp1,'\0',SIZE);
     memcpy(tmp1,pf,ps-pf-1);
     strcat(tmp2,tmp1);
     ps++;
     memset(tmp1,'\0',SIZE);
     sprintf(tmp1,"%d",va_arg( marker, int));
     strcat(tmp2,tmp1);
     break;
    }
   case 'u':
    {
     flag=1;
     memset(tmp1,'\0',SIZE);
     memcpy(tmp1,pf,ps-pf-1);
     strcat(tmp2,tmp1);
     ps++;
     memset(tmp1,'\0',SIZE);
     sprintf(tmp1,"%u",va_arg( marker,unsigned int));
     strcat(tmp2,tmp1);
     break;
    }
   case 'c':
    {
     flag=1;
     memset(tmp1,'\0',SIZE);
     memcpy(tmp1,pf,ps-pf-1);
     strcat(tmp2,tmp1);
     ps++;
     memset(tmp1,'\0',SIZE);
     sprintf(tmp1,"%c",va_arg( marker, int));
     strcat(tmp2,tmp1);
     break;
    }
   case 's':
    {
     flag=1;
     memset(tmp1,'\0',SIZE);
     memcpy(tmp1,pf,ps-pf-1);
     strcat(tmp2,tmp1);
     ps++;
     memset(tmp1,'\0',SIZE);
     tt =va_arg( marker, char*);
     strcpy(tmp1,tt);
     strcat(tmp2,tmp1);
     break;
    }
   case 'f':
    {
     flag=1;
     memset(tmp1,'\0',SIZE);
     memcpy(tmp1,pf,ps-pf-1);
     strcat(tmp2,tmp1);
     ps++;
     memset(tmp1,'\0',SIZE);
     sprintf(tmp1,"%lf",va_arg( marker, double));
     strcat(tmp2,tmp1);
     break;
    }
   default:
    {
     memset(tmp1,'\0',SIZE);      strcat(tmp1,pf);      strcat(tmp2,tmp1);
     break;
    }
   }
  }
  else
  {     break;   }
 }
 if(!flag)
 {
  strcat(tmp2,first);
 }
 strcat(tmp2,"\n");
 printf("%s\n",tmp2);
 if((cfptr=fopen("D:\\handlerlog.txt","a+"))!=NULL)
 {
  fputs(tmp2,cfptr);
  fclose(cfptr);
 }
 else
 {
  printf("file cann't be opened!");
 }
 va_end( marker );
 return 0;
}
int main(int argc,char ** argv)
{
 char path[10]="good";
 int x=180;
 unsigned int y=360;
 float z=3.14;
 writelog("第%u个的名字是: %s\n",y,path);
 writelog("%c\n",'k');
 return 0; }
相关阅读 更多 +
排行榜 更多 +
辰域智控app

辰域智控app

系统工具 下载
网医联盟app

网医联盟app

运动健身 下载
汇丰汇选App

汇丰汇选App

金融理财 下载