C语言可变参数列表应用——多字符串复制和链接
来源:互联网 发布:网络与新媒体概论 pdf 编辑:程序博客网 时间:2024/05/01 02:49
C语言可变参数列表应用——多字符串复制和链接
C标准库中<stdarg.h>头文件中包含可变参数列表的实现,完成遍历未知数目和类型的函数参数列表的功能。提供以下3个宏以及va_list变量:
va_start(va_list ap, lastarg):在提取可变参数前必须调用这个宏实现初始化。
va_arg(va_list ap, type_of_var):用于提取变量,type_of_var是提取的变量的类型。返回对应类型的参数。
va_end(va_list ap):在参数处理完毕之后,必须调用va_end做一些清理。
通过这3个宏就可以实现可变参数的遍历,下面看一下多字符的复制和链接的实现,这两个函数都是通过NULL作为可变参数列表的终结。
- void nstrcat(char *dest, ...){
- va_list ap;
- char *p, *q;
- va_start(ap, dest);
- while( (p = va_arg(ap, char *)) != NULL ){
- strcat(dest, p);
- dest += strlen(p);
- }
- va_end(ap);
- }
- void nstrcpy(char *dest, ...){
- va_list ap;
- char *p;
- va_start(ap, dest);
- while( (p = va_arg(ap, char *)) != NULL){
- strcpy(dest, p);
- dest += strlen(p);
- }
- va_end(ap);
- }
- int
- main(int argc, char** argv){
- char buf[1000], bufa[100];
- char a[] = "abc,123";
- char b[] = "456";
- char c[] = "090";
- nstrcpy(buf, a, b, c, NULL);
- strcpy(bufa, "nbakk__");
- nstrcat(bufa, b, "__", a, "__", c, NULL);
- printf("nstrcpy: %s\n", buf);
- printf("nstrcat: %s\n", bufa);
- }
- nstrcpy: abc,123456090
- nstrcat: nbakk__456__abc,123__090
|--------------|
| 23 | 最后一个可变参数
|--------------| 0x10000008
| 12 | 第一个可变参数
|--------------| 0x10000004
| 1 | 最后一个固定参数
%ebp--> |--------------| 0x10000000
| |
|--------------|
............
|--------------|
| |
%esp--> |---------------|
CPU的%ebp是帧指针,%esp是栈指针,在%ebp和%esp之间的内存就是当前函数的栈帧,传给当前函数的实参是在调用函数的栈帧中,顺序放置在%ebp后面。比如上图就是调用avg(1, 12, 23)的栈对应的状态。根据栈的状态,a对应的是1,a的起始地址是0x10000000,va_list变量实际就是char *,当调用va_list(ap, a)后,ap对应的就是0x10000004。当调用int n = va_arg(ap, int),相当于执行(*(int *)ap)也就是12,然后将ap += sizeof(int),这时ap指向0x10000008,也就是根据传入va_arg的类型type,跳过sizeof(type)个字节,这样去遍历可变参数。这是我对于可变参数的实现的理解和猜测,不一定对啊。。。
- C语言可变参数列表应用——多字符串复制和链接
- C语言可变参数列表应用——多字符串复制和链接
- C语言学习笔记——可变参数列表
- c语言:可变参数列表
- 【C语言】可变参数列表。
- C语言,可变参数列表
- C语言可变参数列表
- C语言-可变参数列表
- C语言可变参数列表
- 【C语言】可变参数列表
- c语言可变参数列表
- c语言 之 可变参数列表的应用
- C语言可变参数列表解析及简单应用
- C学习—可变参数列表
- C语言 #、##运算符和可变参数
- c语言的可变参数列表
- c语言函数可变参数列表
- 深度理解C语言可变参数列表
- oracle 11g 学习笔记2012_10_23(2)
- android 通讯录中贾(jia|gu)处理
- 信号量和自旋锁区别
- [Happy BASH] BASH 编程学习点点滴滴
- Adobe Flash CS4 序列号-Adobe Dreamweaver CS4 序列号
- C语言可变参数列表应用——多字符串复制和链接
- HTTP协议详解
- hdu4430
- ARC之对象转型 __bridge
- Oracle存储过程分页查询
- SSH协议
- QT 多线程服务器及数据库使用
- 前++后++引发的思考
- 建模的技巧及优化