As taught we can pass a whole "struct" by value to a function but we
can't pass an array by value. Why?
the short answer is: because structs and arrays are implemented differently in C.
longer answer: there is a difference between a struct type and its pointer type. for example, given the struct
struct MyStruct {// members};
MyStruct s;
// and
MyStruct *p;
// are different
similarly there is a difference between an array type and its pointer type (or the pointer type elements of this array). for example:
int arr[5];
// and
int *p;
// are different
but only in the scope where the array is created. in other words, you can say that there is no array parameter type. when you declare the type of a parameter as an array, it actually gets declared to be of the array element's pointer type.
in this case, only the pointer is the one that is part of the struct itself but not the elements of the array. for example:
void foo(int arr[]){ // code }
is actually
void foo(int *arr){ // code }
you can confirm that maybe by printing the sizeof
an array where its declared and inside a function that it was passed to as a parameter and compare the results.
it's often said that arrays decay to pointers. this is actually why when passing an array to a function, only the address of that array is passed.
this is not the case with structs. when passing a variable of a struct type to a function, a copy of the contents of that struct is made and stored into the function's parameter. this gets us to the next question.
And, what if the passed struct contains an array as a member?
I always recommend trying things like these but anyway in this case the array member is passed by copy. why? because as said earlier, a copy of the contents of the struct is made and stored into the functions parameter. this includes array members because they are actually part of the struct itself.
of course you can manually pass an array by copy by making a copy and passing it maybe using a function like memcpy
from the standard library. execute man memcpy
for more on that!
update: this is of course unless the struct member is actually a pointer that is set to point to an array in which case you can modify the array through the struct even when passing it to a function. try:
struct S
{
char *str;
};
// some code
char str1[] = "hi";
struct S myS;
myS.str = str1;
foo(myS);
printf("%s\n", str1); // outputs "ai"
// some code
void foo(struct S anS)
{
anS.str[0] = 'a';
}