|
Posted on 2006-03-20 16:58 高山流水 阅读(150) 评论(0) 编辑 收藏 引用 所属分类: 程序语言
书上说,当无法列出传递函数的所有实参的类型和数目时,可用省略号指定参数表 (...) 如:void foo(...); void foo(parm_list,...); void foo(...) { //... } 调用:foo(a,b,c); 就是不懂,把a,b,c的值传进函数里面后,用什么变量来接收???如果不能接收,(...)岂不是没意义? 还有就是不明白 int printf(const char*...); printf("hello,&s\n",userName); 这个c的输出函数是怎么用(...)实现的. 先谢了:)
posted on 2005-12-30 00:21 豪 阅读(260) 评论(9) 编辑 收藏收藏至365Key 所属分类: C++之梦
FeedBack:
2005-12-30 09:09 | 首先函数体中声明一个va_list,然后用va_start函数来获取参数列表中的参数,使用完毕后调用va_end()结束。像这段代码: void TestFun(char* pszDest, int DestLen, const char* pszFormat, ...) { va_list args; va_start(args, pszFormat); _vsnprintf(pszDest, DestLen, pszFormat, args); va_end(args); } 回复
2005-12-30 09:22 | va_list va_start loop: va_arg va_end 可查看C运行库源代码。 回复
2005-12-30 09:38 | 两位说的是printf的实现吧.有点懂了:) 但是普通函数作参数时候,没理由也用va_start(args, pszFormat)吧?? 那普通函数怎样获得实参值? :) 回复
2005-12-30 12:25 | 其实原理很简单,只要知道栈是如何运作的就可以. 栈其实就相当于一个数组,函数的参数都被储存到这个数组中.C方式的参数传递是从后向前的,由于栈顶是大的地址,入栈时栈顶指针减小,所以以这种方式存储参数的话,最后参数在内存中的映象就是想于从前到后的一个数组了. 所以,只要知道第一个元素(即这里的参数)的地址及后面的元素个数和类型,就可以一个一个的把参数取出来.在使用变长参数时一定至少要有一个固定参数就是这个道理. 知道这样的原理的话就可以在程序在通过第一个参数的地址来取得后面的元素了.比如这样一个函数: void foo( int n, ... ); 其中n表示后面的参数的个数.而我在使用时隐式约定后面的参数都是整型的,即int,就可以这样获得后面的参数了: void* p = &n + 1; //指向后面的第一个参数 while( n-- ) { int* num = (int*)p; //use *num p = (int*)p + 1; //通过类型转换才可以知道1是多少字节. } 这样就可以不用stdarg.h而使用变长参数了. 其实stdarg.h里面没有什么内容,只是定义了几个宏,有几个还是空的宏. 但最好还是用它里面定义的宏,而且在普通函数中也是完全有理由用它的,并不是只有库函数才可以. 回复
2005-12-30 13:28 | 虽然不是很明白,但是还要谢谢大家,又上了一课:) 回复
2005-12-30 14:19 | #include <iostream> using namespace std; void fun(int a, ...) { int *temp = &a; temp++; for (int i = 0; i < a; ++i) { cout << *temp << endl; temp++; } } int main() { int a = 1; int b = 2; int c = 3; int d = 4; fun(4, a, b, c, d); system("pause"); return 0; } Output:: 1 2 3 4 照着自己对栈的理解写的 回复
2005-12-30 22:25 | 不知道有没有不用n记下参数个数的方法?就是foo(...)怎么用?:) 回复
2006-01-10 23:06 | 看了 可冰 的回复后总算是清楚了c函数中参数传递的内幕
|