Intermediate · Pointers · topic 24 of 60 · 25 min
Pointer arithmetic
Explanation
Moving by elements, not bytes
int a[4] = {10, 20, 30, 40};
int *p = a; /* p = 0x1000 */
p → 0x1000 *p → 10
p + 1 → 0x1004 *(p + 1) → 20 (moved sizeof(int) = 4 bytes)
p + 3 → 0x100C *(p + 3) → 40
char *c = (char *) a; /* the same memory seen as bytes */
c + 1 → 0x1001 (moved 1 byte)
double d[3]; double *q = d; /* q = 0x2000 */
q + 1 → 0x2008 (moved sizeof(double) = 8 bytes)Increment, subtraction and comparison
int marks[5] = {78, 85, 91, 66, 72};
int *first = &marks[0];
int *last = &marks[4];
printf("%td\n", last - first); /* 4: elements between them (%td prints ptrdiff_t) */
for (int *p = marks; p < marks + 5; p++) { /* comparing pointers into the same array */
printf("%d ", *p);
}
int *p = marks;
printf("%d\n", *p++); /* 78: uses *p, then moves p (postfix ++ binds tighter than *) */
printf("%d\n", *p); /* 85 */The one-past-the-end rule
C lets a pointer point exactly one element past the end of an array (marks + 5 above), so loops like p < marks + 5 are legal. Dereferencing that pointer is undefined behaviour, and so is computing a pointer further outside the array (marks + 6, or marks - 1), even without dereferencing it.
Precedence traps
| Expression | Means |
|---|---|
| *p++ | *(p++): read the current element, then move p |
| (*p)++ | increment the VALUE p points to |
| *++p | move p first, then read |
| ++*p | increment the value, then read it |
What you cannot do
- Add two pointers (p + q has no meaning; subtracting them does).
- Subtract or compare pointers into DIFFERENT arrays (undefined).
- Do arithmetic on void * in standard C (GCC allows it as an extension, treating the size as 1; do not rely on it). Cast to char * or unsigned char * for byte-wise work.
- Multiply or divide pointers.
Need help?
Stuck on a word or an idea? Search this course, or every course, and jump straight to the explanation or a worked question.
Try:
Watch the lesson
Pointer arithmetic · 1/6
In this lesson you will move pointers with arithmetic.
Prefer a video by a teacher? Find free videos on “c pointer arithmetic explained increment subtraction one past the end” on YouTube ↗
In real life: Scanning a network packet
A network tool reads a packet as a buffer of bytes and uses an unsigned char pointer to step through its fields: a 1-byte type, a 2-byte length, then the payload. Pointer arithmetic on unsigned char moves exactly one byte at a time, and the code checks the remaining length before every read.
int parse_packet(const unsigned char *buf, size_t len) {
const unsigned char *p = buf, *end = buf + len;
if (end - p < 3) return -1; /* need type + 2 length bytes */
unsigned type = p[0];
unsigned payload_len = (unsigned)(p[1] << 8 | p[2]); /* big-endian 16-bit length */
p += 3;
if ((size_t)(end - p) < payload_len) return -1; /* never read past the buffer */
printf("type %u, %u payload bytes\n", type, payload_len);
return 0;
}Practice (0/3 done)
int a[5]; int *p = &a[1], *q = &a[4]; What is q - p?
What does this print? int a[] = {1, 2, 3}; int *p = a; int x = *p++; int y = (*p)++; printf("%d %d %d\n", x, y, a[1]);
Without using any [ ] subscripts, write void reverse(int *start, int *end) that reverses an array in place using two pointers that move toward each other (end points one past the last element). Draw the memory diagram for reversing {1, 2, 3, 4}.
Quick quiz
Read more (free)
Related help
Before this, learn
This topic builds on these. If something here feels new, open them first.
Related topics
- NULL, dangling pointers and pointers to pointersPointers · same module
- Pointers and functionsPointers · same module
- Operators and expressionsJava Programming (Core to Spring Boot) · Getting started with Java
- ArraysFunctions and arrays
- Pointers, the stack and the heapC++ Programming (modern C++ and DSA) · References, pointers, arrays and strings
- Pointers without fearGo Programming (backend and cloud) · Pointers, interfaces and errors
Questions people ask about this
Open a question to see the answer and why. The first ones are this topic's own quiz, so try the quiz above before you peek.
If double *q holds 0x2000, what is q + 2?
Answer: 0x2010
2 × 8 bytes = 16 = 0x10.
Which printf format prints a ptrdiff_t?
Answer: %td
t is the length modifier for ptrdiff_t.
Is it legal to compute a + n for int a[n]?
Answer: Yes, one past the end may be computed but not dereferenced
The one-past-the-end rule.
What does (*p)++ do?
Answer: Increments the value p points to
The brackets apply ++ to the value.
How should a pointer be printed with printf?Related
What is 17 / 5 in Java with ints?Related
Where does an array NOT decay to a pointer?Related
Which expression is undefined behaviour?Related
Pass the quiz (60% or more) or mark this topic as done when you are ready.
Your progress is saved on this device only.
Next steps
- 1 more topic in “Pointers” before its exam: NULL, dangling pointers and pointers to pointers.
- Module 5 exam: Pointers · 12 questions · 25 min, without help. 5 topics of this module still to finish first.
- Then the next module, Dynamic memory. 60 topics left in the course before the final exam.