Need Help or More Information?
Questions about this free C programming course, embedded C training or career guidance? Get in touch.
Pointer Comparison in C
Free C tutorial: equality, ordering, null checks and two-pointer loops explained with working code.
Pointer comparison in C is the tool that tells a loop where to stop, a driver whether a handle is valid, and a parser whether it has run out of buffer. In this lecture of our free C programming course you will learn which comparisons are always safe, which ones are only valid inside one array, and how embedded C programming uses them in real code. Every example is original and comes with expected output.
What You Will Learn
- That pointer comparison compares addresses, not stored values
- Which comparison operators are valid for which pointer combinations
- Why ordering pointers from different objects is undefined behaviour
- How to use null checks, end pointers and search functions that return pointers
- How a two-pointer loop reverses an array in place
Prerequisites
- Pointer arithmetic and increment from the previous lectures
- Arrays and loops in C
- Basic function definitions with pointer parameters
What Pointer Comparison in C Really Compares
When you compare two pointers you are comparing addresses, not the values stored at those addresses. This single sentence clears up most beginner bugs. Two pointers are equal only when they hold the same address, or when both are null.
C provides six relational operators and they split into two groups with different rules. Equality (== and !=) is broadly allowed. Ordering (<, <=, >, >=) is only meaningful inside one array.
| Name | Address | Value | Pointer to it |
|---|---|---|---|
| x | 0x3000 | 5 | px holds 0x3000 |
| y | 0x3004 | 5 | py holds 0x3004 |
Here *px == *py is true because both values are 5, but px == py is false because the addresses differ.
When Pointer Comparison Is Valid
| Comparison | Allowed when | Result means |
|---|---|---|
p == q, p != q | same type, or either is null, or one is void * | same address or not |
p == NULL, !p | any pointer | pointer is null or not |
p < q, p > q, p <= q, p >= q | both point into the same array (or one past its end) | earlier or later element |
Ordering unrelated pointers is undefined
Using < or > on pointers to different objects is undefined behaviour in standard C. It may look fine on a flat memory model, but it can break on segmented or tagged architectures and with aggressive optimisation. Use equality when the pointers might belong to different objects.
Hands-On Program: Search, Compare, Reverse
Save this as ptr_cmp.c. It finds the largest sample using <, shows the difference between comparing addresses and comparing values, tests against null, returns a pointer from a search function, and finally reverses the array in place using two pointers that move towards each other.
#include <stdio.h>
#include <stddef.h>
static const int *find(const int *begin, const int *end, int key)
{
for (const int *p = begin; p < end; p++)
if (*p == key)
return p;
return NULL;
}
int main(void)
{
int samples[6] = {12, 48, 7, 93, 31, 60};
int *begin = samples;
int *end = samples + 6;
int *p, *max = samples;
for (p = begin; p < end; p++)
if (*p > *max)
max = p;
printf("largest %d at index %td\n", *max, max - samples);
int *a = &samples[2];
int *b = samples + 2;
printf("a == b : %d\n", a == b);
int x = 5, y = 5;
int *px = &x, *py = &y;
printf("px == py : %d (same value, different variables)\n", px == py);
printf("*px == *py : %d\n", *px == *py);
int *none = NULL;
printf("none == NULL : %d\n", none == NULL);
printf("!none : %d\n", !none);
const int *hit = find(begin, end, 31);
if (hit)
printf("31 found at index %td\n", hit - samples);
hit = find(begin, end, 99);
printf("99 found : %s\n", hit ? "yes" : "no");
int *lo = samples, *hi = samples + 5;
while (lo < hi) {
int t = *lo; *lo = *hi; *hi = t;
lo++; hi--;
}
for (p = begin; p < end; p++)
printf("%d ", *p);
printf("\n");
return 0;
}
gcc -std=c11 -Wall -Wextra -o ptr_cmp ptr_cmp.c
./ptr_cmp
Expected output:
largest 93 at index 3
a == b : 1
px == py : 0 (same value, different variables)
*px == *py : 1
none == NULL : 1
!none : 1
31 found at index 4
99 found : no
60 31 93 7 48 12
Walking through the output
- The loop condition
p < endstops after the last element, becauseendpoints one past it. The largest sample, 93, sits at index 3. a == bprints 1 because&samples[2]andsamples + 2are the same address written two ways.px == pyprints 0 while*px == *pyprints 1: equal values, different addresses.none == NULLand!noneboth print 1. A null pointer is false in a condition.- The
findfunction returns a pointer to the match orNULL. Key 31 is at index 4, and key 99 is not found. - The final line shows the array reversed: the pair
loandhiswap and meet in the middle, which is why the loop test islo < hi.
Pointer Comparison in C for Embedded Programming
- Loop bounds: iterate with
p < endinstead of tracking an index and a length. - Ring buffers: compare head and tail to detect empty, and compare a moving pointer against the buffer end to wrap around.
- Null checks: always test a handle or a freshly allocated block before touching it.
- Sentinel returns: a search function returns a pointer or
NULLso the caller can tell found from not found. - Overflow guards: before writing, check that
dst + len <= buffer_end, being careful that the sum itself stays inside the array.
Pointer Comparison in C: Gotchas Worth Knowing
The find function in the sample takes const int * parameters because it only reads the data. This is a small habit with a large payoff: the compiler will stop you from accidentally modifying data you promised only to inspect, and callers can pass both writable and read-only arrays.
Another detail is the loop for (p = begin; p < end; p++). It never dereferences end. The end pointer is only ever compared, which is exactly what the language permits for the one-past-the-end address.
Common Mistakes in Pointer Comparison in C
- Comparing
p == qwhen the intent was to compare*p == *q. - Using
<and>on pointers that belong to different arrays. - Forgetting a null check before dereferencing a returned pointer.
- Dereferencing the end pointer instead of only comparing against it.
- Writing
if (p = NULL)with a single equals sign.
Best Practices for Embedded C Programming
- Keep pointer comparison in C simple: return a pointer or
NULLfrom search functions and document that contract. - Mark read-only pointer parameters with
const. - Use an end pointer rather than a separate length in simple loops.
- Write
if (p == NULL)orif (!p)consistently across the code base. - Turn on compiler warnings so accidental assignment inside a condition is flagged.
Key Takeaways
- Pointer comparison in C works on addresses: equality compares addresses; two pointers are equal if they hold the same address or are both null.
- Relational operators are only meaningful for pointers into the same array.
- A null pointer is false in a condition.
- The one-past-the-end pointer may be compared but never dereferenced.
- Two pointers moving towards each other make a neat in-place reversal.
Conclusion
Pointer comparison in C is simple once you separate address from value and equality from ordering. Equality is always safe between compatible pointers, ordering belongs inside a single array, and null checks belong in front of every dereference of an unknown pointer.
Next in this free embedded C course we move one level up and meet the pointer to pointer, which unlocks functions that can change the pointer you pass them.
Frequently Asked Questions
How do you compare two pointers in C?
Use == and != to check whether they hold the same address. Use <, >, <= and >= only when both point into the same array.
Does p == q compare the values they point to?
No. It compares the addresses. To compare the pointed-to values, dereference both: *p == *q.
Can I compare a pointer with NULL?
Yes. Any pointer can be compared with NULL, and a null pointer evaluates as false in a condition.
Is comparing pointers from different arrays with < allowed?
Standard C leaves it undefined. Use equality instead, or make sure both pointers point into the same array.
What is a one-past-the-end pointer?
It is the address just after the last element of an array. You may form it and compare against it, but you must never dereference it.
Why should search functions return a pointer?
It lets the caller learn both whether the item exists and where it is, using NULL for not found.
Where will I use pointer comparison in firmware?
In loop bounds, ring buffer wrap-around, null checks on handles and bounds checks before writing into a buffer.
Build Real Embedded C Skills for Free
Move on to the next lecture of our free C programming course and meet the pointer to pointer.
Need Help or More Information?
Questions about this free C programming course, embedded C training or career guidance? Get in touch.

2 Comments