C arrays, strings and functions are tied together by one idea: an array name decays to a pointer to its first element. A C string is simply a char array ending in a null terminator '\0'. And because C passes by value, passing an array actually passes that decayed pointer — which has real consequences for things like sizeof.
Arrays decay to pointers; strings are null-terminated
An array name used in most expressions becomes the address of its first element. A string literal "hi" is stored as {'h','i','\0'} — the '\0' marks the end, which is how functions like strlen know where to stop.
Strings are char arrays
char s[] = "hi"; // actually {'h','i','\0'} — 3 bytes
printf("%lu", strlen(s)); // 2 (counts up to, not including, '\0')
printf("%lu", sizeof(s)); // 3 (includes the terminator)sizeof inside a function differs
void f(int a[]) {
// here 'a' is really a pointer, so sizeof(a) is the POINTER size (e.g. 8)
printf("%lu", sizeof(a));
}
int main(void) {
int arr[10];
printf("%lu", sizeof(arr)); // 40 = 10 * 4 (full array, in main)
f(arr);
}⚡ The edge
- An array name is the address of its first element, so arr[i] is exactly *(arr + i). When you pass an array to a function, you pass that pointer — the function can't tell the original length.
- sizeof on an array gives the whole array's bytes; on a pointer it gives the pointer's size. That's why sizeof inside a function (where the parameter is a pointer) differs from sizeof on the real array — a favourite trick question.
Worked example
Why is sizeof different on an array in main vs inside a function?
- In main, arr is the actual array, so sizeof(arr) is the total bytes (elements × element size).
- When passed to a function, the array decays to a pointer to its first element.
- Inside the function the parameter is a pointer, so sizeof gives the pointer's size, not the array's — you must pass the length separately.
Answer: In main sizeof sees the whole array; inside a function the parameter is a pointer, so sizeof gives the pointer size.
Worked example
How does strlen know where a string ends?
- C strings are terminated by a null character '\0'.
- strlen walks from the start, counting characters until it hits '\0'.
- It returns that count — not including the terminator. A missing '\0' makes strlen read past the buffer (a bug).
Answer: It counts characters until the null terminator '\0'; the terminator marks the end and isn't counted.
⚠ Watch out
- Off-by-one with the null terminator: a string of n characters needs n+1 bytes.
- C does no bounds checking — writing past an array's end is undefined behaviour (buffer overflow).
- sizeof vs strlen: sizeof gives the buffer's bytes; strlen counts characters up to '\0'.