Array Fundamentals
Declaration, indexing, fixed size, no bounds checking, decay on function call.
Eight pieces on the array as C actually implements it: declaration, indexing, a size that's fixed the moment it's declared, no bounds checking at all, and decay the instant it's passed to a function.
int arr[5]; /* uninitialized — garbage until set */
int arr2[5] = {1, 2, 3, 4, 5}; /* fully initialized */
int arr3[] = {1, 2, 3}; /* size inferred as 3 */
arr[0] = 10; /* zero-indexed like everything else in C */The size is baked in at declaration and can't grow or shrink afterward — there's no arr.append() equivalent. And there's no bounds checking whatsoever: arr[10] on a 5-element array compiles and runs, reading or writing whatever memory happens to be sitting past the end. It's undefined behavior, not a caught error.
Decay on function call
void print_size(int arr[]) {
printf("%zu\n", sizeof(arr)); /* prints 8 — sizeof(int*), not the array size! */
}
int main(void) {
int arr[10];
printf("%zu\n", sizeof(arr)); /* prints 40 — this one's the real array size */
print_size(arr);
return 0;
}The sizeof(arr) / sizeof(arr[0]) trick for array length only works in the exact scope where the array was declared. The moment it's passed into a function, it decays to a plain pointer, and sizeof on a parameter just measures the pointer — which is why array-taking functions always need the length passed in separately.
Notes from readers
Comments — via GitHub