![]() |
| | #1 |
| Registered User Join Date: Jul 2002
Posts: 282
| Variable Arguments Question I wrote a function that keeps adding the numbers (till you get a zero in the argument of the function) Here's something I couldn't figure out: The following code works : Code: #include <stdio.h>
#include <stdarg.h>
void add(char *say, ...)
{
int answer = 0;
int temparg = 0;
va_list argumentlist;
va_start(argumentlist, say);
while ((temparg = va_arg(argumentlist, int)) != 0)
{
answer = answer + temparg;
printf("temparg is %d\n", temparg);
}
printf("%s %d\n", say, answer);
va_end(argumentlist);
}
main()
{
add("Addition result: ", 1, 0);
add("Addition result: ", 1, 2, 0);
add("Addition result: ", 1, 2, 3, 0);
}
Code: #include <stdio.h>
#include <stdarg.h>
void add(char *say, ...)
{
int answer = 0;
int temparg = 0;
va_list argumentlist;
va_start(argumentlist, say);
while (va_arg(argumentlist, int) != 0)
{
temparg = va_arg(argumentlist, int);
answer = answer + temparg;
printf("temparg is %d\n", temparg);
}
printf("%s %d\n", say, answer);
va_end(argumentlist);
}
main()
{
add("Addition result: ", 1, 0);
add("Addition result: ", 1, 2, 0);
add("Addition result: ", 1, 2, 3, 0);
}
what could the reason be ? Also, although I read the same paragraph several times, I still didn't understand the real purpose of va_list va_start va_end if I say, va_list mahurshi does it mean that "mahurshi" is like an array ? why do we need to va_end ? Thanks for your time and patience in reading this! ------------------------------------------------------------------------ If anyone is too proud to answer my questions politely, I encourage him/her not to answer. No offence. Thanks. ------------------------------------------------------------------------ |
| moonwalker is offline | |
| | #2 |
| Registered User Join Date: Jul 2002
Posts: 945
| in the second one, you call va_arg in the while statement and discard the result, then you call va_arg again inside the while loop and use the result, so you're missing every other arg
__________________ hello, internet! |
| moi is offline | |
| | #3 | |
| Just because Join Date: Jan 2002
Posts: 2,502
| variable length functions are interesting, but difficult at times. while most functions store their variables into stack, with the function parameters to show what and where the data is, variable list arguments are different. variable list argument functions don't necessarily know what data they're receiving ahead of time, so they need a pointer (va_list) to the stack so they can manage it during run-time. va_start moves the pointer to the beginning of the list. va_end destroys the list. Code: arg_type va_arg(va_list, arg_type); Code: while ((temparg = va_arg(argumentlist, int)) != 0)
{
answer = answer + temparg;
printf("temparg is %d\n", temparg);
}
Code: while (va_arg(argumentlist, int) != 0)
{
temparg = va_arg(argumentlist, int);
answer = answer + temparg;
printf("temparg is %d\n", temparg);
}
Quote:
Code: void func1(int x, int y); Code: -------- - int x- -------- - int y- -------- Code: void printf(char*,...); Code: ---------- - char * - ---------- - ???? - the only way the compiler can tell the contents of that mystery area is to rely on the programmer to figure out a system. in your function, you keep adding each 4-byte block as if it were an integer until you reach a zero. printf relies on the string to find out what data was handed to it. to make a long story short (too late)... va_list is a pointer to the beginning of the stack. va_arg takes an argument of the size you specify and increments the pointer to the next argument. va_end disables the va_list pointer so it can't be used (unless va_start is called again). va_start points the va_list to the first element in the stack. i know i haven't made it clear, but read through and ask if you need anything clarified. | |
| ygfperson is offline | |
| | #4 |
| Registered User Join Date: Jul 2002
Posts: 282
| thanks thank you very much. that clears up most of my stack ![]() just kidding.. it was very helpful. thanks once again. |
| moonwalker is offline | |
| | #5 |
| Registered User Join Date: Jul 2002
Posts: 282
| oh oh, another question... i want void add(char *say, ...) to be directly void add(...) is that possible ? also, i am terminating with a zero in my code... i want it to terminate after the last argument (it need not be zero) how can it be done ? thanks again |
| moonwalker is offline | |
| | #6 |
| and the hat of Jobseeking Join Date: Aug 2001 Location: The edge of the known universe
Posts: 21,710
| > void add(...) > is that possible ? No - va_start needs to know the last named argument, so you always need at least one named parameter > i want it to > terminate after the last argument (it need not be zero) > how can it be done ? It can't - not in standard C anyway The loop which loops through the arguments needs to know how many times to loop - there is no magical compiler generated value which signifies the end of the list There are two basic ways to do this 1. Encode the number of variable parameters - like printf does with all it's conversion formats 2. Mark the end of the list with a sentinel value such as 0, like you have done |
| Salem is offline | |
| | #7 |
| Registered User Join Date: Jul 2002
Posts: 282
| hmm >Encode the number of variable parameters - like printf does with all it's conversion formats could you elaborate this one please? Last edited by moonwalker; 08-04-2002 at 06:37 AM. |
| moonwalker is offline | |
| | #8 |
| and the hat of Jobseeking Join Date: Aug 2001 Location: The edge of the known universe
Posts: 21,710
| printf( "%d %d", 1, 2 ); The number of % tell you the number of additional parameters. In your case, you could just do this to provide the count directly Code: #include <stdio.h>
#include <stdarg.h>
void add ( char *say, int num, ... ) {
int answer = 0;
int temparg = 0;
int i;
va_list argumentlist;
va_start(argumentlist, num);
for ( i = 0 ; i < num ; i++ ) {
temparg = va_arg(argumentlist, int);
answer = answer + temparg;
printf("temparg is %d\n", temparg);
}
va_end(argumentlist);
printf("%s %d\n", say, answer);
}
int main() {
add("Addition result: ", 1, 1 );
add("Addition result: ", 2, 1, 2 );
add("Addition result: ", 3, 1, 2, 3 );
return 0;
}
|
| Salem is offline | |
| | #9 | |
| Just because Join Date: Jan 2002
Posts: 2,502
| Quote:
you can also use that explanation to show why void add(...) won't work. the function void add(...) doesn't give any number of arguments info to itself, so it can't figure out how many (if any) variables to get from the stack. | |
| ygfperson is offline | |
![]() |
| Thread Tools | |
| Display Modes | |
|
Similar Threads | ||||
| Thread | Thread Starter | Forum | Replies | Last Post |
| GradeInfo | kirksson | C Programming | 23 | 07-16-2008 03:27 PM |
| Question about printing a variable??? | Hoser83 | C++ Programming | 2 | 03-31-2006 01:57 PM |
| return values from function with variable number of arguments | evo_x | C++ Programming | 10 | 09-27-2005 12:49 PM |
| How slow are variable arguments? | dwks | C Programming | 5 | 09-18-2005 12:11 PM |
| Variable number of arguments | dit6a9 | Windows Programming | 3 | 08-10-2004 08:58 AM |