An operator is a symbol that tells the compiler to perform a specific operation on one, two, or more values.
We’ll break them into 7 main categories:
Category | Description |
|---|---|
➕ Arithmetic | Basic math operations |
📏 Relational | Compare values |
🔍 Logical | True/False-based conditions |
🧩 Assignment | Assign values to variables |
🔧 Unary | Work with only one operand |
🧮 Bitwise | Manipulate individual bits |
🧪 Miscellaneous |
|
➕ Arithmetic Operators
These perform basic math:
Operator | Description | Example | Result |
|---|---|---|---|
| Addition |
|
|
| Subtraction |
|
|
| Multiplication |
|
|
| Division |
|
|
| Modulus (Remainder) |
|
|
⚠️ Note:
If both operands are
int, division results in integer division.%works only on integers.
📌 Example:
int a = 10, b = 3;
printf("%d", a / b); // prints 3
printf("%d", a % b); // prints 1✏️ Expression:
int result = 10 + 2 * 3 - 4 / 2;🧠 Operator Precedence & Associativity in C
📌 Arithmetic Operators (Follow BODMAS)
BODMAS stands for:
Brackets
Orders (Exponents – not in C directly, but with
pow())Division
Multiplication
Addition
Subtraction
In C, arithmetic expressions follow similar precedence:
Precedence | Operator | Description | Associativity |
|---|---|---|---|
1 (High) |
| Parentheses (Brackets) | Left to Right |
2 |
| Multiplication, Division, Modulus | Left to Right |
3 |
| Addition, Subtraction | Left to Right |
🧮 Example Applying BODMAS/Precedence:
int result = 10 + 2 * 3 - 4 / 2;Step-by-step using precedence:
= 10 + 6 - 2 // First: 2*3 = 6 and 4/2 = 2
= 16 - 2 // Next: 10 + 6
= 14 // Finally: 16 - 2✅ Final Result: 14
🔢 Full C Operator Precedence Table (Grouped)
Precedence | Operators | Description | Associativity |
|---|---|---|---|
1 (Highest) |
| Function call, array subscript, structure/union member | Left to Right |
2 |
| Unary operators | Right to Left |
3 |
| Multiplication, division, modulus | Left to Right |
4 |
| Addition, subtraction | Left to Right |
5 |
| Bitwise shift left, right | Left to Right |
6 |
| Relational operators | Left to Right |
7 |
| Equality operators | Left to Right |
8 |
| Bitwise AND | Left to Right |
9 |
| Bitwise XOR | Left to Right |
10 |
| Bitwise OR | Left to Right |
11 |
| Logical AND | Left to Right |
12 |
| Logical OR | Left to Right |
13 |
| Ternary conditional | Right to Left |
14 |
| Assignment operators | Right to Left |
15 (Lowest) |
| Comma operator | Left to Right |
📏 Relational Operators (Comparison)
Used in conditions (if, while, etc.), return either:
1(true)0(false)
Operator | Meaning | Example | Output |
|---|---|---|---|
| Equal to |
| true if x is equal to y |
| Not equal |
| true if x is NOT equal to y |
| Greater than |
| true if x is greater than y |
| Less than |
| true if x is less than y |
| Greater or Equal |
| true if x ≥ y |
| Less or Equal |
| true if x ≤ y |
📌 Example:
int x = 5, y = 10;
printf("%d", x < y); // prints 1 (true)
printf("%d", x == y); // prints 0 (false🔍 **3. Logical Operators**🔍 Logical Operators
Used to combine multiple conditions:
Operator | Meaning | Example | Result |
|---|---|---|---|
| Logical AND |
| true only if both are true |
| Logical OR |
| true if even one is true |
| Logical NOT |
| reverses true/false |
📌 Example:
int age = 20;
if (age > 18 && age < 30) {
printf("You are young!");
}🧩 Assignment Operators
Used to assign values to variables:
Operator | Meaning | Equivalent To |
|---|---|---|
| Assign |
|
| Add & assign |
|
| Subtract & assign |
|
| Multiply & assign |
|
| Divide & assign |
|
| Modulo & assign |
|
📌 Example:
int a = 5;
a += 2; // Now a is 🔧 Unary Operators
These work on only one operand:
Operator | Description | Example |
|---|---|---|
| Increment |
|
| Decrement |
|
| Negation |
|
| Logical NOT |
|
Prefix vs Postfix (++x vs x++)
int x = 5;
printf("%d", x++); // prints 5, then x becomes 6
printf("%d", ++x); // x becomes 7, then prints 7🧮 Bitwise Operators (Advanced, but powerful)
Used for bit-level operations, useful in:
Embedded systems
Hardware programming
Encryption algorithms
Operator | Name | Meaning |
|---|---|---|
| AND | Sets bit to 1 if both bits are 1 |
| OR | OR |
| XOR | Sets bit to 1 if bits are different |
| NOT | Inverts all bits |
| Left Shift | Shifts bits left (×2) |
| Right Shift | Shifts bits right (÷2) |
📌 Example:
int a = 5; // binary: 00000101
int b = 3; // binary: 00000011
printf("%d", a & b); // 00000001 → 1🧪 Miscellaneous Operators
🧱 sizeof Operator
Returns the size (in bytes) of a data type or variable.
printf("%d", sizeof(int)); // Usually prints 4❓ Ternary Operator
A shortcut for if-else.
📌 Syntax:
condition ? expression_if_true : expression_if_false;📌 Example:
int age = 18;
char *result = (age >= 18) ? "Adult" : "Minor";⛓️ Comma Operator
Allows multiple expressions in one line:
int a = (b = 3, b + 2); // b is 3, a becomes 5<div class="infographic-cops">
<style>
.infographic-cops {
--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-comment: #6a9955;
--warn-color: #e0a458;
--warn-soft: #4a3620;
}
.infographic-cops[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-cops {
box-sizing: border-box;
max-width: 780px;
margin: 0 auto;
background: var(--paper);
color: var(--ink);
font-family: 'Inter', -apple-system, sans-serif;
padding: 0 clamp(1.25rem, 5vw, 3rem);
}
.infographic-cops *, .infographic-cops *::before, .infographic-cops *::after {
box-sizing: border-box;
}
.infographic-cops h1 {
font-family: 'Fraunces', Georgia, serif;
font-weight: 600;
font-size: clamp(1.6rem, 4vw, 2.2rem);
margin: 2rem 0 0.25rem;
}
.infographic-cops .subhead { color: var(--ink-soft); font-size: 0.95rem; margin-bottom: 1.5rem; }
.infographic-cops h2 {
font-family: 'Fraunces', Georgia, serif;
font-weight: 600;
font-size: 1.1rem;
margin: 0 0 0.85rem;
}
.infographic-cops section { margin-bottom: 2.25rem; }
.infographic-cops section + section { border-top: 1px solid var(--line); padding-top: 2rem; }
/* shared */
.infographic-cops .chip-row { display: flex; flex-wrap: wrap; gap: 0.5rem; margin-bottom: 0.9rem; }
.infographic-cops .chip {
all: unset;
cursor: pointer;
font-family: 'IBM Plex Mono', monospace;
font-size: 0.82rem;
font-weight: 600;
padding: 0.4rem 0.8rem;
border-radius: 20px;
border: 1px solid var(--line);
color: var(--ink-soft);
transition: background 0.2s, color 0.2s, border-color 0.2s;
}
.infographic-cops .chip:hover { border-color: var(--accent); }
.infographic-cops .chip.is-active { background: var(--accent); border-color: var(--accent); color: #fff; }
.infographic-cops .field-row { display: flex; align-items: center; gap: 0.6rem; flex-wrap: wrap; margin-bottom: 0.9rem; }
.infographic-cops .field-row label { font-size: 0.85rem; color: var(--ink-soft); }
.infographic-cops .field-row input[type="number"], .infographic-cops .field-row input[type="text"] {
font-family: 'IBM Plex Mono', monospace;
font-size: 0.92rem;
padding: 0.35rem 0.55rem;
border-radius: 6px;
border: 1px solid var(--line);
background: var(--paper);
color: var(--ink);
width: 5.5rem;
}
.infographic-cops .field-row input:focus { outline: 2px solid var(--accent); outline-offset: 1px; }
.infographic-cops .code-panel {
background: var(--code-bg);
color: var(--code-text);
border-radius: 8px;
padding: 0.9rem 1.1rem;
font-family: 'IBM Plex Mono', monospace;
font-size: 0.86rem;
line-height: 1.8;
margin-bottom: 0.9rem;
}
.infographic-cops .code-panel .code-line { white-space: pre; }
.infographic-cops .result-panel {
padding: 0.85rem 1.05rem;
background: var(--paper-alt);
border-radius: 8px;
font-size: 0.9rem;
color: var(--ink-soft);
line-height: 1.5;
}
.infographic-cops .result-panel strong { color: var(--accent); font-family: 'IBM Plex Mono', monospace; }
.infographic-cops .result-panel .note { display: block; margin-top: 0.4rem; font-size: 0.8rem; color: var(--warn-color); }
/* category panels */
.infographic-cops .cat-panel { display: none; }
.infographic-cops .cat-panel.is-active { display: block; animation: cops-fade 0.25s ease; }
@keyframes cops-fade { from { opacity: 0; transform: translateY(4px); } to { opacity: 1; transform: translateY(0); } }
/* binary display */
.infographic-cops .bin-row { display: flex; gap: 1.5rem; flex-wrap: wrap; margin-bottom: 0.9rem; }
.infographic-cops .bin-box { font-family: 'IBM Plex Mono', monospace; font-size: 0.8rem; }
.infographic-cops .bin-box small { display: block; color: var(--ink-soft); font-size: 0.7rem; text-transform: uppercase; margin-bottom: 0.25rem; }
.infographic-cops .bin-box span { letter-spacing: 0.12em; color: var(--ink); }
/* console (unary) */
.infographic-cops .console {
background: var(--code-bg);
color: var(--code-text);
border-radius: 8px;
padding: 0.85rem 1.1rem;
font-family: 'IBM Plex Mono', monospace;
font-size: 0.85rem;
min-height: 3rem;
margin-bottom: 0.9rem;
max-height: 9rem;
overflow-y: auto;
}
.infographic-cops .console .line { opacity: 0.9; }
.infographic-cops .btn-row { display: flex; gap: 0.5rem; flex-wrap: wrap; margin-bottom: 0.9rem; }
.infographic-cops .btn {
all: unset;
cursor: pointer;
font-family: 'IBM Plex Mono', monospace;
font-size: 0.8rem;
font-weight: 600;
padding: 0.4rem 0.8rem;
border-radius: 6px;
background: var(--accent);
color: #fff;
}
.infographic-cops .btn:hover { opacity: 0.88; }
.infographic-cops .btn.secondary { background: var(--paper-alt); color: var(--ink); border: 1px solid var(--line); }
.infographic-cops .x-state { font-family: 'IBM Plex Mono', monospace; font-size: 0.95rem; margin-bottom: 0.9rem; }
.infographic-cops .x-state strong { color: var(--accent); }
/* misc sub-widgets */
.infographic-cops .misc-widget { margin-bottom: 1.75rem; }
.infographic-cops .misc-widget h3 {
font-size: 0.95rem;
font-weight: 600;
margin: 0 0 0.6rem;
}
.infographic-cops .misc-widget:last-child { margin-bottom: 0; }
.infographic-cops .takeaway { font-size: 0.95rem; color: var(--ink-soft); }
.infographic-cops .takeaway strong { color: var(--ink); }
@media (prefers-reduced-motion: reduce) {
.infographic-cops * { transition: none !important; animation: none !important; }
}
</style>
<h1>🧮 C Operators Playground</h1>
<p class="subhead">Pick a category, plug in values, watch C actually evaluate it.</p>
<div class="chip-row" id="cops-tabs">
<button class="chip is-active" data-cat="arith">➕ Arithmetic</button>
<button class="chip" data-cat="rel">📏 Relational</button>
<button class="chip" data-cat="logic">🔍 Logical</button>
<button class="chip" data-cat="assign">🧩 Assignment</button>
<button class="chip" data-cat="unary">🔧 Unary</button>
<button class="chip" data-cat="bit">🧮 Bitwise</button>
<button class="chip" data-cat="misc">🧪 Misc</button>
</div>
<!-- Arithmetic -->
<div class="cat-panel is-active" data-cat="arith">
<div class="chip-row" id="arith-mode">
<button class="chip is-active" data-mode="int">int</button>
<button class="chip" data-mode="float">float</button>
</div>
<div class="field-row">
<label>a</label><input type="number" id="arith-a" value="10">
<label>b</label><input type="number" id="arith-b" value="3">
</div>
<div class="chip-row" id="arith-ops">
<button class="chip is-active" data-op="+">+</button>
<button class="chip" data-op="-">-</button>
<button class="chip" data-op="*">*</button>
<button class="chip" data-op="/">/</button>
<button class="chip" data-op="%">%</button>
</div>
<div class="code-panel"><span class="code-line" id="arith-code"></span></div>
<div class="result-panel"><span id="arith-result"></span><span class="note" id="arith-note"></span></div>
</div>
<!-- Relational -->
<div class="cat-panel" data-cat="rel">
<div class="field-row">
<label>x</label><input type="number" id="rel-a" value="5">
<label>y</label><input type="number" id="rel-b" value="10">
</div>
<div class="chip-row" id="rel-ops">
<button class="chip is-active" data-op="==">==</button>
<button class="chip" data-op="!=">!=</button>
<button class="chip" data-op=">">></button>
<button class="chip" data-op="<"><</button>
<button class="chip" data-op=">=">>=</button>
<button class="chip" data-op="<="><=</button>
</div>
<div class="code-panel"><span class="code-line" id="rel-code"></span></div>
<div class="result-panel"><span id="rel-result"></span></div>
</div>
<!-- Logical -->
<div class="cat-panel" data-cat="logic">
<div class="field-row">
<label>Condition A</label>
<button class="chip is-active" id="logic-a-toggle" data-val="true">true</button>
<label id="logic-b-label">Condition B</label>
<button class="chip is-active" id="logic-b-toggle" data-val="true">true</button>
</div>
<div class="chip-row" id="logic-ops">
<button class="chip is-active" data-op="&&">&&</button>
<button class="chip" data-op="||">||</button>
<button class="chip" data-op="!">!</button>
</div>
<div class="code-panel"><span class="code-line" id="logic-code"></span></div>
<div class="result-panel"><span id="logic-result"></span></div>
</div>
<!-- Assignment -->
<div class="cat-panel" data-cat="assign">
<div class="field-row">
<label>a starts at</label><input type="number" id="assign-a" value="5">
<label>value</label><input type="number" id="assign-b" value="3">
</div>
<div class="chip-row" id="assign-ops">
<button class="chip is-active" data-op="=">=</button>
<button class="chip" data-op="+=">+=</button>
<button class="chip" data-op="-=">-=</button>
<button class="chip" data-op="*=">*=</button>
<button class="chip" data-op="/=">/=</button>
<button class="chip" data-op="%=">%=</button>
</div>
<div class="code-panel"><span class="code-line" id="assign-code"></span></div>
<div class="result-panel"><span id="assign-result"></span></div>
</div>
<!-- Unary -->
<div class="cat-panel" data-cat="unary">
<div class="field-row">
<label>Start x at</label><input type="number" id="unary-start" value="5">
<button class="btn secondary" id="unary-reset">Reset</button>
</div>
<div class="x-state">Current x = <strong id="unary-x-display">5</strong></div>
<div class="btn-row">
<button class="btn" data-action="post-inc">Run printf(x++)</button>
<button class="btn" data-action="pre-inc">Run printf(++x)</button>
<button class="btn" data-action="post-dec">Run printf(x--)</button>
<button class="btn" data-action="pre-dec">Run printf(--x)</button>
</div>
<div class="console" id="unary-console"></div>
</div>
<!-- Bitwise -->
<div class="cat-panel" data-cat="bit">
<div class="field-row">
<label>a</label><input type="number" id="bit-a" value="5">
<label>b</label><input type="number" id="bit-b" value="3">
</div>
<div class="chip-row" id="bit-ops">
<button class="chip is-active" data-op="&">&</button>
<button class="chip" data-op="|">|</button>
<button class="chip" data-op="^">^</button>
<button class="chip" data-op="~">~</button>
<button class="chip" data-op="<<"><<</button>
<button class="chip" data-op=">>">>></button>
</div>
<div class="bin-row">
<div class="bin-box"><small>a</small><span id="bit-a-bin"></span></div>
<div class="bin-box"><small>b</small><span id="bit-b-bin"></span></div>
<div class="bin-box"><small>result</small><span id="bit-r-bin"></span></div>
</div>
<div class="code-panel"><span class="code-line" id="bit-code"></span></div>
<div class="result-panel"><span id="bit-result"></span></div>
</div>
<!-- Misc -->
<div class="cat-panel" data-cat="misc">
<div class="misc-widget">
<h3>🧱 sizeof</h3>
<div class="chip-row" id="sizeof-types">
<button class="chip is-active" data-type="char">char</button>
<button class="chip" data-type="short">short</button>
<button class="chip" data-type="int">int</button>
<button class="chip" data-type="long">long</button>
<button class="chip" data-type="float">float</button>
<button class="chip" data-type="double">double</button>
</div>
<div class="code-panel"><span class="code-line" id="sizeof-code"></span></div>
</div>
<div class="misc-widget">
<h3>❓ Ternary</h3>
<div class="field-row">
<label>age</label><input type="number" id="ternary-age" value="18">
</div>
<div class="code-panel"><span class="code-line">char *result = (age >= 18) ? "Adult" : "Minor";</span></div>
<div class="result-panel"><span id="ternary-result"></span></div>
</div>
<div class="misc-widget">
<h3>⛓️ Comma Operator</h3>
<div class="field-row">
<label>b =</label><input type="number" id="comma-b" value="3">
<label>+</label><input type="number" id="comma-extra" value="2">
</div>
<div class="code-panel"><span class="code-line" id="comma-code"></span></div>
<div class="result-panel"><span id="comma-result"></span></div>
</div>
</div>
<p class="takeaway"><strong>Same rule everywhere:</strong> C evaluates strictly by precedence and type — every result above follows directly from those two things.</p>
</div>
<script>
(function () {
const wrapper = document.currentScript.closest('.infographic-cops')
|| document.querySelector('.infographic-cops');
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); }
function $$(sel) { return wrapper.querySelectorAll(sel); }
function chipGroup(sel, attr, onChange) {
const chips = wrapper.querySelectorAll(sel + ' .chip');
chips.forEach(chip => {
chip.addEventListener('click', () => {
chips.forEach(c => c.classList.remove('is-active'));
chip.classList.add('is-active');
onChange(chip.dataset[attr]);
});
});
return chips;
}
function activeVal(sel, attr) {
const el = wrapper.querySelector(sel + ' .chip.is-active');
return el ? el.dataset[attr] : null;
}
// ---- Category tabs ----
const tabs = wrapper.querySelectorAll('#cops-tabs .chip');
const panels = wrapper.querySelectorAll('.cat-panel');
tabs.forEach(tab => {
tab.addEventListener('click', () => {
tabs.forEach(t => t.classList.remove('is-active'));
tab.classList.add('is-active');
panels.forEach(p => p.classList.toggle('is-active', p.dataset.cat === tab.dataset.cat));
});
});
// ---- Arithmetic ----
function updateArith() {
const isFloat = activeVal('#arith-mode', 'mode') === 'float';
const rawA = parseFloat($('#arith-a').value) || 0;
const rawB = parseFloat($('#arith-b').value) || 0;
const a = isFloat ? rawA : Math.trunc(rawA);
const b = isFloat ? rawB : Math.trunc(rawB);
const op = activeVal('#arith-ops', 'op');
let result, note = '';
switch (op) {
case '+': result = a + b; break;
case '-': result = a - b; break;
case '*': result = a * b; break;
case '/':
if (b === 0) { result = NaN; note = 'Division by zero.'; break; }
result = isFloat ? a / b : Math.trunc(a / b);
if (!isFloat && (a % b !== 0)) note = 'Integer division — decimal part dropped.';
break;
case '%':
if (b === 0) { result = NaN; note = 'Division by zero.'; break; }
result = a % b;
break;
}
const type = isFloat ? 'float' : 'int';
const displayResult = isFloat ? (Number.isInteger(result) ? result.toFixed(1) : result.toPrecision(6).replace(/0+$/, '')) : result;
$('#arith-code').innerHTML = '<span class="syn-keyword">' + type + '</span> a = ' + (isFloat ? a.toFixed(1) : a) +
', b = ' + (isFloat ? b.toFixed(1) : b) + ';\n<span class="syn-keyword">' + type + '</span> result = a ' + op + ' b;';
$('#arith-result').innerHTML = 'result = <strong>' + displayResult + '</strong>';
$('#arith-note').textContent = note;
}
chipGroup('#arith-mode', 'mode', updateArith);
chipGroup('#arith-ops', 'op', updateArith);
$('#arith-a').addEventListener('input', updateArith);
$('#arith-b').addEventListener('input', updateArith);
// ---- Relational ----
function updateRel() {
const a = parseFloat($('#rel-a').value) || 0;
const b = parseFloat($('#rel-b').value) || 0;
const op = activeVal('#rel-ops', 'op');
let result;
switch (op) {
case '==': result = a === b; break;
case '!=': result = a !== b; break;
case '>': result = a > b; break;
case '<': result = a < b; break;
case '>=': result = a >= b; break;
case '<=': result = a <= b; break;
}
$('#rel-code').innerHTML = '<span class="syn-keyword">int</span> x = ' + a + ', y = ' + b + ';\nprintf(<span class="syn-comment">"%d"</span>, x ' + op + ' y);';
$('#rel-result').innerHTML = 'prints <strong>' + (result ? 1 : 0) + '</strong> (' + (result ? 'true' : 'false') + ')';
}
chipGroup('#rel-ops', 'op', updateRel);
$('#rel-a').addEventListener('input', updateRel);
$('#rel-b').addEventListener('input', updateRel);
// ---- Logical ----
function updateLogic() {
const op = activeVal('#logic-ops', 'op');
const aBtn = $('#logic-a-toggle');
const bBtn = $('#logic-b-toggle');
const bLabel = $('#logic-b-label');
const isUnary = op === '!';
bBtn.style.display = isUnary ? 'none' : '';
bLabel.style.display = isUnary ? 'none' : '';
const a = aBtn.dataset.val === 'true';
const b = bBtn.dataset.val === 'true';
let result, exprCode;
if (op === '&&') { result = a && b; exprCode = 'A && B'; }
else if (op === '||') { result = a || b; exprCode = 'A || B'; }
else { result = !a; exprCode = '!A'; }
$('#logic-code').innerHTML = '<span class="syn-keyword">int</span> A = ' + (a ? 1 : 0) + (isUnary ? '' : ', B = ' + (b ? 1 : 0)) + ';\nprintf(<span class="syn-comment">"%d"</span>, ' + exprCode.replace('A', 'A').replace('B', 'B') + ');';
$('#logic-result').innerHTML = 'prints <strong>' + (result ? 1 : 0) + '</strong> (' + (result ? 'true' : 'false') + ')';
}
[$('#logic-a-toggle'), $('#logic-b-toggle')].forEach(btn => {
btn.addEventListener('click', () => {
const cur = btn.dataset.val === 'true';
btn.dataset.val = cur ? 'false' : 'true';
btn.textContent = cur ? 'false' : 'true';
btn.classList.toggle('is-active', !cur);
updateLogic();
});
});
chipGroup('#logic-ops', 'op', updateLogic);
// ---- Assignment ----
function updateAssign() {
const a = parseFloat($('#assign-a').value) || 0;
const b = parseFloat($('#assign-b').value) || 0;
const op = activeVal('#assign-ops', 'op');
let result;
switch (op) {
case '=': result = b; break;
case '+=': result = a + b; break;
case '-=': result = a - b; break;
case '*=': result = a * b; break;
case '/=': result = b === 0 ? NaN : Math.trunc(a / b); break;
case '%=': result = b === 0 ? NaN : a % b; break;
}
$('#assign-code').innerHTML = '<span class="syn-keyword">int</span> a = ' + a + ';\na ' + op + ' ' + b + ';';
$('#assign-result').innerHTML = 'a is now <strong>' + result + '</strong>';
}
chipGroup('#assign-ops', 'op', updateAssign);
$('#assign-a').addEventListener('input', updateAssign);
$('#assign-b').addEventListener('input', updateAssign);
// ---- Unary ----
let xState = parseInt($('#unary-start').value, 10) || 0;
const xDisplay = $('#unary-x-display');
const consoleEl = $('#unary-console');
function logLine(text) {
const line = document.createElement('div');
line.className = 'line';
line.textContent = text;
consoleEl.appendChild(line);
consoleEl.scrollTop = consoleEl.scrollHeight;
}
function updateXDisplay() { xDisplay.textContent = xState; }
$('#unary-reset').addEventListener('click', () => {
xState = parseInt($('#unary-start').value, 10) || 0;
updateXDisplay();
consoleEl.innerHTML = '';
});
wrapper.querySelectorAll('[data-action]').forEach(btn => {
btn.addEventListener('click', () => {
const action = btn.dataset.action;
if (action === 'post-inc') { logLine('printf(x++) → prints ' + xState); xState++; }
else if (action === 'pre-inc') { xState++; logLine('printf(++x) → prints ' + xState); }
else if (action === 'post-dec') { logLine('printf(x--) → prints ' + xState); xState--; }
else if (action === 'pre-dec') { xState--; logLine('printf(--x) → prints ' + xState); }
updateXDisplay();
});
});
// ---- Bitwise ----
function toBin8(n) {
return ((n & 0xFF) >>> 0).toString(2).padStart(8, '0');
}
function updateBit() {
const a = parseInt($('#bit-a').value, 10) || 0;
const b = parseInt($('#bit-b').value, 10) || 0;
const op = activeVal('#bit-ops', 'op');
let result, exprCode;
switch (op) {
case '&': result = a & b; exprCode = 'a & b'; break;
case '|': result = a | b; exprCode = 'a | b'; break;
case '^': result = a ^ b; exprCode = 'a ^ b'; break;
case '~': result = ~a; exprCode = '~a'; break;
case '<<': result = a << b; exprCode = 'a << b'; break;
case '>>': result = a >> b; exprCode = 'a >> b'; break;
}
$('#bit-a-bin').textContent = toBin8(a);
$('#bit-b-bin').textContent = toBin8(b);
$('#bit-r-bin').textContent = toBin8(result);
$('#bit-code').innerHTML = '<span class="syn-keyword">int</span> a = ' + a + ', b = ' + b + ';\nprintf(<span class="syn-comment">"%d"</span>, ' + exprCode + ');';
$('#bit-result').innerHTML = 'result = <strong>' + result + '</strong> <span style="color:var(--ink-soft);">(showing last 8 bits above)</span>';
}
chipGroup('#bit-ops', 'op', updateBit);
$('#bit-a').addEventListener('input', updateBit);
$('#bit-b').addEventListener('input', updateBit);
// ---- Misc: sizeof ----
const SIZES = { char: 1, short: 2, int: 4, long: 8, float: 4, double: 8 };
function updateSizeof() {
const type = activeVal('#sizeof-types', 'type');
$('#sizeof-code').innerHTML = 'printf(<span class="syn-comment">"%zu"</span>, <span class="syn-func">sizeof</span>(<span class="syn-keyword">' + type + '</span>)); <span class="syn-comment">// prints ' + SIZES[type] + '</span>';
}
chipGroup('#sizeof-types', 'type', updateSizeof);
// ---- Misc: ternary ----
function updateTernary() {
const age = parseFloat($('#ternary-age').value) || 0;
const result = age >= 18 ? 'Adult' : 'Minor';
$('#ternary-result').innerHTML = 'result = <strong>"' + result + '"</strong>';
}
$('#ternary-age').addEventListener('input', updateTernary);
// ---- Misc: comma ----
function updateComma() {
const b = parseFloat($('#comma-b').value) || 0;
const extra = parseFloat($('#comma-extra').value) || 0;
const a = b + extra;
$('#comma-code').innerHTML = '<span class="syn-keyword">int</span> a = (b = ' + b + ', b + ' + extra + ');';
$('#comma-result').innerHTML = 'b = <strong>' + b + '</strong>, a = <strong>' + a + '</strong> <span style="color:var(--ink-soft);">(a takes the last expression's value)</span>';
}
$('#comma-b').addEventListener('input', updateComma);
$('#comma-extra').addEventListener('input', updateComma);
// ---- init ----
updateArith();
updateRel();
updateLogic();
updateAssign();
updateXDisplay();
updateBit();
updateSizeof();
updateTernary();
updateComma();
})();
</script>