"Arrays = pointers" * bloated mind *. Many years later: "In fact, they are not" the mind is bloated again "*

Context:

I programmed C on and off for about 2 years before I discovered that a[i] is just syntactic sugar for *(a + i) and therefore equivalent to * (i + a) and i[a] . My reality has been turned upside down, and many "AHA!" in the next few days of training and reading ("So, why arrays are always passed by reference!", etc.). Since then I have learned the equivalence of a pointer / array and kept it close to my heart, so imagine that it was a gross shock when I stumbled upon this thing called "Array decay". Here is a typical example:

the code:

 #include <stdio.h> int Length(int*); int main () { int arr[100]; printf("Length of array: %d\n",(int)(sizeof(arr)/sizeof(arr[0]))); printf("Length of array: %d\n",Length(arr)); return 0; } int Length(int arr[]) { return sizeof(arr)/sizeof(arr[0]); } 

Result:

 Length of array: 100 Length of array: 2 

Question:

So it turns out that C has some recognition of arrays after all! Basically, where an array is declared, the program can correctly report this size. Now I wonder how the syntax of the array is just the syntactic sugar for pointer operations (I previously assumed: all this). C actually has arrays, what are their limitations? An example shows that you can get their length as long as you are in the same function, what can you do for other interesting things? How far can you go before this error breaks up?

+2
c arrays
source share
4 answers

In the "old" C language, there are two operators that do not decay an array type: the sizeof operator and the unary & operator. sizeof evaluates the size of the entire array (not the size of the pointer), and & returns a pointer like a pointer to an array (and not like a pointer to a pointer). C99 added _Alignof , as Eric noted in the comments.

Another context is sometimes mentioned: initializing a char array with a string literal (i.e., a string literal does not break into a pointer).

You can also say this: in object contexts (AKA lvalue contexts) arrays retain their "massiveness", and in context contexts (AKA rvalue contexts) they immediately break up into pointers.

PS . As a historical note: one of the ancestors of the C language - the B language - actually implemented arrays as physical pointers, which means that each array in B was actually a pointer pointing to an independently allocated block of memory. It was originally supposed that this implementation would transfer to C. However, C had to have struct types. And arrays in style B created unnecessary complications with the presence of arrays as part of struct objects. They would make the initialization of struct objects non-trivial, the struct object would not be copied using raw memcpy , etc. This was deemed unacceptable in C. Thus, arrays were reworked into their current form. C arrays are not pointers, but they still emulate the behavior of pointers as their grandparents from the B language, which often confuses people learning C.

(see here http://cm.bell-labs.com/cm/cs/who/dmr/chist.html for the full story.)

+6
source share

The size of the array is "lost" when it is passed to the function. As you noticed, sizeof , being the compilation time, sees the "real" size. This may work because sizeof not a function at all, as you can demonstrate using it without parentheses (e.g. sizeof arr , although the strange sizeof some_type not legal C).

+3
source share

Saying that arrays and pointers are "equivalent" means that they are not identical or even interchangeable. This means that it is pointer arithmetic and array indexing, equivalent in C, pointers and arrays, are different.

A reference to an array-of-T object that appears in an expression splits into a pointer to its first element; the type of the resulting pointer is a pointer to T. That is, whenever the array appears in the expression, the compiler implicitly generates a pointer to the first element of the array, as if the programmer wrote &a[0] .

sizeof or & operator are exceptions to this rule.

I also recommend Expert C Programming , which uses an entire chapter to explain the difference and confusion in pointers and arrays.

+2
source share

Declaring an array as a local or global variable, where it differs from pointers. int arr[100]; allocates 400 bytes of space, while int *p allocates only 4. You can use the local variable int *p similarly to an array if you malloc some space for it, for example

 int *p = (int *)malloc(100 * sizeof(int)); 

You must also remember that freeing this memory later, of course. You can also freely pass a local variable declared as int arr[100] , to a function whose formal parameter is of type int * . When it comes to function arguments, arrays and pointers are a bit more equivalent.

 i[a] 

No, this will not work if I am int. But the other three forms are equivalent.

-one
source share

All Articles