In the C programming language, arrays "decay" into pointers when passed to functions.
This means that in the scope where an array is declared, sizeof
will be able to tell you how many bytes it takes up, but once it is passed to another function, sizeof
can only tell you the size of a pointer to the type of the array. Effectively, when an array is passed as a parameter, you lose all length-of-array related information. All that is preserved is the memory-address where the array starts, and its type, so in your case, sizeof marks
in main()
is equivalent to sizeof(int[5])
and sizeof marks
in avg()
is equivalent to sizeof(int*)
.
The consequences of this are that if you are going to be passing arrays of different lengths to a function, then you either have to send a separate length parameter, or give the function some way to infer the length of the array.
For instance, C strings are implemented as arrays of char
, such that the last character of the array is the null-terminator byte, '\0'
. This allows a function that expects a C-standard string parameter to keep reading byte after byte from the string without stopping until it finds the '\0'
, but this is controversial, as it is a rather significant source of bugs and security concerns, because if this assumption fails, and there is no '\0'
at the end of the string, then the function could very well blindly access memory it has no business messing with.
If you need to pass an array pointer to a function and preserve its length, the best (or perhaps least controversial) solution is to pass the length along with the array, so int avg(int marks[],int numMarks);
might be a function prototype that will serve your purposes. You could implement a system, where there is a value of int
that is an invalid mark to be averaged, and use it to mark the end of the array, but this is likely a more difficult solution to implement safely.