2

There's a function avg(int, ...) which calculates the average number of input integers,

avg(1,2,3) = 2, avg(2,3,4,5,6) = 4  

Now I have an array of integers that need to use avg() to get their average value,
but the array's size is dynamic, maybe read from stdin or from a file.

Code example:

int i, num;  
scanf("%d", &num);  
int *p = malloc(num * sizeof(int));  
for(i = 0; i < num; ++i)  
    scanf("%d", &p[i]);  
// what should I do now?  
// avg(p[0], p[1],....)  

Note that the avg() function should be called only once.

-- EDITED --
The avg() function is just an example, the real function is more complex than that.

2 Answers 2

4

There's no portable way to do this. Most of the time when a varargs function exists, there is also a variant which directly accepts an array parameter instead.

Sign up to request clarification or add additional context in comments.

2 Comments

Indeed there is a varargs function, but without one which accepts an array. I'm doing this on x86 under linux, is there any trick to solve this problem?
You could use gcc's __builtin_apply() function (check gcc documentation) but it requires knowing the format of the ARGUMENTS data (which is not documented, and is platform dependent).
0

Just pass the p and the number of elements that p can point to.

float computeAverage( int *p, int count ) ; // count being `num` in this case.

In the function, have a loop that iterates 0 to count-1 and in which sum of all the elements can be computed. After the loop, just return sum/count which is the average.

4 Comments

Thank you for your quick reply. In fact this is just an example function and the real problem is much more complex, and I have to use the pre-defined function instead of creating my own implementation.
@tfengjun - As @davmac suggested there is no portable way to do this except passing the pointer. Good luck.
Can you give me a hint on how to deal with it in a non portable way? As my code only runs on linux x86.
@tfengjun: the non-portable way is to find out the format in which varargs are stored in your C calling convention (it's part of the ABI for the platform), then write some assembly that allocates the necessary stack space, writes them in the correct format, then calls avg. On linux x86, a series of int varargs looks just like an array of int, but if the arguments are more varied than that then the assembly will get more complicated. There will probably be some helpers for this in linux somewhere, but I don't know what. You may not even have to write assembly, that's the last resort.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.