With a solid pointer baseline from part 8, we can now connect arrays and pointers. In most expressions, an array name acts like the address of its first element. That is why you need pointers to understand arrays and arrays to see pointers in action.
New Terms in This Chapter
- Array Decay: The conversion of an array name into a pointer to its first element within an expression
- Pointer Arithmetic: Adding or subtracting integers from a pointer to move to neighboring elements
- Array Parameter: A function parameter that looks like an array but actually receives a pointer
- Length Information: The explicit number of elements you must pass along to process an array safely
Key Ideas
Study Notes
- Time: 60–70 minutes
- Prep: experience looping over arrays and declaring/dereferencing pointers
- Goal: describe how array names relate to pointers and pass arrays to functions safely
Keep these four ideas in mind:
- Array names act like the address of the first element in many expressions.
arr[i]and*(arr + i)access the same element.- Pointer arithmetic moves in units of the underlying data type.
- Always pass length information along with an array when calling functions.
Follow Along with Code
Comparing an Array Name to the First Element's Address
#include <stdio.h>
int main(void) {
int numbers[3] = {10, 20, 30};
printf("numbers = %p\n", (void *)numbers);
printf("&numbers[0] = %p\n", (void *)&numbers[0]);
printf("sizeof(numbers) = %zu\n", sizeof(numbers));
printf("sizeof(&numbers[0]) = %zu\n", sizeof(&numbers[0]));
return 0;
}
The printed addresses usually match, but note the difference in sizes. sizeof(numbers) is the size of the entire array, while sizeof(&numbers[0]) is just the size of a pointer. In other words, an array name is not itself a pointer, even though it decays to a pointer in many expressions.
arr[i] vs. *(arr + i)
#include <stdio.h>
int main(void) {
int numbers[4] = {3, 6, 9, 12};
int i;
for (i = 0; i < 4; i++) {
printf("numbers[%d] = %d\n", i, numbers[i]);
printf("*(numbers + %d) = %d\n", i, *(numbers + i));
}
return 0;
}
numbers + i points to the address of element i, and *(numbers + i) reads the value stored there. That is why the subscript operator and pointer arithmetic are two views of the same access pattern.
Pointer Arithmetic Respects the Element Size
#include <stdio.h>
int main(void) {
int values[3] = {100, 200, 300};
int *ptr = values;
printf("ptr = %p\n", (void *)ptr);
printf("ptr + 1 = %p\n", (void *)(ptr + 1));
printf("*(ptr + 1) = %d\n", *(ptr + 1));
return 0;
}
ptr + 1 does not simply add 1 to the numeric address—it skips ahead by the size of one int. Pointer arithmetic only makes sense while you stay within the same array.
Passing an Array to a Function
When you pass an array as an argument, the function effectively receives a pointer.
#include <stdio.h>
void print_scores(int scores[], int length) {
int i;
for (i = 0; i < length; i++) {
printf("scores[%d] = %d\n", i, scores[i]);
}
}
int main(void) {
int scores[4] = {95, 82, 74, 63};
print_scores(scores, 4);
return 0;
}
Although the parameter is written as scores[], the function only knows the address of the first element. That is why it needs the length as a second argument. This is one of the most important C habits: when you pass an array to a function, pass its length too.
Read-Only Array Parameters
Use const when the function will not modify the array.
#include <stdio.h>
void print_total(const int numbers[], int length) {
int i;
int total = 0;
for (i = 0; i < length; i++) {
total += numbers[i];
}
printf("total = %d\n", total);
}
int main(void) {
int numbers[3] = {5, 10, 15};
print_total(numbers, 3);
return 0;
}
const documents the fact that the function will only read the data. It does not magically supply the length, so you still have to pass that separately.
Practical Example: Finding the Highest Score
#include <stdio.h>
int find_max(const int values[], int length) {
int i;
int max = values[0];
for (i = 1; i < length; i++) {
if (values[i] > max) {
max = values[i];
}
}
return max;
}
int main(void) {
int scores[5] = {72, 88, 91, 67, 85};
printf("max = %d\n", find_max(scores, 5));
return 0;
}
This example passes an array into a function, combines loops and conditionals, and returns a meaningful result. It shows how the topics from earlier chapters line up in one short program.
Why It Matters
You need to understand the array–pointer relationship to reason about function arguments, string handling, and dynamic memory. Without that connection, later C topics feel disconnected.
Remember these four points:
- Array names usually behave like the address of the first element.
- Brackets and pointer arithmetic are two equivalent ways to reach an element.
- Always send length information along with an array.
- Use
constwhen a function should only read from the array.
Practice in CodeSandbox
The sandbox below uses CodeSandbox's Universal starter. For C, the key learning loop is still compile and run in the terminal, so recreate the lesson code as a source file and repeat that cycle directly.
💬 댓글
이 글에 대한 의견을 남겨주세요