繁体   English   中英

C中如何使用va_arg修改可变参数的值

[英]How to use va_arg to modify the value of a variadic parameter in C

#include <stdarg.h>
#include <stdio.h>
#include <stdlib.h>

void tag_log(const char *format, ...) {
    va_list ap;
    va_start(ap, format);
    for (int i = 0; i < 4; i++) {
        va_arg(ap, int) += 100; // is wrong?
    }
    va_end(ap);
    va_start(ap, format);
    vprintf(format, ap);
    va_end(ap);
}

int main() {
    tag_log("%d, %d, %d, %d\n", 1, 2, 3, 4);
}

由于 va_arg 返回一个右值,因此无法修改内容。 如何修改可变参数的内容?

预计 output:101、102、103、104

谢谢!!!

我应该怎么做?

假设您调用:

int main() {
    tag_log("%d, %s, %d, %d\n", 1, "My precious values", 3, 4);
}

你将如何在你的tag_log()中处理它? 您要重新解释传递给字符串文字的指针并向其添加100吗?

这个问题的答案是“你不能”

        va_arg(ap, int) += 100; // is wrong?

相当于右值(function 值或宏调用的结果,转换为宏调用的第二个参数中指定的类型),因此您无法更改它。 右值只是一个值,与存储位置无关。 这就是参数传递给函数的方式,以及函数返回值的方式,但是虽然显式参数声明导致局部变量(可以用作值和修改),但va_arg()宏返回的表达式是右值,所以,你不能改变它(因为你不能在程序中改变文字值3 )情况就像你有:

#define PARAMETER 3

你说

    PARAMETER = 5;

(好吧,不完全一样......但效果是一样的)即使 statemente 看起来像一个变量赋值,你有一个右值( 3 )被分配另一个右值( 5 ),就像

    3 = 5;

你能做这个吗? 不。

但是您有一个解决方案...只需创建一个局部变量并将 va_arg 返回的值赋给它。

    int var = va_arg(ap, int);
    var += 100;  // this is not wrong anymore.

或者在你想要的表达式中使用右值

    whatever_int_variable = va_arg(ap, int) + 100;  // this is also valid.

如果您认为"%s, %s, %s, %s\n"文字字符串应该始终是固定的,那么您最好这样做:

#include <stdarg.h>
#include <stdio.h>
#include <stdlib.h>

void tag_log(int a, int b, int c, int d) {
   printf("%d, %d, %d, %d\n", a, b, c, d);
}

int main() {
    tag_log(1, 2, 3, 4);
}

但我想你想要做的是像printf一样通用,制作所有可能的格式字符串....然后你需要深入研究printf的主体,看看它如何解决每个格式说明符并执行在您的 function 中相同。您可以通过选择所有格式说明符来划分工作,并将字符串文字划分到仅打印文字字符串的位置,并将所有格式说明符分开以使用每个参数单独调用 printf,但示例代码你指定的没有很好地指定,所以我认为不值得考虑添加 100 来打破字符串参数以将文字格式与格式说明符分开并将 100 添加到所有 integer 参数,或者添加 100.0 到double ,应该怎么办我们用字符串文字还是布尔值?

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM