"ild"模式用于表示后续有三个参数,按顺序分别为int, long, double类型的三个参数那么这样我们可以定义自己版本的printf 如下
01.void printf(char *fmt, ...)
02.{
03.char s[80] = "";
04.int paramCount = strlen(fmt);
05.write(stdout, "paramCount = " , strlen(paramCount = ));
06.itoa(paramCount,s,10);
07.write(stdout, s, strlen(s));
08.char *p = (char *)(&fmt) + sizeof(char *);
09.int *pi = (int *)p;
11.{
12.char line[80] = "";
13.strcpy(line, "param");
14.itoa(i+1, s, 10);
15.strcat(line, s);
16.strcat(line, "=");
17.switch(fmt[i])
18.{
19.case 'i':
20.case 's':
21.itoa((*pi),s,10);
22.strcat(line, s);
23.pi++;
24.break;
25.case 'c':
26.{
27.int len = strlen(line);
28.line[len] = (char)(*pi);
29.line[len+1] = '\0';
30.}
31.break;
32.case 'l':
33.ltoa((*(long *)pi),s,10);
34.strcat(line, s);
35.pi++;
36.break;
37.default:
38.break;
39.}
40.}
41.}
也可以这样定义我们的Max函数,它返回多个输入整型参数的最大值
01.int Max(int n, ...)
02.{
03.int *p = &n + 1;
04.int ret = *p;
05.for (int i=0; i
06.{
07.if (ret < *(p + i))
08.ret = *(p + i);
09.}
10.return ret;
11.}
可以这样调用, 后续参数的个数由第一个参数指定
1.int m = Max(3, 45, 12, 56);
2.int m = Max(1, 3);
3.int m = Max(2, 23, 45);
4.
5.int first = 34, second = 45, third=5;
6.int m = Max(5, first, second, third, 100, 4);
结论
对于可变参数函数的调用有一点需要注意,实际的可变参数的个数必须比前面模式指定的个数要多,或者不小于, 也即后续参数多一点不要紧,但不能少, 如果少了则会访问到函数参数以外的堆栈区域,这可能会把程序搞崩掉。前面模式的类型和后面实际参数的类型不匹配也有可能造成把程序搞崩溃,只要模式指定的数据长度大于后续参数长度,则这种情况就会发生。如:
1.printf("%.3f, %.3f, %.6e", 1, 2, 3, 4);
参数1,2,3,4的默认类型为整型,而模式指定的需要为double型,其数据长度比int大,这种情况就有可能访问函数参数堆栈以外的区域,从而造成危险。但是printf("%d, %d, %d", 1.0, 20., 3.0);这种情况虽然结果可能不正确,但是确不会造成灾难性后果。因为实际指定的参数长度比要求的参数长度长,堆栈不会越界。
阅读(480) | 评论(0) | 转发(0) |