Operators & Expressions
Operators are how C actually does anything to your data — arithmetic, comparisons, logic and bit-level tricks all come down to a fairly small set of symbols whose precedence rules you need to internalize, not memorize on the fly.
Operators are the mechanism C uses to actually do anything with data — every calculation, comparison, assignment, and logical decision a program makes comes down to a fairly small set of symbols. This page starts from the smallest pieces (what counts as an operator, an operand, an expression) and builds up through every operator family C has, finishing with the precedence and evaluation-order rules that decide what a line with several operators in it actually does.
What an operator is
An operator is a symbol or keyword that tells C to carry out a specific operation on some data.
Every operator on this page falls into one of a handful of families like these — arithmetic, comparison and logic, and assignment being the three broadest.
arithmetic: + - * / %
comparison: == != > < && || !
assignment: = += -= *=What an operand is
An operand is the value or object an operator actually acts on.
Here x and 10 are the two operands, and * is the operator combining them.
a + b
| | |
operand operand
operatorWhat an expression is
An expression is a combination of operands and operators that C evaluates according to its rules, and every expression produces a value.
10 + 20 evaluates to 30. a > b evaluates to an integer representing whether the comparison held true or false — every one of these is an expression, whether or not its value ends up stored anywhere.
10 + 20
a * b
x > 10
a == b
x = 50Walking through a simple expression
a + b is evaluated first, producing 30, and only then does that value get assigned into result.
int a = 10;
int b = 20;
int result = a + b;a = 10
b = 20
10 + 20
|
v
30
result = 30The main families of C operators
Several of these — pointer-related, member access, array subscript — only really make sense once pointers, structures, and arrays have their own topics; they're listed here for completeness and get picked back up properly later.
Operators
|-- Arithmetic + - * / %
|-- Increment/decrement ++ --
|-- Relational < > <= >=
|-- Equality == !=
|-- Logical && || !
|-- Assignment = += -= *= /= %=
|-- Bitwise & | ^ ~ << >>
|-- Conditional ?:
|-- Pointer-related & *
|-- Member access . ->
|-- Array subscript []
|-- Function call ()
`-- Other sizeof, _Alignof/alignof, comma ,Arithmetic operators
With a = 20 and b = 6: sum is 26, difference is 14, product is 120, quotient is 3, and remainder is 2.
+ Addition
- Subtraction
* Multiplication
/ Division
% Remainderint a = 20;
int b = 6;
int sum = a + b;
int difference = a - b;
int product = a * b;
int quotient = a / b;
int remainder = a % b;Integer division
This gives 3, not 3.333333 — when both operands of / are integers, the result is computed as integer division, and any fractional part is simply discarded.
Making at least the operands floating-point (10.0 and 3.0 instead of 10 and 3) gives approximately 3.333333 instead. The type of the operands is what decides which kind of division actually happens.
int result = 10 / 3;double result = 10.0 / 3.0;The remainder operator %
This gives 2, because 17 = 5 x 3 + 2 — % hands back whatever is left over after the closest integer division.
Checking a number modulo 2 for zero is the standard way to test evenness.
% is only defined for integer operands — there's no floating-point remainder using this operator.
int result = 17 % 5;if (number % 2 == 0)
{
/* even */
}Unary operators
A unary operator acts on exactly one operand.
y ends up as -10. Compare this with a + b, which takes two operands and is therefore a binary operation, not a unary one.
-x
+x
!x
~x
++x
--xint x = 10;
int y = -x;The increment operator ++
x becomes 11. It can equally be written ++x; — both forms increase x by one, but they differ in an important way once the expression's own value gets used somewhere, covered in the next two sections.
int x = 10;
x++;Prefix increment
x is incremented first, becoming 11, and that new value is what gets used as the expression's result — so both x and y end up as 11.
int x = 10;
int y = ++x;Postfix increment
Here, the old value of x is what the expression evaluates to — 10, stored into y — and only afterward does x itself become 11.
Mixing up prefix and postfix is an easy mistake to make precisely because the two forms look nearly identical — always check whether the surrounding expression actually uses the incremented value before or after the increment happens.
int x = 10;
int y = x++;x++:
use old value -> 10
|
increment x
|
x = 11The decrement operator --
x becomes 9. Like ++, it comes in both prefix (--x) and postfix (x--) forms, and the same before/after distinction applies whenever the expression's value gets used.
int x = 10;
x--;Relational operators
In C, a relational expression produces an int: 1 for true, 0 for false — so result ends up holding 1 here. There's no separate boolean type doing this work under the hood.
< Less than
> Greater than
<= Less than or equal
>= Greater than or equalint result = (10 > 5);Equality operators
== checks whether two values compare equal, and != checks whether they compare unequal. Here result is 1, since 10 does equal 10.
int a = 10;
int b = 10;
int result = (a == b);= versus ==
This mix-up is one of the most common mistakes anyone makes learning C, precisely because the two operators look so similar and both are completely valid in an if condition.
This compiles just fine, but it isn't a comparison — it assigns 10 to x and then uses that resulting value (10, which is nonzero and therefore true) as the condition, so the branch always runs regardless of what x held before.
The fix is almost always to write if (x == 10) instead — worth double-checking any time an if condition looks suspiciously like it's always true.
x = 10; // assignment: store 10 into x
x == 10; // comparison: is x equal to 10?if (x = 10)Logical operators
C provides three logical operators — &&, ||, and ! — used mainly to combine or negate conditions.
Logical AND &&
age >= 18 && age <= 60 is only true when both individual comparisons are true.
int age = 25;
if (age >= 18 && age <= 60)
{
printf("Valid age");
}age >= 18 -> true
age <= 60 -> true
true && true
|
trueLogical OR ||
|| is true as soon as at least one side is true.
if (age < 18 || age > 60)
{
printf("Outside range");
}A B A || B
0 0 0
0 1 1
1 0 1
1 1 1Logical NOT !
! reverses the logical interpretation of whatever it's applied to.
In a boolean context, C treats zero as false and any nonzero value as true. Since x is 10 (nonzero), !x is false, so this branch never runs.
!0 // produces 1
!1 // produces 0int x = 10;
if (!x)
{
printf("Zero");
}Short-circuit evaluation
&& and || both stop evaluating as soon as the overall result is already decided. For A && B, if A is false, B is never evaluated at all — the answer has to be false either way. For A || B, if A is true, B is skipped for the same reason.
If ptr == NULL, the left side is already false, so *ptr == 10 is never evaluated — the deeper reasons this matters specifically for pointers get their full treatment in the Pointers topic, but the short-circuit behavior itself applies to && and || everywhere they're used.
if (ptr != NULL && *ptr == 10)
{
...
}The assignment operator =
= stores a value into a modifiable object — the right-hand side is fully evaluated first, and only then is the resulting value stored into x.
int x;
x = 50;Compound assignment operators
These shorthand forms aren't purely a textual stand-in for the longer version in every technical sense — there are real details around how many times x itself gets evaluated and what conversions apply, which matter more once x is something more complex than a plain variable.
x += 5; // roughly: x = x + 5;
x -= 5; // roughly: x = x - 5;
x *= 5; // roughly: x = x * 5;Bitwise operators
Bitwise operators — &, |, ^, ~, <<, and >> — work on the actual bits of an integer's representation, which makes them fundamentally different from the logical operators &&, ||, and !, even though some of the symbols look similar at a glance.
Mixing up && with & (or || with |) rarely causes a compile error, since both are usually legal C in the same spot — which is exactly what makes the mistake easy to miss. && and || work on truth values and short-circuit; & and | work bit by bit on the full value and always evaluate both sides.
Bitwise AND &
12 & 10 gives 8 — each bit of the result is 1 only where both operands had a 1 in that position.
12 = 1100
10 = 1010
----
& 1000Bitwise OR |
12 | 10 gives 14 — each result bit is 1 wherever either operand had a 1 there.
12 = 1100
10 = 1010
----
| 1110Bitwise XOR ^
12 ^ 10 gives 6 — XOR sets a result bit to 1 exactly where the two operands' bits differ.
12 = 1100
10 = 1010
----
^ 0110Bitwise NOT ~
~ flips every bit of its operand — every 0 becomes a 1, and every 1 becomes a 0.
The exact decimal result of ~x depends heavily on the operand's type and how signed integers are represented on that implementation — it's better to reason about ~ bit by bit than to try to memorize a fixed decimal outcome.
Left shift <<
For suitable nonnegative values, shifting left by 2 corresponds to this bit pattern, giving 12.
Don't treat shifting as a universal stand-in for multiplying or dividing by powers of two — signedness, the shift amount, and whether the result is even representable all come with real rules that matter once the values involved aren't small and nonnegative.
int x = 3;
int result = x << 2;3 = 0011
0011 << 2
1100 (12)Right shift >>
For an unsigned integer, right-shifting fills the vacated high bits with zero.
For signed integers, right-shifting a negative value is implementation-defined in important cases — signed right shifts are one spot where it genuinely pays to be careful rather than assume.
int x = 12;
int result = x >> 2;1100 >> 2
|
0011The conditional operator ?:
The conditional operator is C's only ternary operator — the only one that takes three operands.
age >= 18 is true, so result becomes 1 — expression1's value. If the condition had been false, result would instead take expression2's value.
condition ? expression1 : expression2int age = 20;
int result = (age >= 18) ? 1 : 0;A more natural use of ?:
This entire if/else can be written as one line:
?: is genuinely useful for short, self-contained choices like this one, but nesting several of them together tends to hurt readability fast — a plain if/else is usually clearer once more than one condition is involved.
if (a > b)
max = a;
else
max = b;max = (a > b) ? a : b;The sizeof operator
sizeof works on a type name just as well as on an object, and the result always has type size_t.
For an ordinary expression whose type is known at compile time, sizeof normally doesn't actually evaluate that expression — it only needs the type. Variable-length arrays are a special case with their own rules, covered when arrays get their own topic.
int x;
printf("%zu", sizeof(x));sizeof(int)Address and indirection operators
&x means "the address of x," and *p means "the object p points to." Both operators depend heavily on context — the Pointers topic is where they get their full, proper treatment.
int x = 10;
int *p = &x;Member access operators
. accesses a member of a structure or union object directly, while -> is used to access a member through a pointer to a structure or union instead. Both get covered properly once structures and pointers have their own topics.
person.ageThe array subscript operator []
[] accesses one element of an array. Its deeper connection to pointer arithmetic is worth understanding once the Arrays and Pointers topics are covered — for now, it's enough to recognize it as "give me the element at this position."
int numbers[5];
numbers[0]
numbers[1]
numbers[2]The function call operator ()
The parentheses here form a function call expression — and like any expression, a function call produces a value that can be used inside a larger expression, exactly as add(10, 20)'s result is used above.
printf("Hello");
result = add(10, 20);Operator precedence
Does C compute (10 + 5) * 2, or 10 + (5 * 2)? Multiplication has higher precedence than addition, so it's the latter: 5 * 2 is 10, then 10 + 10 gives 20.
int result = 10 + 5 * 2;A simplified precedence table
This is simplified for learning purposes — reach for the full, precise C precedence table once you're regularly working through genuinely complex expressions.
highest
postfix: () [] . ->
unary: ++ -- ! ~ + - sizeof & *
* / %
+ -
<< >>
< <= > >=
== !=
&
^
|
&&
||
?:
assignments
,
lowestLetting parentheses do the explaining
Parentheses cost nothing and remove any doubt about which grouping was intended — reaching for them is rarely a bad call, even when the precedence rules alone would have given the right answer anyway.
result = a + b * c; // relies on precedence
result = a + (b * c); // says the same thing, explicitly
result = (a + b) * c; // a genuinely different groupingAssociativity
Precedence decides which operator binds tighter; associativity decides how operators of the same precedence group together.
Subtraction associates left to right, so this groups as (a - b) - c.
Assignment, by contrast, associates right to left, grouping conceptually as a = (b = (c = 10)) — though chained assignments like this are only worth using while they stay genuinely easy to read.
a - b - ca = b = c = 10;Expressions can nest
a + b and c - d are each their own smaller expressions, combined into one larger one — exactly the kind of structure precedence and parentheses exist to make unambiguous.
int result = (a + b) * (c - d);*
/ \
+ -
/ \ / \
a b c dExpressions have types
An expression is never just a value in isolation — it has a type too, and C's conversion rules lean on that type to decide how operands combine and what the result's own type ends up being.
int a = 10;
int b = 20;
a + b // has type intdouble x = 10.0;
double y = 20.0;
x + y // has type doubleImplicit conversions in expressions
a and b start out as different types, so C converts a to double before the addition happens. The precise rules behind this are called integer promotions and the usual arithmetic conversions — worth knowing by name even before every detail sinks in.
int a = 10;
double b = 2.5;
double result = a + b;int 10
| conversion
double 10.0
10.0 + 2.5
|
12.5Integer promotions
Smaller integer types like char and short are commonly promoted to int (or occasionally unsigned int) before taking part in an expression — so this addition isn't really performed as "char plus char," it's performed as int plus int. This is exactly why an expression's type can end up different from its operands' declared types.
char a = 10;
char b = 20;
int result = a + b;Unsigned arithmetic wraps around
Unsigned integer arithmetic has well-defined, modulo-style behavior. For an unsigned type with N value bits, the maximum representable value is 2^N - 1, and adding one more wraps straight back around to zero.
x wraps around to the maximum value unsigned int can hold, rather than becoming negative — unsigned types simply have no negative values to fall into. This is a genuinely different situation from signed integer overflow, which is undefined behavior rather than a well-defined wraparound.
unsigned int x = 0;
x--;Evaluation order isn't the same thing as precedence
Precedence tells you how an expression is grouped — which operators bind to which operands. It does not, in general, tell you the order in which every part of the expression actually gets evaluated.
The + operator says how the two results get combined, but C doesn't generally guarantee f() runs before g() or the other way around. Don't confuse precedence (grouping) with evaluation order (sequencing) — they answer two different questions.
f() + g()Expressions to avoid writing
Modifying the same object more than once inside one expression, when the evaluations involved aren't clearly sequenced relative to each other, is genuinely dangerous territory.
This isn't a valid way to get a predictable result out of C — it's undefined behavior, not just "unusual."
Prefer plain, separate statements like these instead. Clear, boring code is safer than a clever one-liner that depends on evaluation-order details the language doesn't actually promise.
i = i++ + ++i;i++;
i++;A complete example
One short program, and already several operator families show up together: arithmetic (+ - * / %), relational (>), logical (&&), equality (!=), and assignment (=).
#include <stdio.h>
int main(void)
{
int a = 20;
int b = 6;
int sum = a + b;
int difference = a - b;
int product = a * b;
int quotient = a / b;
int remainder = a % b;
printf("Sum: %d\n", sum);
printf("Difference: %d\n", difference);
printf("Product: %d\n", product);
printf("Quotient: %d\n", quotient);
printf("Remainder: %d\n", remainder);
if (a > b && b != 0)
{
printf("Condition is true\n");
}
return 0;
}Operator, expression, and statement aren't the same thing
+ alone is just an operator. a + b is a complete expression, since it evaluates to a value. result = a + b; is a statement — an expression followed by a semicolon.
+ -> operator
a + b -> expression
result = a + b; -> statementQuick reference
Arithmetic + - * / %
Increment/decrement ++ --
Relational < > <= >=
Equality == !=
Logical && || !
Assignment = += -= *= /= %=
Bitwise & | ^ ~ << >>
Conditional ?:
Size sizeof
Member access . ->
Array access []
Function call ()
Address/indirection & *
Comma ,What to carry forward
The operator families most worth mastering first, roughly in the order they'll come up: arithmetic, assignment, relational, equality, logical, increment and decrement, bitwise, the conditional operator, sizeof, precedence and associativity together, type conversions inside expressions, and finally evaluation order — the one rule that isn't precedence at all, but gets confused with it constantly.
An operator is a symbol that performs an operation on one or more values (operands). C groups them into arithmetic (+ - * / %), relational (== != < > <= >=), logical (&& || !), assignment (= += -= etc.), and bitwise (& | ^ ~ << >>) operators.
Every meaningful computation — adding a total, checking if a login succeeded, deciding whether to loop again — is built from operators combined into expressions. Understanding precedence (which operator 'binds tighter') prevents an entire category of subtle logic bugs.
Literally everywhere — a shopping cart total (+), a password check (== and &&), a game's collision detection (< and >), and low-level flag manipulation in device drivers (& | << all bitwise).
Think of operators like the operations on a calculator, but with a strict rulebook for what happens first when several are mixed in one expression — exactly like how in ordinary arithmetic, multiplication is done before addition even if addition is written first.
Precedence, modulus, and logical AND Three expressions show arithmetic precedence, the modulus (remainder) operator, and a logical AND combining two comparisons into one true/false result.
a + b * 2 is evaluated as a + (b * 2) because * binds tighter than +, giving 10 + 6 = 16, not (10+3)*2 = 26.
a % b computes the remainder of 10 divided by 3, which is 1 (3 goes into 10 three times, leaving 1).
(a > 5) evaluates first to 1 (true, since 10 > 5), and (b < 5) evaluates to 1 (true, since 3 < 5).
&& combines the two 1s: since both sides are true, the whole expression evaluates to 1, which printf displays as the integer 1 (C has no separate boolean type before C99's _Bool).
Short-circuit evaluation in action Demonstrates why short-circuiting isn't just an optimization — here it actively prevents a division by zero from ever happening.
a != 0 evaluates first and is false (a is 0), so && already knows the whole expression must be false.
Because of short-circuiting, risky(10 / a) is never called at all — 'risky(...)' never prints, and the division by zero inside it never executes.
The program simply prints 'done' — proof that the right-hand side of && was skipped entirely, not evaluated and then ignored.
int x = 5; if (x = 10) { printf("matched"); } int x = 5; if (x == 10) { printf("matched"); }
A single = assigns 10 to x and the if then tests the assigned value (10, which is truthy) — so 'matched' prints even though x was never actually equal to 10 beforehand. == is the comparison operator; = is assignment.
int average = (a + b) / 2; // a, b are int, e.g. 3 and 4 double average = (a + b) / 2.0;
When both operands of / are int, the division truncates — (3 + 4) / 2 gives 3, not 3.5. Making at least one operand a double (2.0 instead of 2) forces real decimal division.
Integer division truncates toward zero: 7 / 2 gives 3, not 3.5 — if either operand is a float or double, the division produces a real decimal result instead.
&& and || short-circuit: in (a() && b()), if a() returns false, b() is never even called, since the overall result is already determined — this is relied on constantly to guard against null-pointer dereferences.
Bitwise operators (& | ^ ~ << >>) operate on the individual binary bits of an integer, completely independently of the logical operators (&& || !), which operate on truth values — mixing them up (using & where you meant &&) is one of the most common C bugs.
Compound assignment operators (+=, -=, *=, /=, %=) are shorthand: x += 5 means exactly x = x + 5, just more concise and, in some cases, marginally faster to compile.
Writing if (x = 5) instead of if (x == 5) — a single = is assignment, not comparison, and this compiles fine (assigning 5 to x, which is then treated as 'true' since it's nonzero) while silently doing the wrong thing.
Confusing & (bitwise AND) with && (logical AND) — if (flags & 0x01 && flags & 0x02) usually works by luck, but using a single & where a logical test was intended can produce wrong results for values other than 0/1.
Forgetting that integer division truncates — average = (a + b) / 2 silently drops the fractional part when a and b are both int.
Assuming operator precedence you're not 100% sure of instead of just adding parentheses — parentheses cost nothing and remove all doubt, for you and for anyone reading the code later.
Using compound assignment operators (total += price;) as the default habit for accumulator-style code — it reads cleaner and is instantly recognizable.
Adding explicit parentheses around mixed arithmetic and comparison expressions even when you know the precedence rules, purely for the next reader's sake.
Relying on && and ||'s short-circuit behavior deliberately, e.g. if (ptr != NULL && ptr->value > 0) — the null check must come first, and short-circuiting guarantees the second half never runs if ptr is null.
The full precedence and associativity table C defines a strict precedence order (roughly: unary operators, then * / %, then + -, then shifts, then relational, then equality, then bitwise, then logical, then the ternary, then assignment) and an associativity direction (left-to-right or right-to-left) for operators of equal precedence. Assignment is right-associative, which is exactly why a = b = c works: it's parsed as a = (b = c).
Sequence points and undefined evaluation order C famously does not guarantee the order in which a function's arguments, or the two sides of most binary operators, are evaluated. An expression like i++ + i++ has undefined behavior precisely because the compiler is free to evaluate the two increments in either order — a classic C interview trap and a real source of portability bugs.
What's the output of 7 / 2 and 7.0 / 2 in C?
7 / 2 is integer division and gives 3 (the fractional part is truncated). 7.0 / 2 involves a double operand, so the whole expression is computed as floating-point division and gives 3.5.
Why is if (x = 5) legal C, and why is it dangerous?
It's legal because = is a valid expression (assignment) that itself evaluates to the assigned value, and if only requires an expression that can be tested as true/false. It's dangerous because it's almost always a typo for == and silently always evaluates as true (since 5 is nonzero), masking a logic bug.
What does short-circuit evaluation mean for && and ||?
For &&, if the left operand is false, the right operand is never evaluated (the result must be false). For ||, if the left operand is true, the right operand is never evaluated (the result must be true). This is relied on to safely guard expressions that would otherwise be unsafe to evaluate unconditionally.
What's the difference between an operator, an operand, and an expression?
An operator is the symbol that performs an action (+, ==, =); an operand is a value or object that operator acts on; an expression is the combination of operands and operators evaluated together, which always produces a value — a + b is an expression built from two operands and one operator.
Why does a relational expression like a > b produce an int in C rather than some distinct boolean type?
C has no built-in boolean type for relational results — every relational or equality expression evaluates to an int, specifically 1 for true or 0 for false, which is why that result can be stored in an ordinary int or used directly wherever a number is expected.
What's the difference between operator precedence and evaluation order, and why does confusing them cause bugs?
Precedence decides how an expression is grouped — which operands bind to which operator. Evaluation order decides the sequence in which the pieces are actually computed. C's precedence rules don't generally guarantee an evaluation order, so something like f() + g() doesn't promise f() runs before g() just because + is left-to-right on the page.
Why should you avoid writing an expression like i = i++ + ++i;?
It modifies i more than once without the evaluations being clearly sequenced relative to each other, which is undefined behavior in C — not just unusual or compiler-dependent. Separate, simple statements always produce a predictable result; a clever one-liner like this one doesn't.
What's the practical difference between && and &, and why is mixing them up an easy mistake to miss?
&& is a logical operator that short-circuits and works on truth values; & is a bitwise operator that always evaluates both sides and works bit by bit on the full value. They're easy to confuse specifically because both are often legal C in the same spot, so swapping one for the other rarely produces a compile error — it just silently changes what the code does.
What does result hold, and why?
3 — with two integer operands, / performs integer division and simply discards the fractional part, rather than rounding.
What does this print?
2 — 17 divided by 5 goes in 3 times with 2 left over, and % returns exactly that remainder.
What do x and y end up holding?
Both end up as 11 — prefix ++ increments x first, and the already-updated value is what gets used as the expression's result and stored into y.
y ends up as 10 and x ends up as 11 — postfix x++ uses the old value for the expression first, then increments x afterward.
What's wrong with this condition, and what did the author most likely mean to write?
This assigns 10 to x rather than comparing it — the condition becomes the value 10 itself, which is nonzero and therefore always true, so the branch runs no matter what x held before. The intended code was almost certainly if (x == 10).
What does result hold?
20 — multiplication has higher precedence than addition, so 5 * 2 is computed first (giving 10), and then 10 + 10 gives 20.
The maximum value an unsigned int can hold on that platform (4294967295 on a typical 32-bit unsigned int) — decrementing an unsigned zero wraps around instead of going negative, since unsigned types can never represent a negative value.
What does max end up holding?
10 — a > b is false, so the conditional operator evaluates to its second operand, b, which becomes max's value.
Is this addition performed as char + char, or as something else?
As int + int. Integer promotions convert small integer types like char to int before they take part in most expressions, so the addition itself happens on two ints, not two chars — result correctly holds 30.
8 — 12 is 1100 in binary and 10 is 1010; bitwise AND keeps a 1 only where both operands have a 1 in that position, giving 1000, which is 8.
OPERAND + OPERATOR + OPERAND
|
EXPRESSION
|
EVALUATION
|
VALUE#include <stdio.h>
int main() {
int a = 10, b = 3;
printf("%d\n", a + b * 2); // precedence matters
printf("%d\n", a % b); // remainder
printf("%d\n", (a > 5) && (b < 5)); // logical AND
return 0;
}#include <stdio.h>
int risky(int x) {
printf("risky(%d) called\n", x);
return x > 0;
}
int main() {
int a = 0;
if (a != 0 && risky(10 / a)) {
printf("won't get here\n");
}
printf("done\n");
return 0;
}int result = 10 / 3;int result = 17 % 5;
printf("%d", result);int x = 10;
int y = ++x;int x = 10;
int y = x++;if (x = 10)
{
printf("matched");
}int result = 10 + 5 * 2;unsigned int x = 0;
x--;
printf("%u", x);