那些网站分享pr做的视频软件,福州网站建设企业,paypal绑定wordpress,进空间的网站吗在C中#xff0c;当无法列出传递函数的所有实参的类型和数目时#xff0c;可以用省略号指定参数表。例如#xff1a;
void foo(...);
void foo(parm_list,...);函数参数的传递原理 函数参数是以栈的形式存取#xff0c;从右至左入栈。 参数的内存存放格式#xff1a;参数…在C中当无法列出传递函数的所有实参的类型和数目时可以用省略号指定参数表。例如
void foo(...);
void foo(parm_list,...);函数参数的传递原理 函数参数是以栈的形式存取从右至左入栈。 参数的内存存放格式参数存放在内存的堆栈段中在执行函数的时候从最后一个开始入栈。因此栈底高地址栈顶低地址举个例子如下
void func(int x, float y, char z);那么调用函数的时候实参 char z 先进栈然后是 float y最后是 int x因此在内存中变量的存放次序是 x-y-z。从理论上说我们只要探测到任意一个变量的地址并且知道其他变量的类型通过指针移位运算则总可以顺藤摸瓜找到其他的输入变量。举个例子如下
#include stdio.h //获取参数列表中的所有参数并打印
void PrintInt(int cnt, ...)
{ int *temp cnt;temp;for (int i 0; i cnt; i) { printf(%d\n, *temp); temp; }
}int main(void)
{int a 1; int b 2; int c 3; int d 4;PrintInt(4, a, b, c, d); return 0;
}执行程序后输出
1 2 3 4
利用Va_start相关宏获取省略号指定的参数 下面是 stdarg.h 里面重要的几个宏定义如下
typedef char* va_list;
void va_start ( va_list ap, prev_param ); /* ANSI version */
type va_arg ( va_list ap, type );
void va_end ( va_list ap ); 说明
1va_list一个字符指针可以理解为指向当前参数的一个指针取参必须通过这个指针进行。
2va_start对ap进行初始化让ap指向可变参数表里面的第一个参数。第一个参数是 ap 本身第二个参数是在变参表前面紧挨着的一个变量即“…”之前的那个参数
3va_arg: 获取参数。它的第一个参数是ap第二个参数是要获取的参数的指定类型。按照指定类型获取当前参数返回这个指定类型的值然后把 ap 的位置指向变参表中下一个变量的位置
4va_end释放指针将输入的参数 ap 置为 NULL。通常va_start和va_end是成对出现。
使用上面的宏获取参数的步骤如下
Step 1 定义一个 va_list 类型的变量(假设va_list 类型变量被定义为ap) Step 2 调用va_start 对ap 进行初始化让它指向可变参数表里面的第一个参数。 Step 3 获取参数并使用参数。 Step 4 获取所有的参数之后将 ap 指针关掉。
给出一个例子如下
#include 〈stdio.h〉
#include 〈string.h〉
#include 〈stdarg.h〉/*ANSI标准形式的声明方式括号内的省略号表示可选参数*/
int demo(char msg, ...) {/*定义保存函数参数的结构*/va_list argp;int argno 0;char para;/*argp指向传入的第一个可选参数msg是最后一个确定的参数*/va_start(argp, msg);while (1) {para va_arg(argp, char);if (strcmp(para, ) 0)break;printf(Parameter #%d is: %s\n, argno, para);argno;}va_end(argp);/*将argp置为NULL*/return 0;
}void main(void) {demo(DEMO, This, is, a, demo!, );
}