sizeof array clarification

匿名 (未验证) 提交于 2019-12-03 01:29:01

问题:

I am studying for a final tomorrow in C, and have a question regarding the sizeof operator.

Let's say the size of an int is 32 bits and a pointer is 64 bits.

If there were a function:

int foo (int zap[]) {     int a = sizeof(zap);     return a; } 

Because zap is a pointer, foo would return 8, as that's how many bytes are needed to store this particular pointer. However, with the following code:

int zip[] = { 0, 1, 2, 3, 4, 5 }; int i = sizeof(zip); 

i would be 6 * sizeof(int) = 6 * 4 = 24

Why is it that sizeof(zip) returns the number of elements times the size of each element, whereas sizeof(zap) returns the size of a pointer? Is it that the size of zap is unspecified, and zip is not? The compiler knows that zip is 6 elements, but doesn't have a clue as to how large zap may be.

回答1:

This is sort of an asymmetry in the C syntax. In C it's not possible to pass an array to a function, so when you use the array syntax in a function declaration for one of the parameters the compiler instead reads it as a pointer.

In C in most cases when you use an array in an expression the array is implicitly converted to a pointer to its first element and that is exactly what happens for example when you call a function. In the following code:

int bar[] = {1,2,3,4}; foo(bar); 

the array is converted to a pointer to the first element and that is what the function receives.

This rule of implict conversion is not however always applied. As you discovered for example the sizeof operator works on the array, and even & (address-of) operator works on the original array (i.e. sizeof(*&bar) == 4*sizeof(int)).

A function in C cannot recevive an array as parameter, it can only receive a pointer to the first element, or a pointer to an array... or you must wrap the array in a structure.

Even if you put a number between the brackets in the function declaration...

void foo(int x[4]) {     ... } 

that number is completely ignored by the compiler... that declaration for the compiler is totally equivalent to

void foo(int *x) {     ... } 

and for example even calling it passing an array with a different size will not trigger any error...

int tooshort[] = {1,2,3}; foo(tooshort);  /* Legal, even if probably wrong */ 

(actually a compiler MAY give a warning, but the code is perfectly legal C and must be accepted if the compiler follows the standard)

If you think that this rule about arrays when in function arguments is strange then I agree, but this is how the C language is defined.



回答2:

Because zip is an array and the compiler knows its size at compile-time. It just a case of using the same notation for two different things, something quite usual in C.

int foo (int zap[]) 

is completely equivalent to

int foo (int *zap) 

The compiler doesn't have any idea how big zap could be (so it leaves the task of finding out to the programmer).



回答3:

zip is a memory block of 6 * sizeof(int) so it has a size of 24 (on your architecture). zap (it could be also written as int *zap in your function declaration) however can point to any memory address and the compiler has no way of knowing how much space starting at this (or even containing this) address has been allocated.



回答4:

The size of zip is known at compile time and the size of zap is not. That is why you are getting the size of a pointer on sizeof(zap) and the size of the array on sizeof(zip).



回答5:

There are some situations wherearrays decay to pointers. Function calls is one of those.



回答6:

because it has been statically initialized with 6 elemens.



标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!