如何在C++中循环使用va_arg,处理未知数量的可选参数求和?
Great question! Let's break this down—C's variable argument system (va_list) doesn't come with a built-in way to know how many extra parameters were passed to your function. That means you need an explicit way to signal when the loop should stop. There are two common, reliable approaches to solve this:
1. Use a Sentinel Value (Terminator)
You can agree on a special "stop" value that tells the loop to exit when it's encountered. For example, if your function doesn't need to sum the number 0, you can use 0 as the sentinel. Here's how to adjust your code (I'll swap the empty for loop for a more intuitive while loop, though I'll show a for version too):
Using while (Recommended for Readability)
#include <stdarg.h> #include <limits.h> // Optional, if you use a more unique sentinel like INT_MIN int sumOfAtLeastTwoIntegers(int a, int b, ...){ int sum = a + b; va_list ptr; va_start(ptr, b); int current; // Loop until we hit our sentinel value (here, using 0 as an example) while ((current = va_arg(ptr, int)) != 0) { sum += current; } va_end(ptr); return sum; }
If You Prefer a for Loop
You can use an infinite for loop and break when the sentinel is found:
int sumOfAtLeastTwoIntegers(int a, int b, ...){ int sum = a + b; va_list ptr; va_start(ptr, b); int current; for (;;) { // Infinite loop current = va_arg(ptr, int); if (current == 0) { break; } sum += current; } va_end(ptr); return sum; }
Important Note: Make sure your sentinel value never appears as a valid input. If your function needs to handle 0, use a more unique value like INT_MIN (the smallest possible integer) from <limits.h> instead. When calling the function, you must append this sentinel at the end:
// Correct call (ends with 0 as sentinel) int total = sumOfAtLeastTwoIntegers(2, 3, 4, 5, 1, 200, 0);
2. Pass the Total Number of Arguments
A more robust approach (especially if all integer values are valid inputs) is to pass the total number of integers as the first parameter. This way, you know exactly how many times to loop:
#include <stdarg.h> int sumOfAtLeastTwoIntegers(int count, ...){ // Ensure we have at least 2 integers to sum if (count < 2) { return 0; // Or handle error as needed } va_list ptr; va_start(ptr, count); int sum = 0; for (int i = 0; i < count; i++) { sum += va_arg(ptr, int); } va_end(ptr); return sum; }
Now your call includes the total number of integers upfront:
// Call with 6 integers total int total = sumOfAtLeastTwoIntegers(6, 2, 3, 4, 5, 1, 200);
Why This Matters
C's va_list doesn't track the number of arguments—relying on a sentinel or explicit count is the only way to safely terminate the loop. Without this, your function will keep reading memory beyond the passed arguments, leading to undefined behavior (random values, crashes, etc.).
内容的提问来源于stack exchange,提问作者Operator

