Are C arrays passed by reference?

Started by
43 comments, last by MadKeithV 15 years, 8 months ago
I'm going to teach a small class the basics of C, and I want to introduce arrays much earlier than pointers. As far as I know, C only has pass by value. Is it safe to suggest beginners that C appears to pass arrays by reference, or will that confuse them? My understanding is that in a formal parameter declaration, char a[] is just syntactic sugar for char *a, and the actual array argument decays into a pointer, and that pointer is passed by value (correct me if I'm wrong). But it is impossible to explain that to the students on the first day.
Advertisement
I was not really sure about it, but yes, arrays are passed by reference.

#include <stdio.h>void function(int array[]){	printf("Address: %p\n", array);}int main(int argc, char **argv){	int array[10];	printf("%p\n", array);	function(array);	return 0;}


0022FF40Address: 0022FF40
That example proves nothing: in main() you are decaying the array to a pointer to pass to printf and the same thing is occurring when you call function().

An example that won't compile:
int main(){    int example[4];    ++example; // illegal}


This, however, will:
void function( int arg[4] ){    ++arg;}int main(){    int example[4];    function(example);}


Finally:
void function( int arg[4] ){    printf("arg size: %d\n",sizeof(arg));}int main(){    int example[4];    function(example);    printf("array size: %d\n",sizeof(example));}
Okay my first example wasn't clear but it is not wrong:
#include <stdio.h>void function(int array[]){	array[0]++;}int main(int argc, char **argv){	int array[10];	array[0] = 5;	printf(" Before: %i\n", array[0]);	function(array);	printf(" After : %i\n", array[0]);	return 0;}

array is a pointer in function(), but you can still use it as the same array like in main(). I think this is the important thing to DevFred as he does not want to introduce pointers yet.
Arrays are not passed by either value or reference in C. You can either pass a pointer (or reference in C++) to an array, or decay the array to a pointer, but either situation will involve a pointer.

You may be able to hide some parts of this reality if you have not introduced pointers yet, by stating that the parameter int arr[] is an array being passed by reference, but its size is unknown (and as such, the value of sizeof(arr) has no meaning). This will work as long as you don't get too deep in the difference between arrays and pointers (but the main differences should not appear until you've dealt with pointers anyway).
Quote:Original post by ToohrVyk
You may be able to hide some parts of this reality if you have not introduced pointers yet, by stating that the parameter int arr[] is an array being passed by reference, but its size is unknown

That is exactly what I was going to do. Thanks for the confirmation.

Later on, I want to explain this behavior. I'm no C expert, this is my train of thought:
- all C89 sizeof expressions are evaluated at compile time
- the size of an array is not part of the array itself, but the compiler can figure it out from the declaration
- if it were possible to pass arrays by value, the size of the array would have to be part of the parameter declaration, so the function could only be called with a specific sized array as an argument, and that isn't very practical
- you could theoretically overload the function with different sized array parameters, but that's also not very practical
- and of course, there is no overloading in C
- thus, we need a solution that throws away the size of the array, and that is how it is done in C

Does that make sense? Hm, it still doesnt explain why arrays aren't passed by value. But if we see argument-parameter-binding as assignment, it makes sense if you know that you can't assign arrays to arrays. Maybe I should make that clear first.
An array in C is really just a pointer to the first value of the array, nothing more (and strings are just char arrays with a terminator). So when ever you pass around an array you are just passing that pointer around.

IMO introducing arrays and not introducing pointers is a very bad idea. The [] is just using pointer arithmetic to get to the position in the array you want. array[5] is no different then *(array +=5). Without understanding the pointer math they will never really understand why their arrays are breaking. Just my 2 cents.

theTroll
Quote:Original post by TheTroll
An array in C is really just a pointer to the first value of the array

No.
Read 6.3.

"A reference to an object of type array-of-T which appears in an expression decays (with three exceptions) into a pointer to its first element; the type of the resultant pointer is pointer-to-T. "

theTroll
If an array is really a pointer, then why does sizeof() lie? Why is pointer arithmetic disallowed? The only conclusion is that the array is not a pointer.

This topic is closed to new replies.

Advertisement