So, why the sizeof(array) in function length returns the pointer size of array? But in function main, it works.
And, how should I modify the length function to get an array's length?
回答1:
A special C rule says that for function parameters, array types are adjusted to pointer types. That means:
int length(int array[]);
is equivalent to
int length(int *array);
So when you compute the sizeof the array you are actually computing the size of the pointer.
(C99, 6.7.5.3p7) "A declaration of a parameter as "array of type" shall be adjusted to "qualified pointer to type", where the type qualifiers (if any) are those specified within the [ and ] of the array type derivation."
回答2:
The array decays into a pointer when you pass it into a function.
回答3:
As the other answerers have noted, a function declared to take an array is compiled the same as if it took a pointer.
The most common way I've seen to do your length method is with a #define, but if you play tricks with templates, you can make your function work.
With your array of length 4, this gets compiled as a method that takes an array of length 4, and returns a static 4. This also has the advantage that if you try to pass something that isn't an array, the compiler will give an error, whereas the #define method doesn't.
int* foo = array; printf("%d\n", length(foo));// error C2784: 'int length(int (&)[_Size])' : could not deduce template// argument for 'int (&)[_Size]' from 'int *'// test.cpp(56) : see declaration of 'length'
回答4:
In the main program, the compiler knows the length of the array. In the subroutine, it doesn't. In particular, in a subroutine, a parameter of type int[] is identical to a parameter of type int *. In the main program, on the other hand, array has type int[4]. (You can test this by trying to assign another value to array in side main. The compiler will complain.)
回答5:
C does not store runtime metadata about the size of an array with the variable. You will have to store that yourself somewhere.
A variable of type int[] in the context of your method length is just a pointer to a block of memory. That's why the size is the same as the size of any other pointer on your system.
When sizeof has access to the array at compile-time (as in your main function) it will instead return the number of bytes occupied by the array.
回答6:
If you want length to be aware of the true size of the passed in array, that information has to be passed in, as everyone says. But it is possible for it to receive a reference to the array with the information also built-in:
I don't know what good that actually does you, though, since the size is already provided in the first place. But you see that the sizeof operator works as you wanted it to in this case.
回答7:
Because the variable array inside length is not the same as the one outside. You have to keep the sizeof(array) / sizeof(int) in the main function.
回答8:
To modify your code so that length can get the array's length, turn it into a macro:
#define length(x)(sizeof(x)/sizeof(*x))
For your code sample, this will behave as you expect.
Note that this will only work on statically-allocated arrays, and only when called using the original array (it won't work when using a pointer to the array). This is because when you write sizeof(x) where x is a pointer to an array, the compiler interprets it literally. It doesn't have any way of mapping x back to the array that it points to before evaluating the sizeof.