C语言可变参数编程之Avg、Myprinf…

可变参数函数(Variadic functions)是stdarg.h内容典型的应用。stdarg.h是C语言中C标准函数库的头文件,stdarg是由standard(标准) arguments(参数)简化而来,主要目的为让函数能够接收可变参数。
  可变参数函数的参数数量是可变动的,它使用省略号来忽略之后的参数。 可变参数函数最少要有一个命名的参数,所以 char *wrong(...) 在c中是不被允许的。 (但在C++中,这样的声明是合理的),
 我们要 访问未命名的可变参数,首先必须在可变参数函数中声明va_list类型的变量。调用 va_start 并传入两个参数:第一个参数为va_list类型的变量,第二个为省略号前最后一个有名字的参数的名称,接着每一调用va_arg就会返回下一个参数,va_arg的第一个参数为va_list,第二个参数为返回的类型。最后va_end必须在函数返回前被va_list调用(va_list当作参数)(没有要求要读取完所有参数)。
 以下是两个示例函数,帮助我们理解它。
C++ Code 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
#include
#include

int  Avg( long   long  n...)  //求平均值
{
    //n的作用:1、记录省略号的开头  2、确定省略号中数据的个数。
    
int  sum =  0 ;
    va_list list; 
  //char *list
    va_start(list, n); 
  //通过n找到省略号的开头

    
for ( int  i =  0 ; i < n; i++)
    {
        sum += va_arg(list, 
int );   //从省略号中取数据
    }

    va_end(list); 
  //结束读取
    list = NULL;
    
return  sum / n;
}

int  main()
{
    
//printf("%d\n",Avg(3,10,20,30));
     //printf("%d\n",Avg(5,10,20,30,40,50));
    printf( "%d\n" , Avg( 7 10 20 30 40 50 60 70 ));
}
 C++ Code 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
#include
#include

void   Print( int  a)  //-123
{
    
int  flag = (a >  0 ) ?  0  :  1 ;
    
char  s[ 10 ];
    
if (flag !=  0 )
    {
        putchar(
'-' );
        a = -a;
    }
    
int  j =  0 ;
    
do
    {
        s[j++] = a % 
10  +  '0' ;
        a /= 
10 ;
    }
    
while (a !=  0 );
    s[j] = 
'\0' ;
    --j;
    
while (j >=  0 )
        putchar(s[j--]);
}

void  Myprintf( const   char  *str, ...)    //printf打印函数
{
    va_list list; 
// char * list 
    va_start(list, str); 
// 通过str定位到...开头 
     int  num;
    
int  c;
    
char  ch;
    
char  *s =  NULL ;
    
float  b;

    
while (*str !=  '\0' )
    {
        
if (*str ==  '%' )
        {
            
switch (*(str +  1 ))
            {
            
case   'd' :
                num = va_arg(list, 
int );   // 从省略号里取数据
                Print(num);
                str++;
                
break ;
            
case   'c' :
                ch = va_arg(list, 
char );
                putchar(ch);
                str++;
                
break ;
            
case   'f' :     //123.45
            {
                b = va_arg(list, 
double );
                c = (
int ) b;
                Print(c);
                putchar(
'.' );
                
int  d = (b - c) *  1000000 ;
                Printt(d);
                str++;
                
break ;
            }
            
case   's' :
                s = va_arg(list, 
char  *);
                
while (*s !=  '\0' )
                {
                    putchar(*s++);
                }
                str++;
                
break ;
            
default :
                
//printf();
                putchar(*str);
                
break ;
            }
        }
        
else
        {
            putchar(*str);
        }
        str++;
    }
    va_end(list); 
  //结束读取
   list = NULL;
}

int  main()
{
     
Myprintf ( "abcd3=%c\n" 'x' );
    
//Myprintf("abcd�\n",1234);
     //Myprintf("abcd%s1234\n","yuebai");
     //Myprintf("%f\n",1.234567);
     //Myprintf("%d,%d\n",-10,20);

    
return   0 ;
}
          

猜你喜欢

转载自blog.csdn.net/qq_19525389/article/details/79378789