操纵可变参数的标准方法?

2023-11-22

这是一个奇怪的问题,但是有没有一种标准方法来操纵 a 的内容va_list在将其传递给另一个函数之前?例如,假设我有两个函数,sum and vsum:

int vsum(int n, va_list ap) {
    int total = 0;
    for (int i = 0; i < n; ++i) {
        total += va_arg(n, int);
    return total;
}

int sum(int n, ...) {
    va_list ap;
    va_start(ap, n);
    int total = vsum(n, ap);
    va_end(ap);
    return total;
}

如果我打电话sum as sum(4, 1, 2, 3, 4),我期望得到结果 10。现在我们假设不是调用vsum直接地,sum调用中间函数,vsum_stub它执行以下操作:

int vsum_stub(int n, va_list ap) {
    va_list temp_ap;
    va_copy(temp_ap, ap);
    for (int i = 0; i < n; ++i) {
        int *arg = &va_arg(ap, int);
        *arg += 2;
    }
    va_end(temp_ap);
    return vsum(n, ap);
}

现在当我打电话时sum(4, 1, 2, 3, 4),我应该返回结果 20,因为vsum_stub递增中的所有值va_list2.这当然不能编译,因为你无法获取结果的地址va_arg。还有另一种方法可以做到这一点吗?我在C99工作。


背景:

我正在开发一个库,它可以进行一些指针转换,以便数据可以以更有效的格式存储在堆上。程序是使用自定义转换来编译的,该转换将调用转换为库函数,例如printf到我自己的存根函数(例如,hc_printf). hc_printf需要翻译任何指针参数(用于%s)在将参数传递给实数之前printf功能。

Edit:这是一个代码示例。假设我们有一个字符串foo. foo是动态分配的修改版本malloc它返回一个假指针。编译器修改程序,使其能够处理假指针。所以这有效:

char *foo = fake_malloc(4);
fake_strcpy(foo, "foo");

我想写一个fake_vprintf像这样的函数(伪代码):

int fake_vprintf(const char *format, va_list args) {
    for each pointer argument p in args
        translate p to q, a real pointer to contiguous memory
        replace p with q in args
    }
    return vprintf(format, args);
}

该程序会调用fake_vprintf就像原来的一样vprintf使用假指针。fake_vprintf将假指针转换为真实指针vprintf可以使用。


啊哈,据我了解,你的问题是创建一个新的va_list传递给标准的论点vprintf功能。这反过来又要求您修改列表中的每个成员。但是,由于这样的列表没有元素明智的获取/编辑/插入操作,因此您陷入困境。

我真的看不出有什么办法可以做到这一点。当然,您可以创建一个vprintf应用转换in situ,一次一个参数。我的建议是:重新实施all这样的标准库函数——无论如何你正在编写包装器。这涉及一些工作,但您已经完成了其中的一部分hc_printf等等,那么为什么不走完全程(猜猜函数调用会节省什么!)。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

操纵可变参数的标准方法? 的相关文章

随机推荐

  • colspan 网格视图行

    我已将行添加到 gridview 中 gridview中有20列 我如何在 gridview 中执行类似 colspan 的功能 该功能可以在 2 3 列下显示 2 3 行 并保留为 colspan 基本上我希望在 gridview 的行上
  • 无法使用 Windows 身份验证登录 SQL Server [已关闭]

    Closed 这个问题是无关 目前不接受答案 我刚刚安装了 SQL Server 2012 并打开 SQL Server Management Studio 当我尝试登录时出现此问题 无法连接到 我的问题是我如何知道服务器名称是什么 当我转
  • Google 地图上的自定义点击窗口

    我只是在看其中的一个谷歌地图在 iPhone 中实现 包含标签和按钮 如何在 Android 中获得这种包含标签 按钮和图像的窗口 请向我提供相同的来源 Stone 我已经给出了这个问题的答案 但我还有另一个答案 与上图中您想要的相同 pa
  • 当其他应用程序在 Android 中使用麦克风时,无法访问麦克风

    我使用以下 URL 中的代码通过 AudioRecord 从麦克风获取声音数据 http www dreamincode net forums topic 303235 visualizing sound from the micropho
  • 如何快速将分钟添加到当前时间

    我是 Swift 新手 正在尝试调度程序 我选择了开始时间 需要在开始时间上添加 5 分钟 或其倍数 并将其显示在UILabel IBAction func timePickerClicked sender UIDatePicker var
  • 有没有办法从 bash 运行 zip 文件中的 python 脚本?

    我知道有一种方法可以使用 python 导入 zip 文件中的模块 我在 zip 文件中创建了一种自定义 python 包库 我也想将我的 任务 脚本放入这个包中 这些脚本正在使用该库 然后 使用 bash 我想调用 zip 文件中所需的脚
  • cmdlet 如何知道何时真正应该调用 WriteVerbose()?

    cmdlet 如何知道何时really应该打电话WriteVerbose WriteDebug 等等 也许我错过了一些简单的事情 但我找不到答案 所有 cmdlet 到目前为止我见过的实现只是调用WriteVerbose 没有任何 犹豫 我
  • 在solaris中获取昨天的日期

    我正在运行 SunOS bash 3 00 uname a SunOS lvsaishdc3in0001 5 10 Generic 142901 02 i86pc i386 i86pc 我需要找到Yesterday s date in li
  • 如何在 web.xml 中的 标记中指定根上下文?

    我想在 WAR 文件中指定 Java Web 应用程序的根上下文 我怎样才能使用有效的方法来做到这一点web appXML 中的web xml file 哦 是的 我想以与应用程序服务器无关的方式执行此操作 这不能以与应用程序服务器无关的方
  • Typescript:我可以定义一个 n 长度的元组类型吗?

    我正在使用 Typescript 创建一个将棋游戏板 将棋盘有 9 个等级 我想将 9x9 多维数组断言为一种类型 以确保数组的大小和内容 目前我正在这样创建 9x9 板类型 type Board9x9 p P P P P P P P P
  • numpy.array 形状 (R, 1) 和 (R,) 之间的区别

    In numpy 一些操作恢复原状 R 1 但有些返回 R 这将使矩阵乘法更加繁琐 因为显式reshape是必须的 例如 给定一个矩阵M 如果我们想做numpy dot M 0 numpy ones 1 R where R是行数 当然 同样
  • 如何从颜色资源中获取 color-int?

    有什么方法可以从颜色资源中获取 color int 吗 我试图获取资源 R color myColor 中定义的颜色的各个红色 蓝色和绿色分量 以便我可以将三个搜索栏的值设置为特定级别 您可以使用 getResources getColor
  • 如何从android中的gradle依赖项添加的外部库目录中删除jar文件?

    首先 我在gradle中添加了依赖 然后同步项目 我们没有错误 但是当我们运行应用程序时 我们收到了一个错误 该错误也显示在图像中 app transformClassesWithJarMergingForDebug FAILED Erro
  • AppEngine Channel API - 检查通道是否仍然打开的最佳方法(服务器端)

    我已经在 AppEngine 上构建了一个社交网络 约会类型应用程序 目前正在添加基于 Channel API 构建的聊天 然而 我遇到的问题是用户可能会在聊天时重新加载或导航到新页面 就像在 Facebook 中一样 这意味着服务器不容易
  • Windows 上的 PHP PDO 安装 (xampp)

    我正在尝试开发一个可以在 PHP 上连接到尽可能多的不同数据库的 Web 应用程序 PDO http www php net manual en book pdo php 似乎是正确的接口 但我在安装我需要的所有不同 PDO 数据库驱动程序
  • 使用 Qt 4.4 的自定义停靠区域

    是否可以使用 Qt 4 4 创建自定义停靠区域 我知道这在 Qt 3 中是可能的 因为document建议 摘自文档 如果您需要创建自己的停靠区域 我们建议您创建 QWidget 的子类并将 Q3DockAreas 添加到您的子类 然而 在
  • “spark.yarn.executor.memoryOverhead”和“spark.memory.offHeap.size”之间的区别

    我在纱线上运行火花 我不明白以下设置有什么区别spark yarn executor memoryOverhead and spark memory offHeap size 两者似乎都是为 Spark 执行器分配堆外内存的设置 我应该使用
  • 以编程方式阅读、突出显示、保存 PDF

    我想编写一个小脚本 将在无头 Linux 服务器上运行 来读取 PDF 突出显示与我传递的字符串数组中的任何内容相匹配的文本 然后保存修改后的 PDF 我想我最终会使用类似的东西python 与 poppler 的绑定但不幸的是 文档几乎为
  • 带有圆角的数据网格模板

    I m creating DataGrid template with rounded corners but I faced with this problem 底角超出边界范围 怎么解决这个问题呢 我读过这篇文章 http diptim
  • 操纵可变参数的标准方法?

    这是一个奇怪的问题 但是有没有一种标准方法来操纵 a 的内容va list在将其传递给另一个函数之前 例如 假设我有两个函数 sum and vsum int vsum int n va list ap int total 0 for in