🧠 What is it?
When you call a function and pass values to it (called arguments), those values are received by the parameters of the function. How they’re received defines the calling method:
Call by Value 📦 – You send a copy of the value.
Call by Reference 📡 – You send the address (reference) of the value.
📦 Call by Value (Default in C)
✅ What happens?
A copy of the actual value is passed.
Any changes made inside the function do not affect the original variable.
The original variable and function parameter are completely separate.
🧠 Real-Life Analogy:
You photocopy your marksheet and send the copy to someone. If they write “Fail” on the copy, your original marksheet is unaffected.
💡 Example:
#include <stdio.h>
void changeValue(int x) {
x = 50; // Changing the value
printf("Inside function: x = %d\\n", x);
}
int main() {
int a = 10;
changeValue(a);
printf("Outside function: a = %d\\n", a);
return 0;
}Inside function: x = 50
Outside function: a = 10🟢 Explanation:
xwas changed inside the function, butaremained unaffected.This is because
xwas just a copy ofa.
📡 Call by Reference (Using Pointers in C which we will study in further chapters)
🧠 C does not support true call-by-reference, but you can achieve the same using pointers.
✅ What happens?
The address of the variable is passed.
Any change made affects the original variable, since both refer to the same memory location.
🧠 Real-Life Analogy:
You give someone the original house key. If they repaint your wall, your actual home gets painted — not a copy!
💡 Example:
#include <stdio.h>
void changeValue(int *x) {
*x = 50; // Changing the actual value using pointer
printf("Inside function: x = %d\\n", *x);
}
int main() {
int a = 10;
changeValue(&a); // Passing address of 'a'
printf("Outside function: a = %d\\n", a);
return 0;
}Inside function: x = 50
Outside function: a = 50🟢 Explanation:
xrefers to the value stored at address ofa.Changing
xchangesadirectly.
🔍 Difference Table: Call by Value vs Call by Reference
Feature | Call by Value 📦 | Call by Reference 📡 |
|---|---|---|
Data Passed | Copy of the variable | Address (reference) of variable |
Affects Original Value? | ❌ No | ✅ Yes |
Memory Usage | More (copying data) | Less (just addresses) |
Default in C? | ✅ Yes | ❌ No (need pointers) |
Safe from side effects? | ✅ Yes | ❌ No (can change original) |
🧪 Bonus: When to Use What?
Use Case | Method |
|---|---|
You want to keep original data safe | Call by Value |
You want to modify original data | Call by Reference (Pointers) |
Working with large data (efficiency) | Call by Reference |
⚠️ Common Mistakes to Avoid
🚫 Don’t forget to use
*to dereference(accessing the value stored at a memory address) in call-by-reference.⚠️ Forgetting to use
&when passing address.🤔 Confusing value vs reference when debugging.
🧠 Example together:
#include <stdio.h>
void test(int x, int *y) {
x = 100;
*y = 200;
}
int main() {
int a = 5, b = 10;
test(a, &b);
printf("a = %d, b = %d\\n", a, b);
return 0;
}a = 5, b = 200<div class="infographic-cpassing">
<style>
.infographic-cpassing {
--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;
--ok: #1a7f4e;
--ok-soft: #e3f5ec;
--warn: #b45309;
--warn-soft: #fdf0dc;
}
.infographic-cpassing[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;
--ok: #5cd6a0;
--ok-soft: #16342a;
--warn: #e0a458;
--warn-soft: #3a2c14;
}
.infographic-cpassing {
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-cpassing *, .infographic-cpassing *::before, .infographic-cpassing *::after {
box-sizing: border-box;
}
.infographic-cpassing h1 {
font-family: 'Fraunces', Georgia, serif;
font-weight: 600;
font-size: clamp(1.3rem, 3.2vw, 1.6rem);
margin: 1.1rem 0 0.2rem;
}
.infographic-cpassing .subhead { color: var(--ink-soft); font-size: 0.85rem; margin-bottom: 0.85rem; }
.infographic-cpassing .chip-row { display: flex; flex-wrap: wrap; gap: 0.45rem; margin-bottom: 0.85rem; }
.infographic-cpassing .chip {
all: unset;
cursor: pointer;
font-family: 'IBM Plex Mono', monospace;
font-size: 0.78rem;
font-weight: 600;
padding: 0.4rem 0.85rem;
border-radius: 20px;
border: 1px solid var(--line);
color: var(--ink-soft);
transition: background 0.2s, color 0.2s, border-color 0.2s;
}
.infographic-cpassing .chip:hover { border-color: var(--accent); }
.infographic-cpassing .chip.is-active { background: var(--accent); border-color: var(--accent); color: #fff; }
.infographic-cpassing .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.78rem;
line-height: 1.5;
margin-bottom: 0.85rem;
}
.infographic-cpassing .code-line {
display: block;
white-space: pre;
border-radius: 4px;
padding: 0.05rem 0.4rem;
margin: 0 -0.4rem;
transition: background 0.3s, box-shadow 0.3s;
}
.infographic-cpassing .code-line.is-highlight {
background: rgba(91, 141, 239, 0.22);
box-shadow: inset 3px 0 0 var(--accent);
}
.infographic-cpassing .syn-keyword { color: var(--syn-keyword); }
.infographic-cpassing .syn-func { color: var(--syn-func); }
.infographic-cpassing .syn-string { color: var(--syn-string); }
.infographic-cpassing .syn-comment { color: var(--syn-comment); }
.infographic-cpassing .field-row { display: flex; align-items: center; gap: 0.55rem; flex-wrap: wrap; margin-bottom: 0.85rem; }
.infographic-cpassing .field-row label { font-size: 0.8rem; color: var(--ink-soft); }
.infographic-cpassing .field-row input {
font-family: 'IBM Plex Mono', monospace;
font-size: 0.85rem;
padding: 0.32rem 0.5rem;
border-radius: 6px;
border: 1px solid var(--line);
background: var(--paper);
color: var(--ink);
width: 4.5rem;
}
.infographic-cpassing .field-row input:focus { outline: 2px solid var(--accent); outline-offset: 1px; }
.infographic-cpassing .ctrl-btn {
all: unset; cursor: pointer;
font-family: 'IBM Plex Mono', monospace;
font-size: 0.76rem; font-weight: 600;
padding: 0.38rem 0.85rem;
border-radius: 999px;
border: 1px solid var(--line);
background: var(--paper-alt);
color: var(--ink);
}
.infographic-cpassing .ctrl-btn.primary { background: var(--accent); color: #fff; border-color: var(--accent); }
.infographic-cpassing .ctrl-btn:disabled { opacity: 0.5; cursor: default; }
.infographic-cpassing .layout {
display: grid;
grid-template-columns: 1fr 210px;
gap: 1rem;
align-items: start;
}
@media (max-width: 600px) { .infographic-cpassing .layout { grid-template-columns: 1fr; } }
/* step list */
.infographic-cpassing .flow { position: relative; padding-left: 2.6rem; }
.infographic-cpassing .flow-spine {
position: absolute; left: 1.05rem; top: 1.2rem; bottom: 1.2rem; width: 2px; background: var(--line);
}
.infographic-cpassing .flow-dot {
position: absolute; left: 1.05rem; top: 1.2rem; width: 10px; height: 10px; margin-left: -4px;
border-radius: 50%; background: var(--accent); box-shadow: 0 0 0 4px var(--accent-soft);
transition: top 0.5s cubic-bezier(.4,0,.2,1); opacity: 0;
}
.infographic-cpassing .flow-dot.is-visible { opacity: 1; }
.infographic-cpassing .flow-step { position: relative; margin-bottom: 0.32rem; cursor: pointer; }
.infographic-cpassing .step-icon {
position: absolute; left: -2.6rem; top: 0.22rem; width: 1.9rem; height: 1.9rem;
border-radius: 50%; background: var(--paper); border: 2px solid var(--line);
font-size: 0.85rem; display: flex; align-items: center; justify-content: center;
transition: border-color 0.25s, background 0.25s, transform 0.35s;
}
.infographic-cpassing .flow-step.is-active .step-icon {
border-color: var(--accent); background: var(--accent-soft); animation: cpass-pop 0.5s ease;
}
@keyframes cpass-pop { 0% { transform: scale(1); } 40% { transform: scale(1.22); } 100% { transform: scale(1); } }
.infographic-cpassing .step-box {
padding: 0.4rem 0.65rem; border: 1px solid var(--line); border-radius: 7px;
font-size: 0.78rem; transition: border-color 0.25s, background 0.25s;
}
.infographic-cpassing .flow-step.is-active .step-box { border-color: var(--accent); background: var(--accent-soft); }
.infographic-cpassing .step-box .mini {
margin-top: 0.1rem; font-family: 'IBM Plex Mono', monospace; font-size: 0.72rem; color: var(--accent); font-weight: 600;
min-height: 1em;
}
/* memory / stack visual */
.infographic-cpassing .stack-panel {
position: sticky; top: 1rem;
border: 1px dashed var(--line);
border-radius: 10px;
padding: 0.6rem;
min-height: 150px;
display: flex;
flex-direction: column-reverse;
gap: 0.4rem;
}
.infographic-cpassing .frame {
border-radius: 7px;
padding: 0.45rem 0.6rem;
font-family: 'IBM Plex Mono', monospace;
font-size: 0.72rem;
background: var(--paper-alt);
border: 1px solid var(--line);
transition: border-color 0.3s, background 0.3s, box-shadow 0.3s;
}
.infographic-cpassing .frame .fname { font-weight: 700; margin-bottom: 0.15rem; }
.infographic-cpassing .frame .fline { color: var(--ink-soft); min-height: 1em; }
.infographic-cpassing .frame.is-active {
border-color: var(--accent); background: var(--accent-soft);
box-shadow: 0 3px 10px -4px rgba(0,0,0,0.25);
}
.infographic-cpassing .frame.is-changed {
border-color: var(--ok); background: var(--ok-soft);
}
.infographic-cpassing .frame.frame-modify {
opacity: 0; transform: translateY(10px) scale(0.94);
transition: opacity 0.35s ease, transform 0.35s ease;
max-height: 0; padding-top: 0; padding-bottom: 0; overflow: hidden; margin: 0;
}
.infographic-cpassing .frame.frame-modify.is-present {
opacity: 1; transform: translateY(0) scale(1); max-height: 5rem; padding: 0.45rem 0.6rem; margin: 0;
}
.infographic-cpassing .outcome-row { display: flex; align-items: center; gap: 0.5rem; margin-top: 0.5rem; }
.infographic-cpassing .outcome-tag {
font-size: 0.7rem; font-weight: 700; text-transform: uppercase; letter-spacing: 0.03em;
padding: 0.28rem 0.65rem; border-radius: 20px;
}
.infographic-cpassing .outcome-tag.unchanged { background: var(--warn-soft); color: var(--warn); }
.infographic-cpassing .outcome-tag.changed { background: var(--ok-soft); color: var(--ok); }
.infographic-cpassing .takeaway { font-size: 0.82rem; color: var(--ink-soft); margin-top: 1.1rem; border-top: 1px solid var(--line); padding-top: 0.85rem; }
.infographic-cpassing .takeaway strong { color: var(--ink); }
@media (prefers-reduced-motion: reduce) {
.infographic-cpassing * { transition: none !important; animation: none !important; }
}
</style>
<h1>🔁 Call by Value vs Call by Reference</h1>
<p class="subhead">Same doubling logic, two ways to pass <code style="font-family:'IBM Plex Mono',monospace;">num</code> in — watch which one actually changes it.</p>
<div class="chip-row" id="cpass-mode">
<button class="chip is-active" data-mode="value">Call by Value</button>
<button class="chip" data-mode="ref">Call by Reference</button>
</div>
<div class="code-panel" id="cpass-code"></div>
<div class="field-row">
<label>num starts at</label><input type="number" id="cpass-num" value="5">
<button class="ctrl-btn primary" id="cpass-play">▶ Play</button>
<button class="ctrl-btn" id="cpass-restart">⟲ Restart</button>
</div>
<div class="layout">
<div class="flow" id="cpass-flow">
<div class="flow-spine"></div>
<div class="flow-dot" id="cpass-dot"></div>
<div class="flow-step" data-step="0">
<div class="step-icon">🏁</div>
<div class="step-box">main() begins<div class="mini" id="mini-0"></div></div>
</div>
<div class="flow-step" data-step="1">
<div class="step-icon">📞</div>
<div class="step-box">Calls modify(...)<div class="mini" id="mini-1"></div></div>
</div>
<div class="flow-step" data-step="2">
<div class="step-icon">🚪</div>
<div class="step-box">Enters modify()<div class="mini" id="mini-2"></div></div>
</div>
<div class="flow-step" data-step="3">
<div class="step-icon">🔧</div>
<div class="step-box">Doubles the value<div class="mini" id="mini-3"></div></div>
</div>
<div class="flow-step" data-step="4">
<div class="step-icon">↩️</div>
<div class="step-box">modify() ends<div class="mini">frame pops</div></div>
</div>
<div class="flow-step" data-step="5">
<div class="step-icon">🖨️</div>
<div class="step-box">Back in main()<div class="mini" id="mini-5"></div></div>
</div>
</div>
<div class="stack-panel" id="cpass-stack">
<div class="frame frame-main">
<div class="fname">main()</div>
<div class="fline">num = <span id="cpass-num-val">5</span></div>
</div>
<div class="frame frame-modify" id="cpass-modframe">
<div class="fname">modify()</div>
<div class="fline" id="cpass-x-line">x = ?</div>
</div>
</div>
</div>
<div class="outcome-row" id="cpass-outcome" style="display:none;">
<span class="outcome-tag unchanged" id="cpass-tag">Unchanged</span>
<span id="cpass-outcome-text" style="font-size:0.8rem; color:var(--ink-soft);"></span>
</div>
<p class="takeaway"><strong>The rule:</strong> pass by value hands the function a copy — it can only change its own copy. Pass by reference hands it the address — it reaches back and changes the original.</p>
</div>
<script>
(function () {
const wrapper = document.currentScript.closest('.infographic-cpassing')
|| document.querySelector('.infographic-cpassing');
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 CODE = {
value: [
{ id: 'decl', html: '<span class="syn-keyword">void</span> <span class="syn-func">modify</span>(<span class="syn-keyword">int</span> x) {' },
{ id: 'body', html: ' x = x * 2;' },
{ id: 'close', html: '}' },
{ id: 'blank', html: ' ' },
{ id: 'main', html: '<span class="syn-keyword">int</span> <span class="syn-func">main</span>() {' },
{ id: 'numdecl', html: ' <span class="syn-keyword">int</span> num = 5;' },
{ id: 'call', html: ' <span class="syn-func">modify</span>(num);' },
{ id: 'printf', html: ' <span class="syn-func">printf</span>(<span class="syn-string">"%d"</span>, num);' },
{ id: 'mclose', html: '}' }
],
ref: [
{ id: 'decl', html: '<span class="syn-keyword">void</span> <span class="syn-func">modify</span>(<span class="syn-keyword">int</span> *x) {' },
{ id: 'body', html: ' *x = *x * 2;' },
{ id: 'close', html: '}' },
{ id: 'blank', html: ' ' },
{ id: 'main', html: '<span class="syn-keyword">int</span> <span class="syn-func">main</span>() {' },
{ id: 'numdecl', html: ' <span class="syn-keyword">int</span> num = 5;' },
{ id: 'call', html: ' <span class="syn-func">modify</span>(&num);' },
{ id: 'printf', html: ' <span class="syn-func">printf</span>(<span class="syn-string">"%d"</span>, num);' },
{ id: 'mclose', html: '}' }
]
};
const LINE_MAP = { 0: 'numdecl', 1: 'call', 2: 'decl', 3: 'body', 4: 'close', 5: 'printf' };
let mode = 'value';
const codePanel = $('#cpass-code');
const modeChips = wrapper.querySelectorAll('#cpass-mode .chip');
const numInput = $('#cpass-num');
const numValEl = $('#cpass-num-val');
const modFrame = $('#cpass-modframe');
const mainFrame = wrapper.querySelector('.frame-main');
const xLine = $('#cpass-x-line');
const outcomeRow = $('#cpass-outcome');
const outcomeTag = $('#cpass-tag');
const outcomeText = $('#cpass-outcome-text');
const steps = Array.from(wrapper.querySelectorAll('#cpass-flow .flow-step'));
const dot = $('#cpass-dot');
const flowList = $('#cpass-flow');
const playBtn = $('#cpass-play');
const restartBtn = $('#cpass-restart');
function renderCode() {
codePanel.innerHTML = CODE[mode].map(line =>
'<span class="code-line" data-line="' + line.id + '">' + line.html + '</span>'
).join('\n');
}
function highlightLine(lineId) {
codePanel.querySelectorAll('.code-line').forEach(l => {
l.classList.toggle('is-highlight', l.dataset.line === lineId);
});
}
function moveDotTo(step) {
const icon = step.querySelector('.step-icon');
const top = icon.offsetTop + icon.offsetHeight / 2 - flowList.offsetTop;
dot.style.top = top + 'px';
dot.classList.add('is-visible');
}
function startNum() { return parseInt(numInput.value, 10) || 0; }
function resetVisual() {
steps.forEach(s => s.classList.remove('is-active'));
dot.classList.remove('is-visible');
modFrame.classList.remove('is-present', 'is-active');
mainFrame.classList.remove('is-active', 'is-changed');
numValEl.textContent = startNum();
xLine.textContent = 'x = ?';
outcomeRow.style.display = 'none';
wrapper.querySelectorAll('.mini[id^="mini-"]').forEach(m => m.textContent = '');
codePanel.querySelectorAll('.code-line').forEach(l => l.classList.remove('is-highlight'));
}
function applyStep(index) {
const start = startNum();
const doubled = start * 2;
steps.forEach(s => s.classList.remove('is-active'));
steps[index].classList.add('is-active');
moveDotTo(steps[index]);
highlightLine(LINE_MAP[index]);
mainFrame.classList.remove('is-active');
modFrame.classList.remove('is-active');
if (index === 0) {
mainFrame.classList.add('is-active');
numValEl.textContent = start;
$('#mini-0').textContent = 'num = ' + start;
} else if (index === 1) {
mainFrame.classList.add('is-active');
$('#mini-1').textContent = mode === 'value' ? 'copies the value in' : 'passes the address (&num)';
} else if (index === 2) {
modFrame.classList.add('is-present', 'is-active');
xLine.textContent = mode === 'value' ? ('x = ' + start + ' (a copy)') : ('x = &num (points to num)');
$('#mini-2').textContent = mode === 'value' ? 'x is a separate copy' : 'x holds num\u2019s address';
} else if (index === 3) {
modFrame.classList.add('is-present', 'is-active');
if (mode === 'value') {
xLine.textContent = 'x = ' + doubled + ' (a copy)';
$('#mini-3').textContent = 'only the copy changes';
} else {
xLine.textContent = 'x = &num (points to num)';
numValEl.textContent = doubled;
mainFrame.classList.add('is-changed');
$('#mini-3').textContent = 'writes straight through to num';
}
} else if (index === 4) {
modFrame.classList.remove('is-present', 'is-active');
if (mode === 'ref') mainFrame.classList.add('is-changed');
} else if (index === 5) {
mainFrame.classList.add('is-active');
const finalNum = mode === 'value' ? start : doubled;
numValEl.textContent = finalNum;
$('#mini-5').textContent = 'num = ' + finalNum;
outcomeRow.style.display = 'flex';
if (mode === 'value') {
outcomeTag.textContent = 'Unchanged';
outcomeTag.className = 'outcome-tag unchanged';
outcomeText.textContent = 'prints ' + start + ' — the original num never moved.';
} else {
outcomeTag.textContent = 'Changed';
outcomeTag.className = 'outcome-tag changed';
mainFrame.classList.add('is-changed');
outcomeText.textContent = 'prints ' + doubled + ' — modify() reached back and changed num.';
}
}
}
let idx = -1;
let timer = null;
let playing = false;
function stop() {
playing = false;
clearTimeout(timer);
playBtn.disabled = false;
playBtn.textContent = '▶ Play';
}
function advance() {
idx++;
if (idx >= steps.length) { stop(); return; }
applyStep(idx);
if (idx >= steps.length - 1) stop();
else timer = setTimeout(advance, 1200);
}
function play() {
if (playing) return;
if (idx >= steps.length - 1) restart();
playing = true;
playBtn.disabled = true;
playBtn.textContent = '⏸ Playing…';
advance();
}
function restart() {
clearTimeout(timer);
playing = false;
idx = -1;
playBtn.disabled = false;
playBtn.textContent = '▶ Play';
resetVisual();
}
steps.forEach((step, i) => {
step.addEventListener('click', () => {
clearTimeout(timer);
playing = false;
playBtn.disabled = false;
playBtn.textContent = '▶ Play';
idx = i;
resetVisual();
for (let s = 0; s <= i; s++) applyStep(s);
});
});
modeChips.forEach(chip => {
chip.addEventListener('click', () => {
modeChips.forEach(c => c.classList.remove('is-active'));
chip.classList.add('is-active');
mode = chip.dataset.mode;
renderCode();
restart();
});
});
numInput.addEventListener('input', restart);
playBtn.addEventListener('click', play);
restartBtn.addEventListener('click', restart);
renderCode();
restart();
})();
</script>