C语言中不定参数的实现

到百度贴吧首页
新闻   网页   贴吧   知道   MP3   图片   视频   百科
    吧内搜索 | 帮助
  • 共有30篇贴子

C语言中不定参数的实现

1楼

     相信大家都用过 printf 这个函数,这就是利用不定参数,来达到
  参数项目不固定的目的。

     但是请注意,由於 K&R C 中并不检查参数型态,so 在此是用 ANSI
  C 来说明,毕竟 ANSI C 是目前所有 C Compiler 都支援的标准;常在
  网路上看到有人推荐 K&R The C Programming Language 这本书,老
  实说这本是不错(我以前也是看这本),但因为 K&R C 慢慢因为 ANSI
  C 的完整标准出现,而面临考验,所以我建议若是初学者先从 ANSI C
  看起,等对 ANSI C 的标准了解後,再回头看这本(其实不看也没差,虽  然它号称 C %D

2楼

但是请注意,由於 K&R C 中并不检查参数型态,so 在此是用 ANSI
 C 来说明,毕竟 ANSI C 是目前所有 C Compiler 都支援的标准;常在
 网路上看到有人推荐 K&R The C Programming Language 这本书,老
 实说这本是不错(我以前也是看这本),但因为 K&R C 慢慢因为 ANSI
 C 的完整标准出现,而面临考验,所以我建议若是初学者先从 ANSI C
 看起,等对 ANSI C 的标准了解後,再回头看这本(其实不看也没差,虽
 然它号称 C 语言圣经,但时代在变,有些东东开始不适用。不过还是有
 看的价值)

 //
 // 固定的参数一定要放前面!!

 

 int FUNC(int xx,...)
 {
 int tmp;
 va_list arg_ptr; // 用va_list声明指向引数列表的 Pointer

 va_start(arg_ptr,xx); // 从引数表中取得第一个引数
 // 第一个引数就是 xx 自己(xx是最后一个固定变量)

 tmp=va_arg(arg_ptr,int); // 从引数表中取得int 型态引数
 // 一直呼叫 va_arg 即可取得所
 // 有引数(第二个参数int是当前不定变量的类型 )

 va_end(arg_ptr); // 取完後将 arg_ptr = NULL
 // 以便归还 stack 空间(要在所有的不定变量引用完之后再用va_end(),否则会有无法预测的结果。)

 }

 理论上不定参数是可以无限多的,但碍於 memory 及 stack 大小
 所以项数通常有上限,如 Turbo C 最多 200 个,一超过就出现如下
 " Fatal stack overflow error-System halted ",然後当掉,你连
 暖开机都不行;所以当你使用一套 Compiler 时一定要有其参考手册
 或资料,以免搞半天除错後,还找不出原因!!
 (P.S. 像 Turbo C 2.0 只能用 4000 个 if ,....太多要注意的!!)

 说了一堆,不知道你会用了没?! 最後用一个画多边型的函数做□
 例,顺便做结束。

 /* EX */
 #include <stdarg.h> // 记得要 include 才能用
 #define END_P -400 // 用来判断是否为最後一个参数

 void DrawPoly(int color,...)
 {
 va_list arg_ptr;
 int x[200],y[200]; // 最多 200 个点
 int p_c=0; // 计算有几点
 int i; // 计数器

 va_list(arg_ptr,color);

 while(((x[p_c]=va_arg(arg_ptr,int))>END_P) \
 &&((y[p_c]=va_arg(arg_ptr,int))>END_P)\
 && p_c<=200) // 不是最後一点且小於 200 个点

 p_c++;

 if(p_c<3) return ; // 不到 3 点不成一多边型,So 跳出

 for(i=0;i<p_c-1;i++)
 // 划线,每个 Compiler 不同,自行修改
 line(x[i],y[i],x[i+1],y[i+1],color);
 // 最後一条线
 line(x[0],y[0],x[p_c-1],y[p_c-1],color);

 va_end(arg_ptr);
 }

219.146.212.*

3楼

为什么没人回帖……
不明白?!

222.168.108.*

4楼

说的太深了。看来还给在学学。本以为学完了呢。
218.78.226.*

5楼

深入分析头函数:
最近在编写不定参数函数的时候发现:
在turbo c中编译可以通过但是在c-free中却不能编译,究其因,才知:
在turbo c中的stdarg.h中是这样的:
typedef void *va_list;

#define va_start(ap, parmN) (ap = ...)/*在这里...是一个参数栈地址*/
#define va_arg(ap, type) (*((type *)(ap))++)
#define va_end(ap)
#define _va_ptr (...)
/*以上的东西应该不用再解释了.所以我写的程序:
void *arg_ptr=...;/*tc中编译通过,但是cfree中不然,何故?*/
原来在cfree中的stdarg.h中却是这样的:
typedef char* va_list;
#define __va_argsiz(t) \
(((sizeof(t) + sizeof(int) - 1) / sizeof(int)) * sizeof(int))/*计算t类型的参数所占的栈的长度*/
#ifdef __GNUC__
#define va_start(ap, pN) \
((ap) = ((va_list) __builtin_next_arg(pN)))/*这个宏先不说,但是意思应该不难理解的*/
#else
#define va_start(ap, pN) \
((ap) = ((va_list) (&pN) + __va_argsiz(pN)))/*从栈的最后一个确定参数位置往下的第一个便是不定参数的开始地址了!*/
#endif
/*相应的程序变成了:*/
char* axsprintf(const char* format,...)
{
 /*void * params=...;*/
 char *params=(char*)(&format)+sizeof(format);
 char result[255];

61.187.56.*

6楼

GCC中没有stdarg.h啊
222.185.89.*

7楼

标准库怎么会没有
220.168.160.*

8楼

看c和指针这本书 上面有

9楼

新手上路!新手上路! 
希望喜欢程序设计的朋友加我 大家共同进步、技术交流! 
QQ:8614631

10楼

顶精帖很好玩么?

11楼

完全不明白 
我还要继续学啊

12楼

形参用什么代表啊??
省略号??

61.150.127.*

14楼

怎么弄的呀!不是很懂呀。

16楼

以前一位就VC++中有这功能,不知道C语言中还有这功能,这是受益匪浅阿。
202.127.110.*

17楼

va_list(arg_ptr,color);
----这行是否应该改为:va_start(arg_ptr,color)
我也是初学者,如有不对,请多包涵。

124.243.223.*

18楼

float的类型的可以用此方法取出吗?我试了,好像取出来的不对啊,请教一下float类型的具体应该怎么取啊

19楼

既然看了,顶一个吧,好帖子

21楼

dddddddddddddddd

22楼

这个工具,是windowsAPI程序设计中的利剑,顶
58.247.173.*

23楼

高手,教教吧,float类型的应该怎么取啊 ?

24楼

dddddddd
222.243.167.*

25楼

妈妈为什么我都不懂啊?
555~
我只知道一点点啊```
啊啊啊!~

210.22.22.*

26楼

K&R C建议新手不要看,它虽然是C语言的鼻祖级资料,但是后来C的标准化过程对许多语法细节做了修改,而这些修改的地方正是K&R C 最容易出现错误或者说引起BUG的地方,还包括了许多不良的编程习惯。比如说printf,由于支持不定参数用起来虽然方便,但用法不当也会使得系统出现一些很难以察觉的BUG。
211.137.59.*

27楼

你真的很留,可不可以给个电子版的The C program 
211.137.59.*

28楼

你真牛 我QQ490384318
218.25.117.*

29楼

aaa
210.72.128.*

30楼

编程多了就知道了,流处理函数fprintf,fscanf,sscanf,snprintf等都属于自变量不固定个数类型的,这种自变量也叫可选自变量。 在stdarg.h头文件中定义了一个类型(va_list)和四个宏(va_start,va_copy,va_end,va_arg)来访问可选性自变量。
建义大家多看一下这些常用函数的原型,可以更多的了解

121.15.77.*

31楼

fasd
58.47.40.*

32楼

我无语 搞点新手看的撒
61.138.125.*

33楼

看不懂 乱

发表回复

内 容:
用户名:
  
©2010 Baidu 贴吧协议  意见反馈