🚀 What is a Pointer (in simple terms)?
A pointer is a variable that stores the memory address of another variable.
🤔 Still confused? Let’s simplify:
Imagine your computer’s memory as a big hotel with rooms.
Each room has a number (called an address), and each room stores some value (like 10, 20, etc.).
When you declare a variable like
int x = 5;, you're booking a room in the hotel to store the value5.A pointer is like a note in your hand that remembers the room number where a specific value (like 5) is stored.
🧠 Analogy:
Variable = Value stored in a room
Pointer = Slip of paper that holds the room number
<div class="infographic-cptr">
<style>
.infographic-cptr {
--ink: #1a1a1a;
--ink-soft: #5c5c5c;
--paper: #ffffff;
--paper-alt: #f0ece4;
--accent: #2563eb;
--accent-soft:#e3ebfd;
--line: #ddd6c9;
--code-bg: #1e1e2e;
--code-text: #d4d4e0;
--warn: #b45309;
--warn-soft: #fdf0dc;
--ok: #1a7f4e;
--ok-soft: #e3f5ec;
}
.infographic-cptr[data-theme="dark"] {
--ink: #e8e6e1;
--ink-soft: #9a968c;
--paper: #121212;
--paper-alt: #1e1e26;
--accent: #5b8def;
--accent-soft:#202942;
--line: #2c313d;
--code-bg: #0d0d14;
--code-text: #d4d4e0;
--warn: #e0a458;
--warn-soft: #3a2c14;
--ok: #5cd6a0;
--ok-soft: #16342a;
}
.infographic-cptr {
box-sizing: border-box;
max-width: 760px;
margin: 0 auto;
background: var(--paper);
color: var(--ink);
font-family: 'Inter', -apple-system, sans-serif;
padding: 0 clamp(1rem, 4vw, 2.25rem) 1.25rem;
}
.infographic-cptr *, .infographic-cptr *::before, .infographic-cptr *::after {
box-sizing: border-box;
}
.infographic-cptr h1 {
font-family: 'Fraunces', Georgia, serif;
font-weight: 600;
font-size: clamp(1.4rem, 3.5vw, 1.9rem);
margin: 1.25rem 0 0.2rem;
text-align: center;
}
.infographic-cptr .subhead { color: var(--ink-soft); font-size: 0.85rem; margin-bottom: 1.4rem; text-align: center; }
.infographic-cptr h2 {
font-family: 'Fraunces', Georgia, serif;
font-weight: 600;
font-size: 1rem;
margin: 0 0 0.8rem;
color: var(--ink-soft);
}
.infographic-cptr section { margin-bottom: 2.4rem; }
.infographic-cptr section + section { border-top: 1px solid var(--line); padding-top: 1.8rem; }
/* ===== Scene 1: pointer to a variable ===== */
.infographic-cptr .scene1 {
position: relative;
display: flex;
align-items: center;
justify-content: center;
gap: 5rem;
padding: 2.2rem 1rem 1.6rem;
}
.infographic-cptr .mem-box {
position: relative;
text-align: center;
}
.infographic-cptr .mem-addr {
font-family: 'IBM Plex Mono', monospace;
font-size: 0.66rem;
color: var(--ink-soft);
margin-bottom: 0.3rem;
}
.infographic-cptr .mem-cell {
width: 6.5rem;
height: 3.4rem;
border: 2px solid var(--line);
border-radius: 10px;
background: var(--paper-alt);
display: flex;
align-items: center;
justify-content: center;
transition: border-color 0.3s, background 0.3s;
}
.infographic-cptr .mem-cell.is-linked { border-color: var(--accent); background: var(--accent-soft); }
.infographic-cptr .mem-cell.is-null { border-color: var(--warn); background: var(--warn-soft); }
.infographic-cptr .mem-cell input {
all: unset;
width: 4.5rem;
text-align: center;
font-family: 'IBM Plex Mono', monospace;
font-size: 1.05rem;
font-weight: 700;
color: var(--ink);
}
.infographic-cptr .mem-cell .ptr-content {
font-family: 'IBM Plex Mono', monospace;
font-size: 0.78rem;
font-weight: 700;
color: var(--accent);
}
.infographic-cptr .mem-cell.is-null .ptr-content { color: var(--warn); font-size: 0.85rem; }
.infographic-cptr .mem-name {
font-family: 'IBM Plex Mono', monospace;
font-size: 0.85rem;
font-weight: 700;
margin-top: 0.4rem;
color: var(--ink-soft);
}
.infographic-cptr .arrow-svg { position: absolute; top: 0; left: 0; width: 100%; height: 100%; pointer-events: none; overflow: visible; }
.infographic-cptr .arrow-path {
fill: none;
stroke: var(--accent);
stroke-width: 2.2;
stroke-dasharray: 200;
stroke-dashoffset: 200;
transition: stroke-dashoffset 0.5s ease, opacity 0.3s ease;
opacity: 0;
}
.infographic-cptr .arrow-path.is-visible { stroke-dashoffset: 0; opacity: 1; }
.infographic-cptr .arrow-head { fill: var(--accent); opacity: 0; transition: opacity 0.3s ease 0.3s; }
.infographic-cptr .arrow-head.is-visible { opacity: 1; }
.infographic-cptr .ctrl-row { display: flex; align-items: center; justify-content: center; gap: 0.6rem; flex-wrap: wrap; margin-bottom: 1.1rem; }
.infographic-cptr .ctrl-btn {
all: unset; cursor: pointer;
font-family: 'IBM Plex Mono', monospace;
font-size: 0.8rem; font-weight: 600;
padding: 0.42rem 0.9rem;
border-radius: 999px;
border: 1px solid var(--line);
background: var(--paper-alt);
color: var(--ink);
transition: border-color 0.2s;
}
.infographic-cptr .ctrl-btn:hover { border-color: var(--accent); }
.infographic-cptr .ctrl-btn.primary { background: var(--accent); color: #fff; border-color: var(--accent); }
.infographic-cptr .ctrl-btn.is-active { background: var(--accent); color: #fff; border-color: var(--accent); }
.infographic-cptr .deref-row {
display: flex;
align-items: center;
justify-content: center;
gap: 0.5rem;
font-family: 'IBM Plex Mono', monospace;
font-size: 0.95rem;
}
.infographic-cptr .deref-row input {
font-family: 'IBM Plex Mono', monospace;
font-size: 0.95rem;
padding: 0.3rem 0.5rem;
width: 4.5rem;
text-align: center;
border-radius: 6px;
border: 1px solid var(--line);
background: var(--paper);
color: var(--ink);
}
.infographic-cptr .deref-row input.is-locked { opacity: 0.4; background: var(--paper-alt); cursor: not-allowed; }
.infographic-cptr .crash-msg {
text-align: center;
font-size: 0.8rem;
color: var(--warn);
font-weight: 600;
min-height: 1.2rem;
margin-top: 0.5rem;
}
/* ===== Scene 2: pointer arithmetic ===== */
.infographic-cptr .arr-row { display: flex; gap: 0.5rem; justify-content: center; margin-top: 1.6rem; flex-wrap: wrap; }
.infographic-cptr .arr-cell { text-align: center; }
.infographic-cptr .arr-marker {
font-size: 1.1rem;
color: var(--accent);
height: 1.2rem;
transition: transform 0.3s ease;
}
.infographic-cptr .arr-marker.is-hidden { visibility: hidden; }
.infographic-cptr .arr-box {
width: 3.6rem;
height: 3rem;
display: flex;
align-items: center;
justify-content: center;
border: 2px solid var(--line);
border-radius: 8px;
background: var(--paper-alt);
font-family: 'IBM Plex Mono', monospace;
font-size: 1rem;
font-weight: 700;
transition: border-color 0.25s, background 0.25s;
}
.infographic-cptr .arr-box.is-current { border-color: var(--accent); background: var(--accent-soft); color: var(--accent); }
.infographic-cptr .arr-idx {
font-family: 'IBM Plex Mono', monospace;
font-size: 0.68rem;
color: var(--ink-soft);
margin-top: 0.25rem;
}
.infographic-cptr .readout-row {
display: flex;
justify-content: center;
gap: 1.5rem;
margin-top: 1.2rem;
font-family: 'IBM Plex Mono', monospace;
font-size: 0.85rem;
flex-wrap: wrap;
}
.infographic-cptr .readout-row strong { color: var(--accent); }
.infographic-cptr .takeaway { font-size: 0.82rem; color: var(--ink-soft); }
.infographic-cptr .takeaway strong { color: var(--ink); }
@media (prefers-reduced-motion: reduce) {
.infographic-cptr * { transition: none !important; }
}
</style>
<h1>👉 Pointers in C</h1>
<p class="subhead">A pointer is just a box that stores another box's address.</p>
<section>
<h2>& gets an address · * reads what's there</h2>
<div class="scene1">
<svg class="arrow-svg" id="arrow-svg">
<path class="arrow-path" id="arrow-path" d=""></path>
<polygon class="arrow-head" id="arrow-head" points=""></polygon>
</svg>
<div class="mem-box">
<div class="mem-addr">0x7ffe2000</div>
<div class="mem-cell is-null" id="p-cell">
<span class="ptr-content" id="p-content">? (garbage)</span>
</div>
<div class="mem-name">p</div>
</div>
<div class="mem-box">
<div class="mem-addr">0x7ffe2010</div>
<div class="mem-cell" id="x-cell">
<input type="number" id="x-input" value="42">
</div>
<div class="mem-name">x</div>
</div>
</div>
<div class="ctrl-row">
<button class="ctrl-btn primary" id="assign-btn">p = &x</button>
<button class="ctrl-btn" id="null-btn">p = NULL</button>
</div>
<div class="deref-row">
<span>*p =</span>
<input type="number" id="deref-input" value="" readonly class="is-locked">
</div>
<div class="crash-msg" id="crash-msg"></div>
</section>
<section>
<h2>p++ walks through memory</h2>
<div class="arr-row" id="arr-row"></div>
<div class="ctrl-row" style="margin-top:1rem;">
<button class="ctrl-btn" id="pminus-btn">p--</button>
<button class="ctrl-btn primary" id="pplus-btn">p++</button>
</div>
<div class="readout-row">
<span>p → arr[<strong id="ptr-idx">0</strong>]</span>
<span>*p = <strong id="ptr-val">10</strong></span>
<span>p = <strong id="ptr-addr">0x7ffe3000</strong></span>
</div>
</section>
<p class="takeaway"><strong>Same rule both scenes:</strong> a pointer never holds the value itself — only the address of a box that does.</p>
</div>
<script>
(function () {
const wrapper = document.currentScript.closest('.infographic-cptr')
|| document.querySelector('.infographic-cptr');
const bodyAttr = document.body.getAttribute('data-darkmode');
let dark;
if (bodyAttr === 'true') { dark = true; }
else if (bodyAttr === 'false') { dark = false; }
else {
const match = document.cookie.match(/(?:^|;\s*)darkMode=([^;]+)/);
dark = match ? match[1] === 'true' : false;
}
if (dark) wrapper.setAttribute('data-theme', 'dark');
function $(sel) { return wrapper.querySelector(sel); }
// ================= Scene 1 =================
const pCell = $('#p-cell');
const pContent = $('#p-content');
const xCell = $('#x-cell');
const xInput = $('#x-input');
const assignBtn = $('#assign-btn');
const nullBtn = $('#null-btn');
const derefInput = $('#deref-input');
const crashMsg = $('#crash-msg');
const arrowPath = $('#arrow-path');
const arrowHead = $('#arrow-head');
const scene1 = wrapper.querySelector('.scene1');
let linked = false;
function drawArrow() {
const svg = $('#arrow-svg');
const svgRect = svg.getBoundingClientRect();
const pRect = pCell.getBoundingClientRect();
const xRect = xCell.getBoundingClientRect();
const startX = pRect.right - svgRect.left;
const startY = pRect.top + pRect.height / 2 - svgRect.top;
const endX = xRect.left - svgRect.left - 10;
const endY = xRect.top + xRect.height / 2 - svgRect.top;
const midY = Math.min(startY, endY) - 40;
arrowPath.setAttribute('d', 'M' + startX + ',' + startY + ' C' + (startX + 40) + ',' + midY + ' ' + (endX - 40) + ',' + midY + ' ' + endX + ',' + endY);
arrowHead.setAttribute('points', (endX) + ',' + endY + ' ' + (endX - 10) + ',' + (endY - 6) + ' ' + (endX - 10) + ',' + (endY + 6));
}
function updateScene1() {
if (linked) {
pCell.classList.remove('is-null');
pCell.classList.add('is-linked');
pContent.textContent = '0x7ffe2010';
pContent.parentElement.classList.remove('is-null');
drawArrow();
arrowPath.classList.add('is-visible');
arrowHead.classList.add('is-visible');
derefInput.readOnly = false;
derefInput.classList.remove('is-locked');
derefInput.value = xInput.value;
crashMsg.textContent = '';
} else {
pCell.classList.remove('is-linked');
pCell.classList.add('is-null');
pContent.textContent = 'NULL';
arrowPath.classList.remove('is-visible');
arrowHead.classList.remove('is-visible');
derefInput.readOnly = true;
derefInput.classList.add('is-locked');
derefInput.value = '';
}
}
assignBtn.addEventListener('click', () => { linked = true; updateScene1(); });
nullBtn.addEventListener('click', () => { linked = false; updateScene1(); });
xInput.addEventListener('input', () => {
if (linked) derefInput.value = xInput.value;
});
derefInput.addEventListener('input', () => {
if (linked) xInput.value = derefInput.value;
});
derefInput.addEventListener('click', () => {
if (derefInput.readOnly) {
crashMsg.textContent = '💥 Segmentation fault — dereferencing NULL';
}
});
window.addEventListener('resize', () => { if (linked) drawArrow(); });
// initial: p is uninitialized garbage, no arrow
pContent.textContent = '? (garbage)';
// ================= Scene 2 =================
const arrRow = $('#arr-row');
const pplusBtn = $('#pplus-btn');
const pminusBtn = $('#pminus-btn');
const ptrIdxEl = $('#ptr-idx');
const ptrValEl = $('#ptr-val');
const ptrAddrEl = $('#ptr-addr');
const ARR = [10, 20, 30, 40, 50];
const BASE = 0x7ffe3000;
let ptrIdx = 0;
let cellEls = [];
let markerEls = [];
function renderArr() {
arrRow.innerHTML = '';
cellEls = [];
markerEls = [];
ARR.forEach((v, i) => {
const col = document.createElement('div');
col.className = 'arr-cell';
const marker = document.createElement('div');
marker.className = 'arr-marker is-hidden';
marker.textContent = '▼';
const box = document.createElement('div');
box.className = 'arr-box';
box.textContent = v;
const idx = document.createElement('div');
idx.className = 'arr-idx';
idx.textContent = 'arr[' + i + ']';
col.appendChild(marker);
col.appendChild(box);
col.appendChild(idx);
arrRow.appendChild(col);
cellEls.push(box);
markerEls.push(marker);
});
}
function updateScene2() {
cellEls.forEach((box, i) => box.classList.toggle('is-current', i === ptrIdx));
markerEls.forEach((m, i) => m.classList.toggle('is-hidden', i !== ptrIdx));
ptrIdxEl.textContent = ptrIdx;
ptrValEl.textContent = ARR[ptrIdx];
ptrAddrEl.textContent = '0x' + (BASE + ptrIdx * 4).toString(16);
pplusBtn.disabled = ptrIdx >= ARR.length - 1;
pminusBtn.disabled = ptrIdx <= 0;
}
pplusBtn.addEventListener('click', () => { if (ptrIdx < ARR.length - 1) { ptrIdx++; updateScene2(); } });
pminusBtn.addEventListener('click', () => { if (ptrIdx > 0) { ptrIdx--; updateScene2(); } });
renderArr();
updateScene2();
})();
</script>🔧 Pointer Declaration
👉 Syntax:
type *pointerName;type→ the data type of value the pointer will point to*→ declares a pointerpointerName→ name of the pointer variable
🧪 Example:
int *ptr; // ptr is a pointer to an integer
char *ch; // ch is a pointer to a character
float *f; // f is a pointer to a float🗺️ What is a Memory Address?
Your computer stores data in RAM (Random Access Memory).
Every variable gets a unique address.
🧪 Example:
int a = 10;
printf("%p", &a); // %p prints the memory address of aOutput: 0x7ffeebbdb22c (example address in hex)
Here:
&ameans “address of variablea”It might look strange (because it's hexadecimal), but it's just a room number in memory
🎯 Assigning Address to a Pointer
To store the address of a variable in a pointer, use the & (address-of) operator:
int x = 10;
int *ptr = &x;Now:
ptrstores the address of xptrgives you the value at that address, which is10
🔎 Code Example with Explanation
#include <stdio.h>
int main() {
int a = 5;
int *p = &a; // pointer p stores the address of a
printf("Value of a: %d\\n", a); // 5
printf("Address of a: %p\\n", &a); // e.g. 0x7ffd...
printf("Value of p (address): %p\\n", p); // same as &a
printf("Value at p (*p): %d\\n", *p); // 5
return 0;
}🧠 What's Happening Here:
pholds the address ofapmeans: “go to the address stored inpand get the value there”So
p == a
🪄 Visual Representation
Let's visualize:
int a = 10;
int *p = &a;Memory:
Address | Value | Variable |
|---|---|---|
1000 | 10 | a |
2000 | 1000 | p |
ais at memory location1000, value =10pis at2000, and holds the address1000pgoes to address1000→ gets value10
🔐 Pointer Terminology Summary
Term | Symbol | Meaning |
|---|---|---|
Address-of |
| Gives the memory address of a variable |
Dereferencing |
| Gives the value stored at a memory address |
Pointer Declaration |
| Declares a pointer variable |
❗ Why Pointers are Important in C
🔗 C uses call-by-value, so to change values inside functions, we need pointers
🧱 Enables dynamic memory allocation (
malloc,calloc, etc. We will study about this further )📦 Crucial for working with arrays, strings, structures
📬 Used in system-level and embedded programming
🧊 Real-World Use Case Analogy
Let’s say:
You have a friend named Raj who is holding a treasure (the value
10)You don’t know what Raj is holding, but someone gives you Raj’s home address (i.e., a pointer to Raj)
You go to his house (dereference the pointer) and ask him for the treasure — that’s what a pointer does!
❓ Common Beginner Confusions
Confusion | Clarification |
|---|---|
Is | No! |
Why use pointers if we can just use variables? | Because pointers let you modify values directly at memory addresses (e.g., inside functions), work with dynamic memory, and optimize performance. |
Is | No! Only |