π¦ Why Use Loops?
Imagine this:
π§ββοΈ You're told: βPrint the numbers from 1 to 100.β
Without loops, you'd have to write:
printf("1\\n");
printf("2\\n");
printf("3\\n");
// ...up to 100!π That's boring, long, and prone to mistakes.
π Loops allow us to repeat the same code block multiple times, efficiently and cleanly.
π§ Types of Loops in C
C provides three types of loops:
π for Loop β Count-Controlled Loop
<div class="infographic-jsfor">
<style>
.infographic-jsfor {
--ink: #1a1a1a;
--ink-soft: #5c5c5c;
--paper: #ffffff;
--paper-alt: #f0ece4;
--accent: #2563eb;
--accent-soft:#e3ebfd;
--line: #ddd6c9;
--ok: #1a7f4e;
--ok-soft: #e3f5ec;
--display-font: 'Fraunces', Georgia, serif;
--body-font: 'Inter', -apple-system, sans-serif;
--mono-font: 'IBM Plex Mono', 'Courier New', monospace;
max-width: 680px;
margin: 0 auto;
box-sizing: border-box;
font-family: var(--body-font);
color: var(--ink);
background: var(--paper);
}
.infographic-jsfor[data-theme="dark"] {
--ink: #e8e6e1;
--ink-soft: #9a968c;
--paper: #121212;
--paper-alt: #1e1e26;
--accent: #5b8def;
--accent-soft:#202942;
--line: #2c313d;
--ok: #5cd6a0;
--ok-soft: #16342a;
}
.infographic-jsfor * { box-sizing: border-box; }
.infographic-jsfor .ig-inner { padding: 1.75rem clamp(1.25rem, 5vw, 3rem) 2rem; }
.infographic-jsfor .ig-title {
font-family: var(--display-font); font-size: clamp(1.4rem, 4.5vw, 1.9rem);
font-weight: 600; text-align: center; margin: 0 0 0.4rem;
}
.infographic-jsfor .ig-code {
text-align: center; font-family: var(--mono-font); font-size: 0.85rem; color: var(--ink-soft);
margin: 0 0 1.75rem;
}
.infographic-jsfor .ig-code strong { color: var(--accent); }
.infographic-jsfor .controls { display: flex; align-items: center; justify-content: center; gap: 0.6rem; flex-wrap: wrap; }
.infographic-jsfor .ctrl-btn {
font: inherit; font-size: 0.82rem; font-weight: 600; border: 1px solid var(--line);
background: var(--paper-alt); color: var(--ink); padding: 0.45rem 1rem;
border-radius: 999px; cursor: pointer; display: inline-flex; align-items: center; gap: 0.35rem;
}
.infographic-jsfor .ctrl-btn:hover { border-color: var(--accent); color: var(--accent); }
.infographic-jsfor .ctrl-btn.primary { background: var(--accent); color: var(--paper); border-color: var(--accent); }
.infographic-jsfor .i-badge {
font-family: var(--mono-font); font-size: 0.85rem; font-weight: 700; color: var(--accent);
background: var(--accent-soft); padding: 0.45rem 0.9rem; border-radius: 999px;
}
.infographic-jsfor .stage { margin-top: 1.5rem; display: flex; justify-content: center; }
.infographic-jsfor .stage svg { width: 100%; max-width: 560px; height: auto; overflow: visible; }
.infographic-jsfor .fc-shape { fill: var(--paper-alt); stroke: var(--line); stroke-width: 1.8; transition: fill 0.2s, stroke 0.2s; }
.infographic-jsfor .fc-shape.reached-yes { fill: var(--accent-soft); stroke: var(--accent); filter: drop-shadow(0 3px 6px rgba(0,0,0,0.15)); }
.infographic-jsfor .fc-shape.reached-no { fill: var(--paper-alt); stroke: var(--accent); }
.infographic-jsfor .fc-block.reached { fill: var(--ok-soft); stroke: var(--ok); filter: drop-shadow(0 3px 6px rgba(0,0,0,0.15)); }
.infographic-jsfor .fc-pill { fill: var(--accent-soft); stroke: var(--accent); }
.infographic-jsfor .fc-pill.reached { filter: drop-shadow(0 3px 6px rgba(0,0,0,0.15)); }
.infographic-jsfor .fc-text { font-family: var(--mono-font); font-size: 12px; fill: var(--ink); text-anchor: middle; }
.infographic-jsfor .fc-text.on-pill { fill: var(--accent); font-weight: 700; }
.infographic-jsfor .fc-text.on-block { font-weight: 700; }
.infographic-jsfor .fc-mark { font-family: var(--mono-font); font-size: 13px; font-weight: 700; text-anchor: middle; }
.infographic-jsfor .fc-mark.yes { fill: var(--accent); }
.infographic-jsfor .fc-mark.no { fill: var(--ink-soft); }
.infographic-jsfor .edge-label { font-family: var(--mono-font); font-size: 10px; fill: var(--ink-soft); text-anchor: middle; }
.infographic-jsfor .fc-edge path { stroke: var(--line); stroke-width: 2; fill: none; transition: stroke 0.2s; }
.infographic-jsfor .fc-edge polygon { fill: var(--line); transition: fill 0.2s; }
.infographic-jsfor .fc-edge.is-active path { stroke: var(--accent); stroke-width: 2.5; }
.infographic-jsfor .fc-edge.is-active polygon { fill: var(--accent); }
.infographic-jsfor .output {
margin-top: 1.5rem; text-align: center; font-family: var(--mono-font); font-size: 0.85rem;
color: var(--ink-soft); min-height: 1.4em;
}
.infographic-jsfor .output strong { color: var(--ok); }
.infographic-jsfor .caption {
text-align: center; font-size: 0.9rem; color: var(--ink-soft); margin-top: 0.6rem; min-height: 1.2em;
}
.infographic-jsfor .caption strong { color: var(--ink); font-family: var(--mono-font); }
@media (prefers-reduced-motion: reduce) {
.infographic-jsfor *, .infographic-jsfor *::before, .infographic-jsfor *::after {
animation-duration: 0.001ms !important; transition-duration: 0.001ms !important;
}
}
</style>
<div class="ig-inner">
<h2 class="ig-title">The for Loop</h2>
<p class="ig-code">for (<strong>let i = 0</strong>; <strong>i < 5</strong>; <strong>i++</strong>) { print(i); }</p>
<div class="controls">
<button class="ctrl-btn primary" id="playBtn">βΆ Play</button>
<button class="ctrl-btn" id="restartBtn">β² Restart</button>
<span class="i-badge" id="iBadge">i = β</span>
</div>
<div class="stage">
<svg viewBox="0 0 600 350" xmlns="http://www.w3.org/2000/svg">
<!-- Start -->
<g id="n-start">
<rect class="fc-shape fc-pill" x="15" y="130" width="100" height="40" rx="20"></rect>
<text class="fc-text on-pill" x="65" y="155">Start</text>
</g>
<!-- Start -> Init -->
<g class="fc-edge" id="e-start-init">
<path d="M115,150 L149,150"></path>
<polygon points="155,150 145,145 145,155"></polygon>
</g>
<!-- Init -->
<g id="n-init">
<rect class="fc-shape fc-block" x="155" y="125" width="130" height="50" rx="8"></rect>
<text class="fc-text on-block" x="220" y="155">let i = 0</text>
</g>
<!-- Init -> Condition -->
<g class="fc-edge" id="e-init-check">
<path d="M285,150 L309,150"></path>
<polygon points="315,150 305,145 305,155"></polygon>
</g>
<!-- Condition -->
<g id="n-check">
<polygon class="fc-shape" points="365,95 435,150 365,205 295,150"></polygon>
<text class="fc-text" x="365" y="146">i < 5</text>
<text class="fc-text" x="365" y="160">?</text>
<text class="fc-mark" id="mark-check" x="400" y="115"></text>
</g>
<!-- Yes -> Statement -->
<g class="fc-edge" id="e-check-yes">
<path d="M435,150 L459,150"></path>
<polygon points="465,150 455,145 455,155"></polygon>
</g>
<text class="edge-label" x="450" y="138">yes</text>
<g id="n-statement">
<rect class="fc-shape fc-block" x="465" y="125" width="120" height="50" rx="8"></rect>
<text class="fc-text on-block" x="525" y="155">print(i)</text>
</g>
<!-- Statement -> Increment -->
<g class="fc-edge" id="e-statement-inc">
<path d="M525,125 L525,84"></path>
<polygon points="525,78 520,88 530,88"></polygon>
</g>
<!-- Increment -->
<g id="n-increment">
<rect class="fc-shape fc-block" x="465" y="25" width="120" height="50" rx="8"></rect>
<text class="fc-text on-block" x="525" y="55">i++</text>
</g>
<!-- Increment -> Condition (loop back) -->
<g class="fc-edge" id="e-inc-check">
<path d="M465,50 L365,50 L365,84"></path>
<polygon points="365,90 360,80 370,80"></polygon>
</g>
<!-- No -> End -->
<g class="fc-edge" id="e-check-no">
<path d="M365,205 L365,274"></path>
<polygon points="365,280 360,270 370,270"></polygon>
</g>
<text class="edge-label" x="381" y="240">no</text>
<!-- End -->
<g id="n-end">
<rect class="fc-shape fc-pill" x="315" y="280" width="100" height="40" rx="20"></rect>
<text class="fc-text on-pill" x="365" y="305">End</text>
</g>
</svg>
</div>
<p class="output" id="output"></p>
<p class="caption" id="caption">Press Play to run the loop.</p>
</div>
</div>
<script>
(function () {
const wrapper = document.currentScript.closest('.infographic-jsfor')
|| document.querySelector('.infographic-jsfor');
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');
const MAX = 5;
const playBtn = wrapper.querySelector('#playBtn');
const restartBtn = wrapper.querySelector('#restartBtn');
const iBadge = wrapper.querySelector('#iBadge');
const output = wrapper.querySelector('#output');
const caption = wrapper.querySelector('#caption');
const nStart = wrapper.querySelector('#n-start .fc-pill');
const nInit = wrapper.querySelector('#n-init .fc-block');
const nCheck = wrapper.querySelector('#n-check .fc-shape');
const markCheck = wrapper.querySelector('#mark-check');
const nStatement = wrapper.querySelector('#n-statement .fc-block');
const nIncrement = wrapper.querySelector('#n-increment .fc-block');
const nEnd = wrapper.querySelector('#n-end .fc-pill');
const eStartInit = wrapper.querySelector('#e-start-init');
const eInitCheck = wrapper.querySelector('#e-init-check');
const eCheckYes = wrapper.querySelector('#e-check-yes');
const eStatementInc = wrapper.querySelector('#e-statement-inc');
const eIncCheck = wrapper.querySelector('#e-inc-check');
const eCheckNo = wrapper.querySelector('#e-check-no');
const allNodes = [nStart, nInit, nCheck, nStatement, nIncrement, nEnd];
const allEdges = [eStartInit, eInitCheck, eCheckYes, eStatementInc, eIncCheck, eCheckNo];
function resetVisual() {
allNodes.forEach(n => n.classList.remove('reached', 'reached-yes', 'reached-no'));
allEdges.forEach(e => e.classList.remove('is-active'));
markCheck.textContent = ''; markCheck.classList.remove('yes', 'no');
}
// Build the full step sequence
let steps = [];
function buildSteps() {
steps = [];
steps.push({ edge: eStartInit });
steps.push({ node: nInit, i: 0, setBadge: 0 });
steps.push({ edge: eInitCheck });
for (let i = 0; i < MAX; i++) {
steps.push({ check: true, i, result: true });
steps.push({ edge: eCheckYes });
steps.push({ node: nStatement, i, print: i });
steps.push({ edge: eStatementInc });
steps.push({ node: nIncrement, i, setBadge: i + 1 });
steps.push({ edge: eIncCheck });
}
steps.push({ check: true, i: MAX, result: false });
steps.push({ edge: eCheckNo });
steps.push({ node: nEnd, done: true });
}
buildSteps();
let idx = -1;
let timer = null;
let printed = [];
function applyStep(step) {
resetVisual();
nStart.classList.add('reached');
if (step.edge) {
step.edge.classList.add('is-active');
}
if (step.node) {
step.node.classList.add('reached');
if (step.setBadge !== undefined) iBadge.textContent = `i = ${step.setBadge}`;
if (step.print !== undefined) {
printed.push(step.print);
output.innerHTML = `output: <strong>${printed.join(', ')}</strong>`;
}
if (step.done) {
caption.textContent = 'Loop finished β condition is now false.';
}
}
if (step.check) {
nCheck.classList.add(step.result ? 'reached-yes' : 'reached-no');
markCheck.textContent = step.result ? 'β' : 'β';
markCheck.classList.add(step.result ? 'yes' : 'no');
iBadge.textContent = `i = ${step.i}`;
caption.textContent = step.result
? `i = ${step.i} β true, run the loop body`
: `i = ${step.i} β false, exit the loop`;
}
}
function stop() {
clearInterval(timer);
timer = null;
playBtn.textContent = 'βΆ Play';
}
function advance() {
idx++;
if (idx >= steps.length) {
stop();
return;
}
applyStep(steps[idx]);
if (idx >= steps.length - 1) stop();
}
function play() {
if (timer) { stop(); return; }
if (idx >= steps.length - 1) restart(false);
playBtn.textContent = 'βΈ Pause';
timer = setInterval(advance, 850);
advance();
}
function restart(clearBadge = true) {
stop();
idx = -1;
printed = [];
output.textContent = '';
resetVisual();
if (clearBadge) {
iBadge.textContent = 'i = β';
caption.textContent = 'Press Play to run the loop.';
}
}
playBtn.addEventListener('click', play);
restartBtn.addEventListener('click', () => restart(true));
restart(true);
})();
</script>π Syntax:
for (initialization; condition; increment/decrement) {
// loop body
}π Parts of a for loop:
Initialization β Start value (e.g.,
int i = 1)Condition β Loop continues while this is true (e.g.,
i <= 5)Increment/Decrement β Changes the loop variable (
i++ori--)
β Example:
for (int i = 1; i <= 5; i++) {
printf("%d\\n", i);
}1
2
3
4
5π Example: Reverse counting
for (int i = 5; i >= 1; i--) {
printf("%d ", i);
}5 4 3 2 1π while Loop β Condition-Controlled Loop
<div class="infographic-jswhile">
<style>
.infographic-jswhile {
--ink: #1a1a1a;
--ink-soft: #5c5c5c;
--paper: #ffffff;
--paper-alt: #f0ece4;
--accent: #2563eb;
--accent-soft:#e3ebfd;
--line: #ddd6c9;
--ok: #1a7f4e;
--ok-soft: #e3f5ec;
--display-font: 'Fraunces', Georgia, serif;
--body-font: 'Inter', -apple-system, sans-serif;
--mono-font: 'IBM Plex Mono', 'Courier New', monospace;
max-width: 700px;
margin: 0 auto;
box-sizing: border-box;
font-family: var(--body-font);
color: var(--ink);
background: var(--paper);
}
.infographic-jswhile[data-theme="dark"] {
--ink: #e8e6e1;
--ink-soft: #9a968c;
--paper: #121212;
--paper-alt: #1e1e26;
--accent: #5b8def;
--accent-soft:#202942;
--line: #2c313d;
--ok: #5cd6a0;
--ok-soft: #16342a;
}
.infographic-jswhile * { box-sizing: border-box; }
.infographic-jswhile .ig-inner { padding: 1.75rem clamp(1.25rem, 5vw, 3rem) 2rem; }
.infographic-jswhile .ig-title {
font-family: var(--display-font); font-size: clamp(1.4rem, 4.5vw, 1.9rem);
font-weight: 600; text-align: center; margin: 0 0 0.4rem;
}
.infographic-jswhile .ig-code {
text-align: center; font-family: var(--mono-font); font-size: 0.85rem; color: var(--ink-soft);
margin: 0 0 1.75rem;
}
.infographic-jswhile .ig-code strong { color: var(--accent); }
.infographic-jswhile .controls { display: flex; align-items: center; justify-content: center; gap: 0.6rem; flex-wrap: wrap; }
.infographic-jswhile .ctrl-btn {
font: inherit; font-size: 0.82rem; font-weight: 600; border: 1px solid var(--line);
background: var(--paper-alt); color: var(--ink); padding: 0.45rem 1rem;
border-radius: 999px; cursor: pointer; display: inline-flex; align-items: center; gap: 0.35rem;
}
.infographic-jswhile .ctrl-btn:hover { border-color: var(--accent); color: var(--accent); }
.infographic-jswhile .ctrl-btn.primary { background: var(--accent); color: var(--paper); border-color: var(--accent); }
.infographic-jswhile .i-badge {
font-family: var(--mono-font); font-size: 0.85rem; font-weight: 700; color: var(--accent);
background: var(--accent-soft); padding: 0.45rem 0.9rem; border-radius: 999px;
}
.infographic-jswhile .stage { margin-top: 1.5rem; display: flex; justify-content: center; }
.infographic-jswhile .stage svg { width: 100%; max-width: 580px; height: auto; overflow: visible; }
.infographic-jswhile .fc-shape { fill: var(--paper-alt); stroke: var(--line); stroke-width: 1.8; transition: fill 0.2s, stroke 0.2s; }
.infographic-jswhile .fc-shape.reached-yes { fill: var(--accent-soft); stroke: var(--accent); filter: drop-shadow(0 3px 6px rgba(0,0,0,0.15)); }
.infographic-jswhile .fc-shape.reached-no { fill: var(--paper-alt); stroke: var(--accent); }
.infographic-jswhile .fc-block.reached { fill: var(--ok-soft); stroke: var(--ok); filter: drop-shadow(0 3px 6px rgba(0,0,0,0.15)); }
.infographic-jswhile .fc-pill { fill: var(--accent-soft); stroke: var(--accent); }
.infographic-jswhile .fc-pill.reached { filter: drop-shadow(0 3px 6px rgba(0,0,0,0.15)); }
.infographic-jswhile .fc-text { font-family: var(--mono-font); font-size: 12px; fill: var(--ink); text-anchor: middle; }
.infographic-jswhile .fc-text.on-pill { fill: var(--accent); font-weight: 700; }
.infographic-jswhile .fc-text.on-block { font-weight: 700; }
.infographic-jswhile .fc-mark { font-family: var(--mono-font); font-size: 13px; font-weight: 700; text-anchor: middle; }
.infographic-jswhile .fc-mark.yes { fill: var(--accent); }
.infographic-jswhile .fc-mark.no { fill: var(--ink-soft); }
.infographic-jswhile .edge-label { font-family: var(--mono-font); font-size: 10px; fill: var(--ink-soft); text-anchor: middle; }
.infographic-jswhile .fc-edge path { stroke: var(--line); stroke-width: 2; fill: none; transition: stroke 0.2s; }
.infographic-jswhile .fc-edge polygon { fill: var(--line); transition: fill 0.2s; }
.infographic-jswhile .fc-edge.is-active path { stroke: var(--accent); stroke-width: 2.5; }
.infographic-jswhile .fc-edge.is-active polygon { fill: var(--accent); }
.infographic-jswhile .output {
margin-top: 1.5rem; text-align: center; font-family: var(--mono-font); font-size: 0.85rem;
color: var(--ink-soft); min-height: 1.4em;
}
.infographic-jswhile .output strong { color: var(--ok); }
.infographic-jswhile .caption {
text-align: center; font-size: 0.9rem; color: var(--ink-soft); margin-top: 0.6rem; min-height: 1.2em;
}
.infographic-jswhile .caption strong { color: var(--ink); font-family: var(--mono-font); }
@media (prefers-reduced-motion: reduce) {
.infographic-jswhile *, .infographic-jswhile *::before, .infographic-jswhile *::after {
animation-duration: 0.001ms !important; transition-duration: 0.001ms !important;
}
}
</style>
<div class="ig-inner">
<h2 class="ig-title">The while Loop</h2>
<p class="ig-code">let i = 0; while (<strong>i < 5</strong>) { print(i); <strong>i++</strong>; }</p>
<div class="controls">
<button class="ctrl-btn primary" id="playBtn">βΆ Play</button>
<button class="ctrl-btn" id="restartBtn">β² Restart</button>
<span class="i-badge" id="iBadge">i = β</span>
</div>
<div class="stage">
<svg viewBox="0 0 630 350" xmlns="http://www.w3.org/2000/svg">
<!-- Start -->
<g id="n-start">
<rect class="fc-shape fc-pill" x="15" y="130" width="100" height="40" rx="20"></rect>
<text class="fc-text on-pill" x="65" y="155">Start</text>
</g>
<!-- Start -> Init -->
<g class="fc-edge" id="e-start-init">
<path d="M115,150 L149,150"></path>
<polygon points="155,150 145,145 145,155"></polygon>
</g>
<!-- Init -->
<g id="n-init">
<rect class="fc-shape fc-block" x="155" y="125" width="130" height="50" rx="8"></rect>
<text class="fc-text on-block" x="220" y="155">let i = 0</text>
</g>
<!-- Init -> Condition -->
<g class="fc-edge" id="e-init-check">
<path d="M285,150 L309,150"></path>
<polygon points="315,150 305,145 305,155"></polygon>
</g>
<!-- Condition -->
<g id="n-check">
<polygon class="fc-shape" points="365,95 435,150 365,205 295,150"></polygon>
<text class="fc-text" x="365" y="146">i < 5</text>
<text class="fc-text" x="365" y="160">?</text>
<text class="fc-mark" id="mark-check" x="400" y="115"></text>
</g>
<!-- Yes -> Statement -->
<g class="fc-edge" id="e-check-yes">
<path d="M435,150 L459,150"></path>
<polygon points="465,150 455,145 455,155"></polygon>
</g>
<text class="edge-label" x="450" y="138">yes</text>
<g id="n-statement">
<rect class="fc-shape fc-block" x="465" y="125" width="150" height="50" rx="8"></rect>
<text class="fc-text on-block" x="540" y="146">print(i);</text>
<text class="fc-text on-block" x="540" y="163">i++;</text>
</g>
<!-- Statement -> Condition (loop back) -->
<g class="fc-edge" id="e-loop-back">
<path d="M540,125 L540,50 L365,50 L365,84"></path>
<polygon points="365,90 360,80 370,80"></polygon>
</g>
<!-- No -> End -->
<g class="fc-edge" id="e-check-no">
<path d="M365,205 L365,274"></path>
<polygon points="365,280 360,270 370,270"></polygon>
</g>
<text class="edge-label" x="381" y="240">no</text>
<!-- End -->
<g id="n-end">
<rect class="fc-shape fc-pill" x="315" y="280" width="100" height="40" rx="20"></rect>
<text class="fc-text on-pill" x="365" y="305">End</text>
</g>
</svg>
</div>
<p class="output" id="output"></p>
<p class="caption" id="caption">Press Play to run the loop.</p>
</div>
</div>
<script>
(function () {
const wrapper = document.currentScript.closest('.infographic-jswhile')
|| document.querySelector('.infographic-jswhile');
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');
const MAX = 5;
const playBtn = wrapper.querySelector('#playBtn');
const restartBtn = wrapper.querySelector('#restartBtn');
const iBadge = wrapper.querySelector('#iBadge');
const output = wrapper.querySelector('#output');
const caption = wrapper.querySelector('#caption');
const nStart = wrapper.querySelector('#n-start .fc-pill');
const nInit = wrapper.querySelector('#n-init .fc-block');
const nCheck = wrapper.querySelector('#n-check .fc-shape');
const markCheck = wrapper.querySelector('#mark-check');
const nStatement = wrapper.querySelector('#n-statement .fc-block');
const nEnd = wrapper.querySelector('#n-end .fc-pill');
const eStartInit = wrapper.querySelector('#e-start-init');
const eInitCheck = wrapper.querySelector('#e-init-check');
const eCheckYes = wrapper.querySelector('#e-check-yes');
const eLoopBack = wrapper.querySelector('#e-loop-back');
const eCheckNo = wrapper.querySelector('#e-check-no');
const allNodes = [nStart, nInit, nCheck, nStatement, nEnd];
const allEdges = [eStartInit, eInitCheck, eCheckYes, eLoopBack, eCheckNo];
function resetVisual() {
allNodes.forEach(n => n.classList.remove('reached', 'reached-yes', 'reached-no'));
allEdges.forEach(e => e.classList.remove('is-active'));
markCheck.textContent = ''; markCheck.classList.remove('yes', 'no');
}
let steps = [];
function buildSteps() {
steps = [];
steps.push({ edge: eStartInit });
steps.push({ node: nInit, setBadge: 0 });
steps.push({ edge: eInitCheck });
for (let i = 0; i < MAX; i++) {
steps.push({ check: true, i, result: true });
steps.push({ edge: eCheckYes });
steps.push({ node: nStatement, i, print: i, setBadge: i + 1 });
steps.push({ edge: eLoopBack });
}
steps.push({ check: true, i: MAX, result: false });
steps.push({ edge: eCheckNo });
steps.push({ node: nEnd, done: true });
}
buildSteps();
let idx = -1;
let timer = null;
let printed = [];
function applyStep(step) {
resetVisual();
nStart.classList.add('reached');
if (step.edge) {
step.edge.classList.add('is-active');
}
if (step.node) {
step.node.classList.add('reached');
if (step.setBadge !== undefined) iBadge.textContent = `i = ${step.setBadge}`;
if (step.print !== undefined) {
printed.push(step.print);
output.innerHTML = `output: <strong>${printed.join(', ')}</strong>`;
}
if (step.done) {
caption.textContent = 'Loop finished β condition is now false.';
}
}
if (step.check) {
nCheck.classList.add(step.result ? 'reached-yes' : 'reached-no');
markCheck.textContent = step.result ? 'β' : 'β';
markCheck.classList.add(step.result ? 'yes' : 'no');
iBadge.textContent = `i = ${step.i}`;
caption.textContent = step.result
? `i = ${step.i} β true, run the loop body`
: `i = ${step.i} β false, exit the loop`;
}
}
function stop() {
clearInterval(timer);
timer = null;
playBtn.textContent = 'βΆ Play';
}
function advance() {
idx++;
if (idx >= steps.length) {
stop();
return;
}
applyStep(steps[idx]);
if (idx >= steps.length - 1) stop();
}
function play() {
if (timer) { stop(); return; }
if (idx >= steps.length - 1) restart(false);
playBtn.textContent = 'βΈ Pause';
timer = setInterval(advance, 850);
advance();
}
function restart(clearBadge = true) {
stop();
idx = -1;
printed = [];
output.textContent = '';
resetVisual();
if (clearBadge) {
iBadge.textContent = 'i = β';
caption.textContent = 'Press Play to run the loop.';
}
}
playBtn.addEventListener('click', play);
restartBtn.addEventListener('click', () => restart(true));
restart(true);
})();
</script>π Syntax:
while (condition) {
// loop body
}Checks the condition before the first execution.
If condition is false initially, the loop wonβt run at all.
β Example:
int i = 1;
while (i <= 5) {
printf("%d\\n", i);
i++;
}1
2
3
4
5π¨ Infinite Loop Danger:
If the condition never becomes false, the loop runs forever.
while (1) {
printf("Forever!\\n"); // Infinite loop (avoid unless intentional)
}π do-while Loop β Exit-Controlled Loop
<div class="infographic-jsdowhile">
<style>
.infographic-jsdowhile {
--ink: #1a1a1a;
--ink-soft: #5c5c5c;
--paper: #ffffff;
--paper-alt: #f0ece4;
--accent: #2563eb;
--accent-soft:#e3ebfd;
--line: #ddd6c9;
--ok: #1a7f4e;
--ok-soft: #e3f5ec;
--display-font: 'Fraunces', Georgia, serif;
--body-font: 'Inter', -apple-system, sans-serif;
--mono-font: 'IBM Plex Mono', 'Courier New', monospace;
max-width: 720px;
margin: 0 auto;
box-sizing: border-box;
font-family: var(--body-font);
color: var(--ink);
background: var(--paper);
}
.infographic-jsdowhile[data-theme="dark"] {
--ink: #e8e6e1;
--ink-soft: #9a968c;
--paper: #121212;
--paper-alt: #1e1e26;
--accent: #5b8def;
--accent-soft:#202942;
--line: #2c313d;
--ok: #5cd6a0;
--ok-soft: #16342a;
}
.infographic-jsdowhile * { box-sizing: border-box; }
.infographic-jsdowhile .ig-inner { padding: 1.75rem clamp(1.25rem, 5vw, 3rem) 2rem; }
.infographic-jsdowhile .ig-title {
font-family: var(--display-font); font-size: clamp(1.4rem, 4.5vw, 1.9rem);
font-weight: 600; text-align: center; margin: 0 0 0.4rem;
}
.infographic-jsdowhile .ig-code {
text-align: center; font-family: var(--mono-font); font-size: 0.85rem; color: var(--ink-soft);
margin: 0 0 1.75rem;
}
.infographic-jsdowhile .ig-code strong { color: var(--accent); }
.infographic-jsdowhile .controls { display: flex; align-items: center; justify-content: center; gap: 0.6rem; flex-wrap: wrap; }
.infographic-jsdowhile .ctrl-btn {
font: inherit; font-size: 0.82rem; font-weight: 600; border: 1px solid var(--line);
background: var(--paper-alt); color: var(--ink); padding: 0.45rem 1rem;
border-radius: 999px; cursor: pointer; display: inline-flex; align-items: center; gap: 0.35rem;
}
.infographic-jsdowhile .ctrl-btn:hover { border-color: var(--accent); color: var(--accent); }
.infographic-jsdowhile .ctrl-btn.primary { background: var(--accent); color: var(--paper); border-color: var(--accent); }
.infographic-jsdowhile .i-badge {
font-family: var(--mono-font); font-size: 0.85rem; font-weight: 700; color: var(--accent);
background: var(--accent-soft); padding: 0.45rem 0.9rem; border-radius: 999px;
}
.infographic-jsdowhile .stage { margin-top: 1.5rem; display: flex; justify-content: center; }
.infographic-jsdowhile .stage svg { width: 100%; max-width: 600px; height: auto; overflow: visible; }
.infographic-jsdowhile .fc-shape { fill: var(--paper-alt); stroke: var(--line); stroke-width: 1.8; transition: fill 0.2s, stroke 0.2s; }
.infographic-jsdowhile .fc-shape.reached-yes { fill: var(--accent-soft); stroke: var(--accent); filter: drop-shadow(0 3px 6px rgba(0,0,0,0.15)); }
.infographic-jsdowhile .fc-shape.reached-no { fill: var(--paper-alt); stroke: var(--accent); }
.infographic-jsdowhile .fc-block.reached { fill: var(--ok-soft); stroke: var(--ok); filter: drop-shadow(0 3px 6px rgba(0,0,0,0.15)); }
.infographic-jsdowhile .fc-pill { fill: var(--accent-soft); stroke: var(--accent); }
.infographic-jsdowhile .fc-pill.reached { filter: drop-shadow(0 3px 6px rgba(0,0,0,0.15)); }
.infographic-jsdowhile .fc-text { font-family: var(--mono-font); font-size: 12px; fill: var(--ink); text-anchor: middle; }
.infographic-jsdowhile .fc-text.on-pill { fill: var(--accent); font-weight: 700; }
.infographic-jsdowhile .fc-text.on-block { font-weight: 700; }
.infographic-jsdowhile .fc-mark { font-family: var(--mono-font); font-size: 13px; font-weight: 700; text-anchor: middle; }
.infographic-jsdowhile .fc-mark.yes { fill: var(--accent); }
.infographic-jsdowhile .fc-mark.no { fill: var(--ink-soft); }
.infographic-jsdowhile .edge-label { font-family: var(--mono-font); font-size: 10px; fill: var(--ink-soft); text-anchor: middle; }
.infographic-jsdowhile .fc-edge path { stroke: var(--line); stroke-width: 2; fill: none; transition: stroke 0.2s; }
.infographic-jsdowhile .fc-edge polygon { fill: var(--line); transition: fill 0.2s; }
.infographic-jsdowhile .fc-edge.is-active path { stroke: var(--accent); stroke-width: 2.5; }
.infographic-jsdowhile .fc-edge.is-active polygon { fill: var(--accent); }
.infographic-jsdowhile .output {
margin-top: 1.5rem; text-align: center; font-family: var(--mono-font); font-size: 0.85rem;
color: var(--ink-soft); min-height: 1.4em;
}
.infographic-jsdowhile .output strong { color: var(--ok); }
.infographic-jsdowhile .caption {
text-align: center; font-size: 0.9rem; color: var(--ink-soft); margin-top: 0.6rem; min-height: 1.2em;
}
.infographic-jsdowhile .caption strong { color: var(--ink); font-family: var(--mono-font); }
@media (prefers-reduced-motion: reduce) {
.infographic-jsdowhile *, .infographic-jsdowhile *::before, .infographic-jsdowhile *::after {
animation-duration: 0.001ms !important; transition-duration: 0.001ms !important;
}
}
</style>
<div class="ig-inner">
<h2 class="ig-title">The do...while Loop</h2>
<p class="ig-code">let i = 0; do { print(i); i++; } while (<strong>i < 5</strong>);</p>
<div class="controls">
<button class="ctrl-btn primary" id="playBtn">βΆ Play</button>
<button class="ctrl-btn" id="restartBtn">β² Restart</button>
<span class="i-badge" id="iBadge">i = β</span>
</div>
<div class="stage">
<svg viewBox="0 0 640 350" xmlns="http://www.w3.org/2000/svg">
<!-- Start -->
<g id="n-start">
<rect class="fc-shape fc-pill" x="15" y="130" width="100" height="40" rx="20"></rect>
<text class="fc-text on-pill" x="65" y="155">Start</text>
</g>
<!-- Start -> Init -->
<g class="fc-edge" id="e-start-init">
<path d="M115,150 L149,150"></path>
<polygon points="155,150 145,145 145,155"></polygon>
</g>
<!-- Init -->
<g id="n-init">
<rect class="fc-shape fc-block" x="155" y="125" width="130" height="50" rx="8"></rect>
<text class="fc-text on-block" x="220" y="155">let i = 0</text>
</g>
<!-- Init -> Statement -->
<g class="fc-edge" id="e-init-statement">
<path d="M285,150 L309,150"></path>
<polygon points="315,150 305,145 305,155"></polygon>
</g>
<!-- Statement (runs first, before any check) -->
<g id="n-statement">
<rect class="fc-shape fc-block" x="315" y="125" width="150" height="50" rx="8"></rect>
<text class="fc-text on-block" x="390" y="146">print(i);</text>
<text class="fc-text on-block" x="390" y="163">i++;</text>
</g>
<!-- Statement -> Condition -->
<g class="fc-edge" id="e-statement-check">
<path d="M465,150 L479,150"></path>
<polygon points="485,150 475,145 475,155"></polygon>
</g>
<!-- Condition -->
<g id="n-check">
<polygon class="fc-shape" points="555,95 625,150 555,205 485,150"></polygon>
<text class="fc-text" x="555" y="146">i < 5</text>
<text class="fc-text" x="555" y="160">?</text>
<text class="fc-mark" id="mark-check" x="590" y="115"></text>
</g>
<!-- Condition -> Statement (loop back, true) -->
<g class="fc-edge" id="e-loop-back">
<path d="M555,95 L555,50 L390,50 L390,84"></path>
<polygon points="390,90 385,80 395,80"></polygon>
</g>
<text class="edge-label" x="472" y="40">if true</text>
<!-- No -> End -->
<g class="fc-edge" id="e-check-no">
<path d="M555,205 L555,274"></path>
<polygon points="555,280 550,270 560,270"></polygon>
</g>
<text class="edge-label" x="571" y="240">if false</text>
<!-- End -->
<g id="n-end">
<rect class="fc-shape fc-pill" x="505" y="280" width="100" height="40" rx="20"></rect>
<text class="fc-text on-pill" x="555" y="305">End</text>
</g>
</svg>
</div>
<p class="output" id="output"></p>
<p class="caption" id="caption">Press Play to run the loop.</p>
</div>
</div>
<script>
(function () {
const wrapper = document.currentScript.closest('.infographic-jsdowhile')
|| document.querySelector('.infographic-jsdowhile');
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');
const MAX = 5;
const playBtn = wrapper.querySelector('#playBtn');
const restartBtn = wrapper.querySelector('#restartBtn');
const iBadge = wrapper.querySelector('#iBadge');
const output = wrapper.querySelector('#output');
const caption = wrapper.querySelector('#caption');
const nStart = wrapper.querySelector('#n-start .fc-pill');
const nInit = wrapper.querySelector('#n-init .fc-block');
const nStatement = wrapper.querySelector('#n-statement .fc-block');
const nCheck = wrapper.querySelector('#n-check .fc-shape');
const markCheck = wrapper.querySelector('#mark-check');
const nEnd = wrapper.querySelector('#n-end .fc-pill');
const eStartInit = wrapper.querySelector('#e-start-init');
const eInitStatement = wrapper.querySelector('#e-init-statement');
const eStatementCheck = wrapper.querySelector('#e-statement-check');
const eLoopBack = wrapper.querySelector('#e-loop-back');
const eCheckNo = wrapper.querySelector('#e-check-no');
const allNodes = [nStart, nInit, nStatement, nCheck, nEnd];
const allEdges = [eStartInit, eInitStatement, eStatementCheck, eLoopBack, eCheckNo];
function resetVisual() {
allNodes.forEach(n => n.classList.remove('reached', 'reached-yes', 'reached-no'));
allEdges.forEach(e => e.classList.remove('is-active'));
markCheck.textContent = ''; markCheck.classList.remove('yes', 'no');
}
let steps = [];
function buildSteps() {
steps = [];
steps.push({ edge: eStartInit });
steps.push({ node: nInit, setBadge: 0 });
steps.push({ edge: eInitStatement });
for (let i = 0; i < MAX; i++) {
steps.push({ node: nStatement, i, print: i, setBadge: i + 1 });
steps.push({ edge: eStatementCheck });
const nextI = i + 1;
const result = nextI < MAX;
steps.push({ check: true, i: nextI, result });
if (result) {
steps.push({ edge: eLoopBack });
} else {
steps.push({ edge: eCheckNo });
steps.push({ node: nEnd, done: true });
}
}
}
buildSteps();
let idx = -1;
let timer = null;
let printed = [];
function applyStep(step) {
resetVisual();
nStart.classList.add('reached');
if (step.edge) {
step.edge.classList.add('is-active');
}
if (step.node) {
step.node.classList.add('reached');
if (step.setBadge !== undefined) iBadge.textContent = `i = ${step.setBadge}`;
if (step.print !== undefined) {
printed.push(step.print);
output.innerHTML = `output: <strong>${printed.join(', ')}</strong>`;
}
if (step.done) {
caption.textContent = 'Loop finished β condition is now false.';
}
}
if (step.check) {
nCheck.classList.add(step.result ? 'reached-yes' : 'reached-no');
markCheck.textContent = step.result ? 'β' : 'β';
markCheck.classList.add(step.result ? 'yes' : 'no');
iBadge.textContent = `i = ${step.i}`;
caption.textContent = step.result
? `i = ${step.i} β true, run the block again`
: `i = ${step.i} β false, exit the loop`;
}
}
function stop() {
clearInterval(timer);
timer = null;
playBtn.textContent = 'βΆ Play';
}
function advance() {
idx++;
if (idx >= steps.length) {
stop();
return;
}
applyStep(steps[idx]);
if (idx >= steps.length - 1) stop();
}
function play() {
if (timer) { stop(); return; }
if (idx >= steps.length - 1) restart(false);
playBtn.textContent = 'βΈ Pause';
timer = setInterval(advance, 850);
advance();
}
function restart(clearBadge = true) {
stop();
idx = -1;
printed = [];
output.textContent = '';
resetVisual();
if (clearBadge) {
iBadge.textContent = 'i = β';
caption.textContent = 'Press Play to run the loop.';
}
}
playBtn.addEventListener('click', play);
restartBtn.addEventListener('click', () => restart(true));
restart(true);
})();
</script>π Syntax:
do {
// loop body
} while (condition);Runs the loop body first, then checks the condition.
Loop will always run at least once even if the condition is false.
β Example:
int i = 1;
do {
printf("%d\\n", i);
i++;
} while (i <= 5)1
2
3
4
5β Real Difference from while:
int x = 10;
while (x < 5) {
printf("Hello from while!");
}
do {
printf("Hello from do-while!");
} while (x < 5)
Hello from do-while!Even though the condition is false, do-while ran once.
π Difference between for, while, and do-while loops in C:
Feature |
|
|
|
|---|---|---|---|
Use Case | When number of iterations is known | When condition must be checked before loop | When loop must run at least once |
Syntax |
|
|
|
Condition Check | Before the first iteration | Before the first iteration | After the first iteration |
Minimum Executions | 0 times (if condition is false) | 0 times | 1 time minimum |
Best For | Counting loops, fixed iterations | Event-driven loops, unknown iterations | Menu-driven programs, at-least-once runs |
Initialization & Update | Inside loop header | Separate from loop | Update must be handled manually |