/* Concatenate the NULL-terminated list of string arguments into
freshly allocated space. */
char *
concat_strings (const char *str0, ...)
{
va_list args;
int saved_lengths[5]; /* inspired by Apache's apr_pstrcat , (for efficiency matters?)*/
char *ret, *p;
const char *next_str;
int total_length = 0;
int argcount;
/* Calculate the length of and allocate the resulting string. */
argcount = 0;
va_start (args, str0);
for (next_str = str0; next_str != NULL; next_str = va_arg (args, char *))
{
int len = strlen (next_str);
if (argcount < dim (saved_lengths))
saved_lengths[argcount++] = len;
total_length += len;
}
va_end (args);
p = ret = (char *)malloc (total_length + 1);
/* Copy the strings into the allocated space. */
argcount = 0;
va_start (args, str0);
for (next_str = str0; next_str != NULL; next_str = va_arg (args, char *))
{
int len;
if (argcount < dim (saved_lengths))
len = saved_lengths[argcount++];
else
len = strlen (next_str);
memcpy (p, next_str, len);
p += len;
}
va_end (args);
*p = '\0';
return ret;
}
我的疑问是:函数内没有任何语句跟可变参数...联系。va_xxxx系列的函数是怎么知道是对可变参数...进行操作的呢?
5 个解决方案
#1
知道最后一个固定参数就能知道可变参数开始的地址,关于到底压了多少参数,其实是不知道的,所以说很危险
#2
不是这样吧,带可变参数调用函数时,是把参数一个一个压入一个栈里,最后给你一个开头地址你可以根据此
地址一个一个取参数,具体怎么取,有你自己决定,参数什么意义,也有你自己决定.
//你看一下这个函数,不加参数运行一下就知道了.
int main(int argv,char **argc)
{
int i=0;
for(i=0;i<10;i++)
printf("%s\n",argc[i]);
}
地址一个一个取参数,具体怎么取,有你自己决定,参数什么意义,也有你自己决定.
//你看一下这个函数,不加参数运行一下就知道了.
int main(int argv,char **argc)
{
int i=0;
for(i=0;i<10;i++)
printf("%s\n",argc[i]);
}
#3
哦,是不是跟c语言内部实现的函数参数压栈有关?
以上一个函数为例,
调用concat_strings("we ", "are ", "the ", "champions", (char *)0);
程序会把参数按顺序排列,即每个字符串的地址按顺序排列,从而可变参数知道"we"的地址就可以按顺序找到下一个变量的地址.
是这样吗?
以上一个函数为例,
调用concat_strings("we ", "are ", "the ", "champions", (char *)0);
程序会把参数按顺序排列,即每个字符串的地址按顺序排列,从而可变参数知道"we"的地址就可以按顺序找到下一个变量的地址.
是这样吗?
#4
谢谢cceczjxy()
按照你说的,如下也可以。谢谢了
void
arg(int i, int j)
{
int *ip = &i;
printf("%d --- %d\n", *ip, *(ip + 1));
}
int
main()
{
arg(4, 6);
}
按照你说的,如下也可以。谢谢了
void
arg(int i, int j)
{
int *ip = &i;
printf("%d --- %d\n", *ip, *(ip + 1));
}
int
main()
{
arg(4, 6);
}
#5
这是我写的错误处理函数,变长参数,其实就是K&R中的代码^_^
主意要include <stdarg.h>
18 /***********our error handler***********/
19 void printerr(char *fmt, ...)
20 {
21 va_list args;
22
23 va_start(args, fmt);
24 fprintf(stderr, "error: ");
25 vfprintf(stderr, fmt, args);
26 fprintf(stderr, "\n");
27 va_end(args);
28 exit(1);
29 }
我的疑问是:函数内没有任何语句跟可变参数...联系。va_xxxx系列的函数是怎么知道是对可变参数...进行操作的呢?
注意函数:va_start(),va_end(),还有va_list类型,这几个就是处理的关键
主意要include <stdarg.h>
18 /***********our error handler***********/
19 void printerr(char *fmt, ...)
20 {
21 va_list args;
22
23 va_start(args, fmt);
24 fprintf(stderr, "error: ");
25 vfprintf(stderr, fmt, args);
26 fprintf(stderr, "\n");
27 va_end(args);
28 exit(1);
29 }
我的疑问是:函数内没有任何语句跟可变参数...联系。va_xxxx系列的函数是怎么知道是对可变参数...进行操作的呢?
注意函数:va_start(),va_end(),还有va_list类型,这几个就是处理的关键
#1
知道最后一个固定参数就能知道可变参数开始的地址,关于到底压了多少参数,其实是不知道的,所以说很危险
#2
不是这样吧,带可变参数调用函数时,是把参数一个一个压入一个栈里,最后给你一个开头地址你可以根据此
地址一个一个取参数,具体怎么取,有你自己决定,参数什么意义,也有你自己决定.
//你看一下这个函数,不加参数运行一下就知道了.
int main(int argv,char **argc)
{
int i=0;
for(i=0;i<10;i++)
printf("%s\n",argc[i]);
}
地址一个一个取参数,具体怎么取,有你自己决定,参数什么意义,也有你自己决定.
//你看一下这个函数,不加参数运行一下就知道了.
int main(int argv,char **argc)
{
int i=0;
for(i=0;i<10;i++)
printf("%s\n",argc[i]);
}
#3
哦,是不是跟c语言内部实现的函数参数压栈有关?
以上一个函数为例,
调用concat_strings("we ", "are ", "the ", "champions", (char *)0);
程序会把参数按顺序排列,即每个字符串的地址按顺序排列,从而可变参数知道"we"的地址就可以按顺序找到下一个变量的地址.
是这样吗?
以上一个函数为例,
调用concat_strings("we ", "are ", "the ", "champions", (char *)0);
程序会把参数按顺序排列,即每个字符串的地址按顺序排列,从而可变参数知道"we"的地址就可以按顺序找到下一个变量的地址.
是这样吗?
#4
谢谢cceczjxy()
按照你说的,如下也可以。谢谢了
void
arg(int i, int j)
{
int *ip = &i;
printf("%d --- %d\n", *ip, *(ip + 1));
}
int
main()
{
arg(4, 6);
}
按照你说的,如下也可以。谢谢了
void
arg(int i, int j)
{
int *ip = &i;
printf("%d --- %d\n", *ip, *(ip + 1));
}
int
main()
{
arg(4, 6);
}
#5
这是我写的错误处理函数,变长参数,其实就是K&R中的代码^_^
主意要include <stdarg.h>
18 /***********our error handler***********/
19 void printerr(char *fmt, ...)
20 {
21 va_list args;
22
23 va_start(args, fmt);
24 fprintf(stderr, "error: ");
25 vfprintf(stderr, fmt, args);
26 fprintf(stderr, "\n");
27 va_end(args);
28 exit(1);
29 }
我的疑问是:函数内没有任何语句跟可变参数...联系。va_xxxx系列的函数是怎么知道是对可变参数...进行操作的呢?
注意函数:va_start(),va_end(),还有va_list类型,这几个就是处理的关键
主意要include <stdarg.h>
18 /***********our error handler***********/
19 void printerr(char *fmt, ...)
20 {
21 va_list args;
22
23 va_start(args, fmt);
24 fprintf(stderr, "error: ");
25 vfprintf(stderr, fmt, args);
26 fprintf(stderr, "\n");
27 va_end(args);
28 exit(1);
29 }
我的疑问是:函数内没有任何语句跟可变参数...联系。va_xxxx系列的函数是怎么知道是对可变参数...进行操作的呢?
注意函数:va_start(),va_end(),还有va_list类型,这几个就是处理的关键