- c - 在位数组中找到第一个零
- linux - Unix 显示有关匹配两种模式之一的文件的信息
- 正则表达式替换多个文件
- linux - 隐藏来自 xtrace 的命令
我想设计一个函数,它接受可变数量的参数,其中一个参数本身就是一个va_list
;但是我的代码出了点问题,我不明白是什么......
警告——我的问题不是设计一个代码来做我想做的事情(我已经找到了绕过这个问题的方法),而是了解我做错了什么......
为了解释我的问题,让我们从一个简单的例子开始:即一个函数 ffprintf
,它的作用类似于 fprintf
,但将其内容写入多个字符串,这些字符串的number 由 ffprintf
的第一个参数指示,其身份由紧接着的参数给出(这些参数的数量可能因一次调用而异,因此您必须使用可变参数列表).这样的函数可以这样使用:
FILE *stream0, *stream1, *stream2;
int a, b;
ffprintf (3, stream0, stream1, stream2, "%d divided by %d worths %f", a, b, (double)a / b);
它的代码是:
void ffprintf (int z, ...)
{va_list vlist, auxvlist;
FILE **streams = malloc (z * sizeof(FILE *));
va_start (vlist, z);
for (int i = 0; i < z; ++i)
{streams[i] = va_arg (vlist, FILE *); // Getting the next stream argument
}
char const *format = va_arg (vlist, char const *); // Getting the format argument
for (int i = 0; i < z; ++i)
{va_copy (auxvlist, vlist); // You have to work on a copy "auxvlist" of "vlist", for otherwise "vlist" would be altered by the next line
vfprintf (streams[i], format, auxvlist);
va_end (auxvlist);
}
va_end (vlist);
free (streams);
}
这很好用。现在,还有标准函数vfprintf
,它的原型(prototype)是vfprintf (FILE *stream, char const* format, va_list vlist);
,你可以像这样使用它来创建另一个具有可变参数列表的函数:
void fprintf_variant (FILE *stream, char const* format, ...)
{
va_list vlist;
va_start (vlist, format);
vfprintf (stream, format, vlist);
va_end (vlist);
}
这也很好用。现在,我的目标是结合这两种想法来创建一个函数,我称之为 vffprintf
,您可以像这样使用它:
FILE *stream0, *stream1, *stream2;
void fprintf_onto_streams012 (char const *format, ...)
{va_list vlist;
va_start (vlist, format);
vffprintf (3, stream0, stream1, stream2, format, vlist);
va_end (vlist);
}
我设计了如下代码:
void vffprintf (int z, ...)
{va_list vlist, auxvlist, auxauxvlist;
va_start (vlist, z);
FILE **streams = malloc (z * sizeof(FILE *));
for (int i = 0; i < z; ++i)
{streams[i] = va_arg (vlist, FILE *);
}
char const *format = va_arg (vlist, char const *);
va_copy (auxvlist, va_arg (vlist, va_list)); // Here I get the next argument of "vlist", knowing that this argument is of "va_list" type
for (int i = 0; i < z; ++i)
{va_copy (auxauxvlist, auxvlist);
vfprintf (streams[i], format, auxvlist);
va_end (auxauxvlist);
}
va_end (auxvlist);
va_end (vlist);
free (streams);
}
这段代码可以顺利编译,但不能正常工作...例如,如果我编写以下完整代码:
#include <stdlib.h>
#include <stdio.h>
#include <stdarg.h>
void vffprintf (int z, ...)
{va_list vlist, auxvlist, auxauxvlist;
FILE **streams = malloc (z * sizeof(FILE *));
va_start (vlist, z);
for (int i = 0; i < z; ++i)
{streams[i] = va_arg (vlist, FILE *);
}
char const *format = va_arg (vlist, char const *);
va_copy (auxvlist, va_arg (vlist, va_list));
for (int i = 0; i < z; ++i)
{va_copy (auxauxvlist, auxvlist);
vfprintf (streams[i], format, auxauxvlist);
va_end (auxauxvlist);
}
va_end (auxvlist);
va_end (vlist);
free (streams);
}
void printf_variant (char const *format, ...)
{va_list vlist;
va_start (vlist, format);
vffprintf (1, stdout, format, vlist);
va_end (vlist);
}
int main (void)
{printf_variant ("Ramanujan's number is %d.\n", 1729);
return 0;
}
我遇到段错误!...为什么?!
P.-S.:很抱歉这个很长的问题;但我希望它非常清楚,因为它是相当技术性的...
P.-S.2:对于这个问题,我特意使用了标签“va-list”和“variableargumentlists”,因为我感兴趣的是 va_list
,被视为一种类型,在(其他)变量参数列表中,被视为列表...所以这里实际上是两个不同的概念。
最佳答案
C11终稿(N1570)中va_arg
的描述包含(type为第二个参数):
if type is not compatible with the type of the actual next argument (as promoted according to the default argument promotions), the behavior is undefined
va_list
可以是数组类型(标准要求它是所谓的“完整对象类型”),您的实现似乎利用了这种可能性。您可能知道,在 C 中,数组不能作为参数传递,因为它们会退化为指针,并且此类指针的类型与原始数组类型不兼容。
例如:int *
与 int [1]
不兼容。因此,如果您确实需要可移植地传递数组或 va_list
,则定义一个带有 va_list
成员的 struct
并传递它(参见 Why can't we pass arrays to function by value? ) .
关于c - 在里面放一个 va_list 变量......一个变量参数列表(!),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/31013757/
在我的应用程序中,我使用 scrape(string url) 方法从网页中抓取链接。可以说它每次都返回我 10 个 url。 我想从每个抓取的 url 中抓取 10 个链接。 长话短说: (第 1
正如标题所说,我需要将 php 放入由 php 回显的 javascript 中 例如: if (something) then (some php)') ?> 这不是真正的代码,只是可能有助于理解
我有一个 ng-repeat 使用 ng-switch 来分隔 ng-repeat 内部的部分,我想在 ng-switch 组上应用一个 orderby 过滤器,但我似乎无法让它工作:
我是 shell 的新手。我不太了解以下功能。这个函数基本上把小时加1。 我想知道为什么开发人员在 $g_current_hour+1 前面放了“10#”。根据我的理解,shell 中的剂量 # 是指
为了在 MongoDB 中对元素进行分组和计数,我已经筋疲力尽了。有很多帖子,但没有一个是我需要的。 这是一个基于以下内容的示例: styvane answer db.VIEW_HISTORICO.a
int main() { int count = 0; string prev = " "; string current; while (cin>>current)
$0表示传递给swift闭包的第一个参数,是swift语言的语法糖。swift会自动为内联闭包提供速记参数名称,可使用$0,$1,$2等名称来引用闭包参数的值。 代码
我想把这个 If 放在宏中,但它总是给我一个错误。我不知道“或”用得是否正确。 Dim SMAT As String SMAT = "blahblahblah" (...) If Ce
这是 JSFiddle 链接:https://jsfiddle.net/fmdsu9Lo/ 我想添加一个悬停功能,以便将鼠标悬停在菜单上将在该菜单选项卡上应用 .current 样式,同时将其从当前打
是否可以在 SQL 中执行类似的操作? SELECT SUM(jobRequirements.number) as total, SUM(jobRequirements.number WHER
我有 3 个 SQL 表。 游戏 wo_tenis_partidos 选择 wo_tenis_pronosticos 配额 wo_tenis_cuotas_ha2 我需要获取满足两个条件的所有行: 条
我有这张乘客表日期: 这意味着在 Reservation 000004 中,有两个行程,分别是 Itinerary 0000010 (AAC Hangar - Anvaya Cove) 和 00000
里面
已关闭。此问题不符合Stack Overflow guidelines 。目前不接受答案。 已关闭 9 年前。 此问题是由拼写错误或无法再重现的问题引起的。虽然类似的问题可能是 on-topic在这里
我在模态框内显示一个弹出窗口,我可以在关闭时隐藏它,但在点击模态框外时无法隐藏它。我试着在关闭时隐藏它,这很好。代码在这里 $('.close, .close-button').click(funct
我所在的团队正在使用 MVC 架构开发 C# 程序。 当我完成 MVC 教程时,我有一些疑问。请帮我澄清一下这个疑惑。 1) Controller 可以对 View 进行哪些修改? 2)我认为所有 U
我正坐在一些通过#defines 生成大量代码的遗留代码上。现在我知道在 #define 中不可能有 #ifdef,但是 #if 可能吗?我想为特定类型添加一些特化。 (无需进行重大更改,例如使用模板
这是我试图用来创建触发器的代码: -- Dumping structure for trigger kavanga_lead.click_links_insert DROP TRIGGER IF EX
我想写这样的东西: #define COV_ON(x) \ #ifdef COVERAGE_TOOL \ _Pragma (CO
我在这样的定义的帮助下初始化一个结构数组: #define FLAGCODE(name) { #name, MNT_ ## name } struct { const char
我尝试将 css 和 jquery 应用于 div 元素,但它不接受 $(this) 参数。我想知道为什么我不能使用 $(this) 作为 div 元素的引用。 blabla.css({ 'top':
我是一名优秀的程序员,十分优秀!