C makes arrays and pointers inseparable. You cannot write effective code without understanding their relationship. It takes time to master. The payoff is immediate control over memory.
Consider a basic setup. You declare two integer arrays of size ten.
Compile this. It fails. You cannot assign one array to another using the equals sign. C does not support bulk copying via assignment operators. To copy a into b, you must loop through every element.
You could compress that loop into a single line with a comma operator, but readability suffers. The standard approach is to use memcpy from string.h. It handles the byte-level copy efficiently.
The failure of b=a reveals a fundamental rule. In C, array variables are not arrays. They are fixed pointers. a and b are permanent identifiers for the starting address of their respective memory blocks. a points to a[0]. b points to b[0]. These addresses are immutable. You cannot redirect a variable name to a different memory location. That is why the assignment fails. The compiler treats the array name as a constant pointer.
Since the name is effectively a pointer, you can use pointer arithmetic to access data. This is where the syntax becomes powerful.
Here, p is a pointer variable. You can assign the address of array a to p. The statement p=a copies the address. Now p holds the same value as the array name a. Dereferencing p with *p retrieves the first element. The output is zero.
This distinction matters because pointer variables can be changed. You can make p point to a[1] or a[5] using arithmetic. The array name itself remains stuck at the start. This flexibility allows functions to iterate through memory without copying large data structures. It is the backbone of low-level performance in C.
Understanding this link prevents subtle bugs. It explains why some functions accept pointers instead of array syntax. It clarifies memory layout. Ignore it, and you will struggle with segmentation faults or unintended data overwrites. Learn it, and you see exactly what the machine is doing.
The syntax may feel unnatural at first. The double meaning of brackets and asterisks confuses beginners. But once the model clicks, the abstraction vanishes. You are left with addresses and values. Nothing more.
Is it worth the mental effort? The code becomes faster. The memory usage drops. You gain direct access to hardware-level operations. Most C programs rely
You can assign an array variable directly to a pointer because, under the hood, they are essentially the same thing.
p=a; works not because of magic, but because a decays into a pointer. Specifically, it points to the memory address of the array’s first element (index 0). Since that element is an integer, a acts as a pointer to a single int. Declaring p as an integer pointer and setting it equal to a is just letting two variables share the same address. You could write p=&a[0]; instead. The result is identical.
Once p is hooked up to the start of a, you gain mobility. Array names like a are constants; they are fixed addresses that cannot change. Pointers like p are different. You can move them around using pointer arithmetic.
This is where C gets clever.
When you write p++;, the compiler doesn’t just add one byte to the address. It knows p points to an integer. It adds sizeof(int) bytes instead, landing exactly on the next element. If p pointed to a structure 100 bytes long, p++ would jump 100 bytes forward. C handles the math. You just move the pointer.
Copying Arrays Without Indexes
You can copy one array into another using these pointers. Instead of a standard loop with indexes:
You can use pointers:
It’s verbose. You can compress it.
Or collapse it into a single line.
The operator precedence here is doing heavy lifting. * has higher precedence than ++, but the post-increment happens after the value is fetched. So *p++ fetches the current value, then moves the pointer. *q++ does the same for the destination. The assignment happens in between. It’s compact. It’s fast. It’s also easy to misread if you aren’t paying attention.
The Danger Zone
What happens if you push p or q past the end of the array?
C doesn’t stop you.
The compiler assumes you know what you are doing. It will keep incrementing the pointers, copying data into memory that doesn’t belong to the array. You might overwrite other variables. You might corrupt the stack. You might crash the program later, somewhere unrelated to the bug.
This is why bounds checking is manual in C. The language trusts you. When you step out of line, you pay the price.
Passing Arrays to Functions
You can pass arrays to functions in two ways. They look different but behave similarly.
Consider a function that prints an array:
Or the pointer version:
The nia parameter (number in array) is mandatory. Arrays in C don’t carry their size with them. The function needs to know when to stop.
In both cases, you are passing a pointer to the start of the array, not






































