c语言中的变长参数
voidvar_args_func(constchar*fmt,...){char*ap;ap=((char*)&fmt)+sizeof(fmt);/*只想问问这里为什么...
void var_args_func(const char * fmt, ... ) {
char *ap;
ap = ((char*)&fmt) + sizeof(fmt);/*只想问问这里为什么要 + sizeof(fmt) 难道这个&fmt不是4的首地址吗?*/
printf("%d\n", *(int*)ap);
ap = ap + sizeof(int);
printf("%d\n", *(int*)ap);
ap = ap + sizeof(int);
printf("%s\n", *((char**)ap));
}
int main(){
var_args_func("%d %d %s\n", 4, 5, "hello world");
}
void var_args_func(const char * fmt, ... )
函数原型里fmt就是一个指针了,所以fmt就应该是个地址了,
&fmt应该是2级地址了, sillyeeyore你为什么要说&fmt是取第一个参数的首地址呢?
你能确定你没说错吗?
我还求注释那句话的解释如果&fmt是二级指针,那么强制转化成(char *)不久指向错误的地址了?
还有即使是为什么还要加上 + sizeof(fmt) 呢?
在机器上运行sizeof(fmt)=4; 在机器上运行sizeof(fmt)=4; 展开
char *ap;
ap = ((char*)&fmt) + sizeof(fmt);/*只想问问这里为什么要 + sizeof(fmt) 难道这个&fmt不是4的首地址吗?*/
printf("%d\n", *(int*)ap);
ap = ap + sizeof(int);
printf("%d\n", *(int*)ap);
ap = ap + sizeof(int);
printf("%s\n", *((char**)ap));
}
int main(){
var_args_func("%d %d %s\n", 4, 5, "hello world");
}
void var_args_func(const char * fmt, ... )
函数原型里fmt就是一个指针了,所以fmt就应该是个地址了,
&fmt应该是2级地址了, sillyeeyore你为什么要说&fmt是取第一个参数的首地址呢?
你能确定你没说错吗?
我还求注释那句话的解释如果&fmt是二级指针,那么强制转化成(char *)不久指向错误的地址了?
还有即使是为什么还要加上 + sizeof(fmt) 呢?
在机器上运行sizeof(fmt)=4; 在机器上运行sizeof(fmt)=4; 展开
6个回答
展开全部
&fmt是第一个参数的首地址。
根据你后面的代码来看,你传递的第一个参数是一个字符串,即%d %d %s\n。你凭什么要认为你的第一个参数是4呢?奇怪……
&操作符这里是取fmt的地址,没有涉及引用啊?
转化成char*的意思估计是为了强调你第一个传过去的参数是字符串吧?这种叫做“类型转换”,不会改变&fmt里面的数据的,所以肯定不会指向错误的地址,瀑布汗。
最后,+sizeof(fmt)的目的需要肯定,是为了打印出4这个字符来。那么这句话意思就很明白了:首先,将fmt强制转换为char*类型,然后呢,因为fmt已经是char*了,所以移动一个char*那么长的“位置”,来到存储“4”这个数字的地方……再多说一句:你程序里变长参数fmt的结构是“char*,int,int,char*”这样子的,两个char*分别指向两个字符串。
希望你看明白了:D
根据你后面的代码来看,你传递的第一个参数是一个字符串,即%d %d %s\n。你凭什么要认为你的第一个参数是4呢?奇怪……
&操作符这里是取fmt的地址,没有涉及引用啊?
转化成char*的意思估计是为了强调你第一个传过去的参数是字符串吧?这种叫做“类型转换”,不会改变&fmt里面的数据的,所以肯定不会指向错误的地址,瀑布汗。
最后,+sizeof(fmt)的目的需要肯定,是为了打印出4这个字符来。那么这句话意思就很明白了:首先,将fmt强制转换为char*类型,然后呢,因为fmt已经是char*了,所以移动一个char*那么长的“位置”,来到存储“4”这个数字的地方……再多说一句:你程序里变长参数fmt的结构是“char*,int,int,char*”这样子的,两个char*分别指向两个字符串。
希望你看明白了:D
展开全部
你不需要考虑fmt是个什么东西, 也不要把&fmt看作是个什么“二级指针”。 你要注意的是, fmt是最左边的一个参数(唯一一个确定参数), 这样它处于栈顶(按cdecl约定),所以 &fmt实际上就是栈顶地址(这里fmt是个指针的事实是无所谓的,不管它是什么反正它的地址就是栈顶地址),逻辑上说它应该是个void*,转换成char *是为了加减方便。
栈顶地址再加上最顶上元素的size,就是下一个参数(也就是左边数第二个参数)的地址了。
写出来就是: (char*) &fmt + sizeof(fmt)
栈顶地址再加上最顶上元素的size,就是下一个参数(也就是左边数第二个参数)的地址了。
写出来就是: (char*) &fmt + sizeof(fmt)
本回答被提问者采纳
已赞过
已踩过<
评论
收起
你对这个回答的评价是?
展开全部
fmt是传入参数的地址
&fmt存放地址的地址,也就是是指针的地址。
fmt地址的内容是"%d %d %s\n"
ap = ((char*)&fmt) + sizeof(fmt); ap指向的是参数地址的地址+参数的长度。(其实也是一个内存地址),他指向的地址是4的地址的地址
printf("%d\n", *(int*)ap); 第一个输出的内容应该是4
ap = ap + sizeof(int); 这里又往后便宜一个整形长度
printf("%d\n", *(int*)ap); 这里输出是5
ap = ap + sizeof(int); 同上
printf("%s\n", *((char**)ap)); 这里输出是 hello world
ap是指针地址,输出时 *ap还是一个地址,所以用**ap,才能得到内容
是很绕,不知有没有说清楚
&fmt存放地址的地址,也就是是指针的地址。
fmt地址的内容是"%d %d %s\n"
ap = ((char*)&fmt) + sizeof(fmt); ap指向的是参数地址的地址+参数的长度。(其实也是一个内存地址),他指向的地址是4的地址的地址
printf("%d\n", *(int*)ap); 第一个输出的内容应该是4
ap = ap + sizeof(int); 这里又往后便宜一个整形长度
printf("%d\n", *(int*)ap); 这里输出是5
ap = ap + sizeof(int); 同上
printf("%s\n", *((char**)ap)); 这里输出是 hello world
ap是指针地址,输出时 *ap还是一个地址,所以用**ap,才能得到内容
是很绕,不知有没有说清楚
已赞过
已踩过<
评论
收起
你对这个回答的评价是?
展开全部
fmt这个已经是地址了啊 &fmt这个也是取地址不是是这个指针fmt的地址,等于**fmt,&这个表示的是取地址的运算符,与*相反的。不过有时候&这个表示引用取别名的意思。 不一样的
已赞过
已踩过<
评论
收起
你对这个回答的评价是?
展开全部
形参已经是个指针了,* fmt,那么fmt里装的就是地址?
已赞过
已踩过<
评论
收起
你对这个回答的评价是?
推荐律师服务:
若未解决您的问题,请您详细描述您的问题,通过百度律临进行免费专业咨询