Array size determination

I am studying the final tomorrow in C and asking a question regarding the sizeof operator.

Suppose the int size is 32 bits and the pointer is 64 .

If there was a function:

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

Since zap is a pointer, foo returns 8 , since this is the number of bytes needed to store this particular pointer. However, with the following code:

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

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

Why does this mean that sizeof(zip) returns the number of elements times the size of each element, while sizeof(zap) returns the size of the pointer? Is it that the zap size is not specified, but the zip not? The compiler knows that zip is 6 elements, but has no idea how large zap .

+8
c
source share
6 answers

This is a kind of asymmetry in the C syntax. It is not possible to pass an array to a function in C, 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 this 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 this is what the function receives.

However, this implication conversion rule does not always apply. As you find, for example, the sizeof operator works with an array, and even the & (address-of) operator works with the original array (i.e. sizeof(*&bar) == 4*sizeof(int) ).

A function in C cannot receive an array as a 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]) { ... } 

this number is completely ignored by the compiler ... this declaration to the compiler is completely equivalent

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

and, for example, even calling it when passing an array with a different size does not cause any error ...

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

(in fact, the compiler MAY give a warning, but the code is completely legal C and should be accepted if the compiler follows the standard)

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

+8
source share

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

 int foo (int zap[]) 

completely equivalent

 int foo (int *zap) 

The compiler has no idea how big the zap can be (so it leaves the programmer with a search task).

+2
source share

zip is a 6 * sizeof(int) memory block, so it has a size of 24 (according to your architecture). zap (it can also be written as int *zap in the declaration of your function), however, it can point to any memory address, and the compiler does not know how much space has been allocated starting from this (or even containing this) address.

+2
source share

The zip size is known at compile time, but the zap size is not. This is why you get the size of the pointer to sizeof(zap) and the size of the array to sizeof(zip) .

0
source share

There are some situations where markers disappear. Calling functions is one of them.

0
source share

since it was statically initialized with six elements.

-one
source share

All Articles