1. 程式人生 > >Linux下函式可變引數va_arg_##__VA_ARGS__巨集

Linux下函式可變引數va_arg_##__VA_ARGS__巨集

va_list

//compile:gcc va_arg.c
//run:./a.out
//Notes:如果遇到獲取char,type用int,如果該用char會提示...傳遞時被提升為int。此處使用的編譯器是Linux下的gcc
#include<stdio.h>
#include<stdarg.h>
#define filename "filemark"
//***************************************
#define DEBUG_Xu__Jiayu(format,...)  DEBUG_(format,##__VA_ARGS__)//有可變引數個數的函式名替換
void DEBUG_(const char*format,...)
{ 

   va_list thethis;
   va_start(thethis,format); //可變引數獲取可變部分頭地址  
   
   FILE*fp=fopen(filename,"a+");//開啟檔案,不存在新建
   if(NULL==fp)return ;
   vfprintf(fp,format,thethis);//寫檔案,這個可以處理va_list
   fclose(fp);//關閉檔案
   
   va_end(thethis);
}
//**************************************
typedef char byte;
void write_byte(const int cnt,...)
{
  va_list args;//char*args;
  va_start(args,cnt);//(args=(va_list)(&cnt)+_INTSIZEOF(cnt)); 
  int i=0;
  for(;i<cnt;i++)
  {
     //註釋的提升到int
     byte t=va_arg(args,int);//char:int
 
     printf("%c\n",t);
  }

  va_end(args);//(args=(va_list)0);
}
//*************************************
void write_str(const int cnt,...)
{
  va_list args;//char*args;
  va_start(args,cnt);//(args=(va_list)(&cnt)+_INTSIZEOF(cnt));
  int i=0;
  for(;i<cnt;i++)
  {

    char* c=va_arg(args,char*);//char*:char*

     printf("%d=%s\n",i,c);

  }

  va_end(args);//(args=(va_list)0);
}
//***********************************
void write_dif(const char c,...)
{
  va_list args;//char*args;
  va_start(args,c);//(args=(va_list)(&cnt)+_INTSIZEOF(cnt));
  int i=0;
  int cnt=va_arg(args,int);  
  if(c=='c')
  for(i=0;i<cnt;i++)
  {
    char cc=va_arg(args,int);//char:int函式傳遞後char提升為int
     printf("%d=%c\n",i,cc);
  }
  else if(c=='s')
  for(i=0;i<cnt;i++)
  {

    char* s=va_arg(args,char*);//char*:char*

     printf("%d=%s\n",i,s);

  }
  else if(c=='d')
  for(i=0;i<cnt;i++)
  {

    int dt=va_arg(args,int);//int:int

     printf("%d=%d\n",i,dt);

  }
   else printf("wrong parameter\n");


   

  va_end(args);//(args=(va_list)0);
}
//***********************************
int main(int argc,char*argv[])
{
   printf("...##__VA_ARGS__巨集*********\n");
   DEBUG_("one parameter loading...\n");
   DEBUG_("%d  parameter loading...\n",2);
   DEBUG_("%d  patameter %s...\n",3,"loading");
   printf("save in file :filemark\n%s",
           "you could check it from using shell \"cat filemark\"in Linux system\n");

   //檢視shell命令
   //cat filemark
   printf("\nNotes:如果遇到獲取char,type用int,如果該用char會提示...傳遞時被提升為int。此處使用的編譯器是Linux下的gcc\n");
   //*******************************************
   printf("...va_list:char************\n");
   write_byte(0);
   write_byte(4,'m','a','r','k');
  //*********************************************
   printf("...va_list:string**********\n");
   write_str(0);
   write_str(2,"mystr","strend");
  //*********************************************
   printf("...va_list:char,string,int*\n");
   printf("char***********************\n");
   write_dif('c',2,'o','k');
   printf("string*********************\n");
   write_dif('s',3,"this","is","string");
   printf("int************************\n");
   write_dif('d',4,1,2,5,8);
   printf("wrong mark*****************\n");
   write_dif('w',2,'w',"string");
return 0;
}


螢幕結果

...##__VA_ARGS__巨集*********
save in file :filemark
you could check it from using shell "cat filemark"in Linux system

Notes:如果遇到獲取char,type用int,如果該用char會提示...傳遞時被提升為int。此處使用的編譯器是Linux下的gcc
...va_list:char************
m
a
r
k
...va_list:string**********
0=mystr
1=strend
...va_list:char,string,int*
char***********************
0=o
1=k
string*********************
0=this
1=is
2=string
int************************
0=1
1=2
2=5
3=8
wrong mark*****************
wrong parameter

執行一次檔案結果【shell:cat filemark】:

one parameter loading...
2  parameter loading...
3  patameter loading...