Vikram said:
James said:
Vikram said:
Ian Collins writes:
On 01/25/11 09:50 AM, Vikram wrote:
Hello friends
the code below will find the mean (average) of some numbers, however
it produces only garbage. Can you see a problem?
Kind Regards,
Vikram
float mean(int x[])
^^^^^^^
NB in this function I am considering the pointer, as an array.
Regardless of how you like to think about it, when you pass an array to
a function in C, the function receives a pointer to the first element of
the array. That's just the way passing an array works in C. If you take
sizeof() the parameter, you'll just get the size of the pointer, which
is nothing to do with the size of the array.
Hello James
I think you are wrong about this. I have been doing some tests and what I
discovered is my library's sizeof() function is buggy! For some reason it
miscalculates all sizes by a multiple of 4. It's easy to correct this,
see the code below
You have misunderstood.
#define sizeof(x) (sizeof(x)/4)
This macro is likely to break things very badly if you try to use it.
This should be "int main(void)". Your compiler will probably let you
get away with the old-style "main()" declaration. This is not the cause
of your problems, but you should fix it anyway.
{
int a1[1];
int a2[5];
int a3[20];
printf("1=%d\n5=%d\n20=%d\n",sizeof(a1),sizeof(a2),sizeof(a3));
sizeof (either the built-in operator or your macro) yields a result of
type size_t, which is an unsigned type. The "%d" format requires an
argument of type int, a signed type. If size_t and int happen to be the
same size on your system, the above is likely to *appear* to work
correctly, but it could break badly on a different system. You can
avoid this by converting each operand to int, or (if your implementation
supports it), by using the "%zu" format which does require a size_t
argument.
printf("1=%d\n5=%d\n20=%d\n", (int)sizeof a1, (int)sizeof a2, (int)sizeof a3);
or
printf("1=%zu\n5=%zu\n20=%zu\n", sizeof a1, sizeof a2, sizeof a3);
This is not the cause of your problems, but you should fix it anyway.
The parentheses are unnecessary but harmless.
}
This now successfully produces:
1=1
5=5
20=20
That's the output I'd expect on a system with sizeof(int) == 4.
Some things you should understand:
sizeof is an operator, not a function. It might seem odd to have an
operator whose name is a keyword rather than a sequence of one or more
punctuation characters, but there it is.
There are actually two forms. One is ``sizeof expr'', which
yields the size of the result of an expression (without evaluating
the operand in most cases). If you write ``sizeof(a1)'', you're
applying sizeof to a parenthesized expression; the parentheses
are part of the operand, not part of the syntax of sizeof itself,
just like writing ``-(x)'' rather than ``-x''. If you're more
comfortable adding parentheses, they won't hurt anything (the same
applies to your return statement), but you should at least be able to
understand what's going on when you're reading someone else's code.
In some cases you might need parentheses just for grouping.
The other form is ``sizeof ( type-name )'', which yields the size
of a given type; for that form, the parentheses are required.
sizeof yields the size of its operand *in bytes*. It does not yield the
number of elements in an array, unless the array happens to have
one-byte elements. (A byte is *at least* 8 bits; it will be exactly
8 bits on any system you're likely to encounter.)
The reason dividing by 4 gave results that you thought were sensible is
that sizeof(int) happens to be 4 on your system. It could be 2, or 8,
or even 1, on another system (the latter is possible only if a byte is
at least 16 bits).
It's common to define a macro to determine the number of elements in an
array:
#define ARRAY_LENGTH(arr) (sizeof (arr) / sizeof (arr[0]))
Note that this works only if you apply it to an array object. If you
try to apply it to a function parameter -- well, read section 6 of
the comp.lang.c FAQ, <
http://www.c-faq.com/>. And browse the rest of it
while you're there; it's an excellent resource.