Using pointers with structures allows you to:
π Efficiently pass structures to functions
πΎ Access and modify structure data using memory addresses
π Save memory by avoiding large data copies
π§© First, Letβs Recall a Structure Example:
struct Student {
int id;
char name[50];
float marks;
};Now letβs go step by step into using pointers to this structure.
π§· Declaring a Pointer to Structure
You declare a pointer to a structure just like other pointers:
struct Student s1;
struct Student *ptr;
ptr = &s1; // assign address of s1 to ptrNow, ptr holds the address of the structure s1.
π οΈ Accessing Structure Members Using Pointer
πΉ Using (*ptr).member
(*ptr).id = 101;πΉ This says: Go to where ptr points, then access .id
πΉ Using ptr->member (Preferred shortcut)
ptr->id = 101β This is the most common and cleanest syntax.
ptr-> means: "Go to what the pointer points to, then access the member"
<div class="infographic-cstructptr">
<style>
.infographic-cstructptr {
--ink: #1a1a1a;
--ink-soft: #5c5c5c;
--paper: #ffffff;
--paper-alt: #f0ece4;
--accent: #2563eb;
--accent-soft:#e3ebfd;
--line: #ddd6c9;
--code-bg: #1e1e2e;
--code-text: #d4d4e0;
--syn-keyword: #c586c0;
--syn-func: #dcdcaa;
--syn-string: #ce9178;
--syn-comment: #6a9955;
}
.infographic-cstructptr[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;
}
.infographic-cstructptr {
box-sizing: border-box;
max-width: 880px;
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-cstructptr *, .infographic-cstructptr *::before, .infographic-cstructptr *::after {
box-sizing: border-box;
}
.infographic-cstructptr h1 {
font-family: 'Fraunces', Georgia, serif;
font-weight: 600;
font-size: clamp(1.3rem, 3.5vw, 1.7rem);
margin: 1.25rem 0 0.2rem;
text-align: center;
}
.infographic-cstructptr .subhead { color: var(--ink-soft); font-size: 0.85rem; margin-bottom: 1.1rem; text-align: center; }
.infographic-cstructptr .code-panel {
background: var(--code-bg);
color: var(--code-text);
border-radius: 8px;
padding: 0.65rem 0.9rem;
font-family: 'IBM Plex Mono', monospace;
font-size: 0.76rem;
line-height: 1.55;
margin-bottom: 1rem;
overflow-x: auto;
-webkit-overflow-scrolling: touch;
}
.infographic-cstructptr .code-panel .code-line { display: block; white-space: pre; }
.infographic-cstructptr .code-panel .code-line.is-highlight {
background: rgba(91, 141, 239, 0.22);
box-shadow: inset 3px 0 0 var(--accent);
}
.infographic-cstructptr .syn-keyword { color: var(--syn-keyword); }
.infographic-cstructptr .syn-func { color: var(--syn-func); }
.infographic-cstructptr .syn-string { color: var(--syn-string); }
.infographic-cstructptr .syn-comment { color: var(--syn-comment); }
.infographic-cstructptr .field-row { display: flex; align-items: center; gap: 0.5rem; flex-wrap: wrap; margin-bottom: 0.9rem; }
.infographic-cstructptr .field-row label { font-family: 'IBM Plex Mono', monospace; font-size: 0.72rem; color: var(--ink-soft); }
.infographic-cstructptr .field-row input {
font-family: 'IBM Plex Mono', monospace;
font-size: 0.82rem;
padding: 0.3rem 0.45rem;
border-radius: 6px;
border: 1px solid var(--line);
background: var(--paper);
color: var(--ink);
}
.infographic-cstructptr .field-row input.w-id { width: 3.4rem; }
.infographic-cstructptr .field-row input.w-name { width: 6rem; }
.infographic-cstructptr .field-row input.w-marks { width: 4.2rem; }
.infographic-cstructptr .run-btn {
all: unset; cursor: pointer;
font-family: 'IBM Plex Mono', monospace;
font-size: 0.8rem; font-weight: 600;
padding: 0.45rem 1rem;
border-radius: 999px;
background: var(--accent);
color: #fff;
margin-bottom: 1rem;
display: inline-block;
}
.infographic-cstructptr .run-btn:hover { opacity: 0.88; }
.infographic-cstructptr .run-btn:disabled { opacity: 0.5; cursor: default; }
.infographic-cstructptr .scene {
position: relative;
display: flex;
align-items: center;
justify-content: center;
gap: 3rem;
padding: 1.4rem 0.5rem;
margin-bottom: 0.5rem;
}
.infographic-cstructptr .ptr-box {
font-family: 'IBM Plex Mono', monospace;
font-size: 0.85rem;
font-weight: 700;
padding: 0.5rem 0.9rem;
border: 2px solid var(--line);
border-radius: 8px;
background: var(--paper-alt);
color: var(--ink-soft);
transition: border-color 0.3s, background 0.3s, color 0.3s;
}
.infographic-cstructptr .ptr-box.is-linked { border-color: var(--accent); background: var(--accent-soft); color: var(--accent); }
.infographic-cstructptr .s1-box {
border: 2px solid var(--line);
background: var(--paper-alt);
border-radius: 10px;
padding: 0.7rem 0.9rem;
min-width: 9rem;
transition: border-color 0.3s, background 0.3s;
}
.infographic-cstructptr .s1-box.is-active { border-color: var(--accent); background: var(--accent-soft); }
.infographic-cstructptr .s1-box .s1-title { font-family: 'IBM Plex Mono', monospace; font-size: 0.72rem; font-weight: 700; color: var(--ink-soft); margin-bottom: 0.4rem; }
.infographic-cstructptr .s1-box.is-active .s1-title { color: var(--accent); }
.infographic-cstructptr .s1-box .s1-line { font-family: 'IBM Plex Mono', monospace; font-size: 0.8rem; color: var(--ink-soft); margin-bottom: 0.2rem; }
.infographic-cstructptr .s1-box .s1-line strong { color: var(--ink); }
.infographic-cstructptr .s1-box .s1-line.is-filled strong { color: var(--accent); }
.infographic-cstructptr .arrow-svg { position: absolute; top: 0; left: 0; width: 100%; height: 100%; pointer-events: none; overflow: visible; }
.infographic-cstructptr .arrow-path {
fill: none; stroke: var(--accent); stroke-width: 2.2;
stroke-dasharray: 160; stroke-dashoffset: 160;
transition: stroke-dashoffset 0.5s ease, opacity 0.3s ease;
opacity: 0;
}
.infographic-cstructptr .arrow-path.is-visible { stroke-dashoffset: 0; opacity: 1; }
.infographic-cstructptr .arrow-head { fill: var(--accent); opacity: 0; transition: opacity 0.3s ease 0.3s; }
.infographic-cstructptr .arrow-head.is-visible { opacity: 1; }
.infographic-cstructptr .console {
background: var(--code-bg);
color: var(--code-text);
border-radius: 8px;
padding: 0.7rem 0.9rem;
font-family: 'IBM Plex Mono', monospace;
font-size: 0.8rem;
line-height: 1.55;
white-space: pre;
min-height: 4rem;
}
.infographic-cstructptr .takeaway {
font-size: 0.82rem; color: var(--ink-soft);
margin-top: 1.3rem; border-top: 1px solid var(--line); padding-top: 0.9rem;
}
.infographic-cstructptr .takeaway strong { color: var(--ink); }
@media (prefers-reduced-motion: reduce) {
.infographic-cstructptr * { transition: none !important; }
}
</style>
<h1>π Struct via Pointer</h1>
<p class="subhead">ptr->id is just shorthand for (*ptr).id.</p>
<div class="code-panel" id="sp-code">
<span class="code-line"><span class="syn-keyword">struct</span> <span class="syn-func">Student</span> { <span class="syn-keyword">int</span> id; <span class="syn-keyword">char</span> name[50]; <span class="syn-keyword">float</span> marks; };</span>
<span class="code-line"> </span>
<span class="code-line"><span class="syn-keyword">struct</span> Student s1;</span>
<span class="code-line" data-line="assign"><span class="syn-keyword">struct</span> Student *ptr = &s1;</span>
<span class="code-line"> </span>
<span class="code-line" data-line="id">ptr->id = 1;</span>
<span class="code-line" data-line="name"><span class="syn-func">strcpy</span>(ptr->name, <span class="syn-string">"Aman"</span>);</span>
<span class="code-line" data-line="marks">ptr->marks = 95.5;</span>
<span class="code-line"> </span>
<span class="code-line" data-line="p1"><span class="syn-func">printf</span>(<span class="syn-string">"ID: %d\n"</span>, ptr->id);</span>
<span class="code-line" data-line="p2"><span class="syn-func">printf</span>(<span class="syn-string">"Name: %s\n"</span>, ptr->name);</span>
<span class="code-line" data-line="p3"><span class="syn-func">printf</span>(<span class="syn-string">"Marks: %.2f\n"</span>, ptr->marks);</span>
</div>
<div class="field-row">
<label>id</label><input type="number" class="w-id" id="sp-id" value="1">
<label>name</label><input type="text" class="w-name" id="sp-name" value="Aman">
<label>marks</label><input type="number" class="w-marks" id="sp-marks" value="95.5" step="0.1">
</div>
<button class="run-btn" id="sp-run">βΆ Run</button>
<div class="scene" id="sp-scene">
<svg class="arrow-svg" id="sp-arrow-svg">
<path class="arrow-path" id="sp-arrow-path" d=""></path>
<polygon class="arrow-head" id="sp-arrow-head" points=""></polygon>
</svg>
<div class="ptr-box" id="sp-ptr-box">ptr</div>
<div class="s1-box" id="sp-s1-box">
<div class="s1-title">struct Student s1</div>
<div class="s1-line" id="sp-line-id">id: <strong>β</strong></div>
<div class="s1-line" id="sp-line-name">name: <strong>β</strong></div>
<div class="s1-line" id="sp-line-marks">marks: <strong>β</strong></div>
</div>
</div>
<div class="console" id="sp-console"></div>
<p class="takeaway"><strong>ptr doesn't hold a copy</strong> β it holds s1's address, so every ptr->member writes directly into s1 itself.</p>
</div>
<script>
(function () {
const wrapper = document.currentScript.closest('.infographic-cstructptr')
|| document.querySelector('.infographic-cstructptr');
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); }
const idInput = $('#sp-id'), nameInput = $('#sp-name'), marksInput = $('#sp-marks');
const runBtn = $('#sp-run');
const codePanel = $('#sp-code');
const codeLines = codePanel.querySelectorAll('.code-line[data-line]');
const consoleEl = $('#sp-console');
const ptrBox = $('#sp-ptr-box');
const s1Box = $('#sp-s1-box');
const lineId = $('#sp-line-id'), lineName = $('#sp-line-name'), lineMarks = $('#sp-line-marks');
const arrowPath = $('#sp-arrow-path');
const arrowHead = $('#sp-arrow-head');
const scene = $('#sp-scene');
const svg = $('#sp-arrow-svg');
function highlight(id) {
codeLines.forEach(l => l.classList.toggle('is-highlight', l.dataset.line === id));
}
function drawArrow() {
const svgRect = svg.getBoundingClientRect();
const fromRect = ptrBox.getBoundingClientRect();
const toRect = s1Box.getBoundingClientRect();
const startX = fromRect.right - svgRect.left;
const startY = fromRect.top + fromRect.height / 2 - svgRect.top;
const endX = toRect.left - svgRect.left - 8;
const endY = toRect.top + toRect.height / 2 - svgRect.top;
arrowPath.setAttribute('d', 'M' + startX + ',' + startY + ' L' + endX + ',' + endY);
arrowHead.setAttribute('points', endX + ',' + endY + ' ' + (endX - 9) + ',' + (endY - 6) + ' ' + (endX - 9) + ',' + (endY + 6));
}
function resetVisual() {
ptrBox.classList.remove('is-linked');
s1Box.classList.remove('is-active');
arrowPath.classList.remove('is-visible');
arrowHead.classList.remove('is-visible');
[lineId, lineName, lineMarks].forEach(el => {
el.classList.remove('is-filled');
el.querySelector('strong').textContent = 'β';
});
consoleEl.textContent = '';
highlight(null);
}
function runSequence() {
runBtn.disabled = true;
resetVisual();
const id = idInput.value, name = nameInput.value, marks = parseFloat(marksInput.value || 0).toFixed(2);
const steps = [
() => {
highlight('assign');
ptrBox.classList.add('is-linked');
s1Box.classList.add('is-active');
drawArrow();
arrowPath.classList.add('is-visible');
arrowHead.classList.add('is-visible');
},
() => { highlight('id'); lineId.classList.add('is-filled'); lineId.querySelector('strong').textContent = id; },
() => { highlight('name'); lineName.classList.add('is-filled'); lineName.querySelector('strong').textContent = name; },
() => { highlight('marks'); lineMarks.classList.add('is-filled'); lineMarks.querySelector('strong').textContent = marks; },
() => { highlight('p1'); consoleEl.textContent = 'ID: ' + id; },
() => { highlight('p2'); consoleEl.textContent += '\nName: ' + name; },
() => { highlight('p3'); consoleEl.textContent += '\nMarks: ' + marks; },
() => { highlight(null); runBtn.disabled = false; }
];
let i = 0;
function next() {
if (i >= steps.length) return;
steps[i]();
i++;
setTimeout(next, 400);
}
next();
}
runBtn.addEventListener('click', runSequence);
window.addEventListener('resize', () => { if (ptrBox.classList.contains('is-linked')) drawArrow(); });
})();
</script>π Passing Structure Pointer to Functions
Passing structure by pointer is efficient and allows modification of original structure.
π€ Function Definition:
void display(struct Student *s) {
printf("ID: %d\\n", s->id);
printf("Name: %s\\n", s->name);
printf("Marks: %.2f\\n", s->marks);
}π€ Calling from main():
struct Student s1 = {1, "Aman", 95.5};
display(&s1); // pass addressπ§ Because we passed the pointer, any changes inside the function will affect the original s1.
π§ͺ Modifying Structure Members via Pointer
You can even change values through pointer inside a function:
void updateMarks(struct Student *s) {
s->marks += 5; // add grace marks
}π§΅ Array of Structures with Pointers
You can also work with an array of structures using pointers.
struct Student students[3];
struct Student *ptr = students; // points to first studentTo access student i:
(ptr + i)->id = i + 1;β You can loop using pointers instead of array indexing!
π§ Why Use Pointers with Structures?
β Benefit | π Explanation |
|---|---|
Efficiency | Avoids copying large structures to functions |
Direct Access | Allows editing the original data |
Dynamic Allocation | Required when allocating structs via |
Easy to Build Linked Lists | Each node stores a pointer to the next struct |
π¦ Structures + Pointers + Dynamic Memory
struct Student *ptr;
ptr = (struct Student*) malloc(sizeof(struct Student));
ptr->id = 101;
strcpy(ptr->name, "Sita");
ptr->marks = 88.8;β Common in dynamic applications like:
Linked Lists
File-based Record Systems
Operating Systems & Drivers
β Common Mistakes to Avoid
β οΈ Mistake | π« Example | β Fix |
|---|---|---|
Forgetting |
|
|
Not using |
| Allocate first using |
Dereferencing NULL pointer |
| Always check if |