Your question is not very clear to me, but I assume that you perplexity is related to arrays.
In C the name of an array is it's address (a pointer to its first element). So if you pass an array to a function in reality you're passing the address of the very first element and no other information. No memory copy of the data is created. So you
don't have a copy and you
don't know the dimensions of the array. And if you use the 'sizeof' operatoor on the array name you'll get the size of a pointer (not the size of array).
The answer to your question in case of arrays is:
No, the function doesn't know what is the size of the parameter.
The case of other types of data is handled differently, but the function still doesn't know the dimension of the parameter.
Consider a structure. For structures passing data by reference or by value makes the difference.
In this case the compiler cannot allocate the structure on the calling stack frame (because this would create problems firstly with stack frames handling, then with memory access boundary), the compilers then, by common conventions, allocates a private copy of the structure someway (normally on stack memory using alloca()), then passing a pointer to that structure to the called function. The compiler handles the whole thing transparently as if the real data value was passed instead of a pointer to the copy, and anyway for the user accessing a private copy is equivalent to a passage by value.
For the sake of completeness, the compiler before to act checks the structure dimension and if it can fit in a basic type dimension pass the structure directly. I.e.
struct _tagMyStr
{
short a;
short b;
};
This struct made of 2 shorts can fit in one integer than it is passed directly on the stack (or register in 64bits __fastcall).