深入了解可变参数列表

                                     献上一段代码! 编写的简单模拟简单printf函数

1. 实现了字符串‘s’,和字符‘c’的处理,大家可以自行进行功能的完善!

//使用可变参数列表模拟printf();函数  
79.  
80.#include<stdio.h>  
81.#include<stdarg.h>  
82.  
83.void print(charchar *str, ...)  
84.{  
85.    const charchar *p = NULL;  
86.    char ch;  
87.    char c;  
88.    va_list arg;//定义一个char 类型的指针  
89.  
90.    va_start(arg,str);  //将指针指向第一个参数!
91.  
92.    while(*str)  
93.    {  
94.        switch(*str)  //switch语句可以更好地处理各种字符串,字符!
95.        {  
96.        case 's':  
97.            p = va_arg(arg,const charchar *);  //每次执行一次va_arg语句,自动指向下一个参数!
98.            while(*p)  
99.            {  
100.                putchar(*p);  
101.                p++;  
102.            }  
103.            ++str;  
104.            break;  
105.        case 'c':  
106.            ch = va_arg(arg,char);  
107.            putchar(ch);  
108.            ++str;  
109.            break;  
110.        case ' ':  //其实这里是多余的废话 ,但是为了更好的理解switch, 其实可以优化!
111.            ++str;  
112.            break;  
113.        case '\n':  
114.            putchar('\n');  
115.                        ++str;  
116.            break;  
117.        default:  
118.            break;  
119.  
120.  
121.        }  
122.    }  
123.    va_end(arg);  //最后结束掉参数指针, 这里是将指针arg赋值为NULL;
124.}  
125.  
126.int main()  
127.{  
128.  
129.    print("s ccc \n","hello",'b','i','t');  
130.    //printf("%s","strstr");  
131.  
132.    return 0;  
133.}  

 2.详细了解可变参数列表的内部!
    stdarg宏
可变参数列表是通过宏来实现的,这些宏定义stdarg.h头文件,它是标准库的一部分。这个头文件声明了一个类型va_list和
三个宏——va_start、va_arg、va_end。我们可以声明一个类型为va_list的变量,与这几个宏配合使用,访问参数的值。
 
 int printf(const char *fmt, ...);

    这个...表示的是什么,在c语言里面,这个叫做可变参数的声明,...就是说它有不确定个参数,专业术语叫可变参数。我们去看看它的源代码:

    int printf(const char *fmt, ...)

    {

        int res;

        va_list arg;

        va_start(arg, fmt);

        res = vprintf(fmt, arg);

        va_end(arg);

        return res;

    }

    原来它只是简单的调用vprintf,为了弄清什么是可变参数列表,是不是有必要去深究vprintf的代码呢,完全没有必要。下面我们来写一个求最小值的函数min,不过我们要做的当然与简单的#define min(a, b) (a < b? a: b)又所不同,我们来实现一个求任意个数的最小值的函数:

    int min(int n, int m, ...)

    {

        int tmp;

        int res = m;

        va_list arg;

        va_start(arg, m);

        while (--n > 1)

        {

             tmp = va_arg(arg,int);

             if (tmp < res)

                 res = tmp;

        }

        va_end(arg);

        return res;

    }
3.可变参数的限制
和java中相比,C中的可变参数要弱不少,主要有两个缺点:</span>
     1、无法确定可变参数列表的长度。这就是为什么printf要提供通配符,在cocos2d中要用NULL结尾
     2、不能提供类型检查。由于不能判定入参的类型,所以在从实参到形参的复制过程中可能会有问题,所以一般都建议只传递基本类型,或者是类类型的指针。但是这一点意外的也有一些用处,比如上面说到的printf
<span style="font-size:18px;">4.警告</span>
<span style="font-size:18px;"><img alt="" src="http://pic002.cnblogs.com/images/2011/352816/2011120416573922.jpg" />ps</span>
<span style="font-size:18px;">
</span>

你可能感兴趣的:(C语言,可变参数列表)