Skip to content

C Operators

An operator is a symbol that tells the compiler to perform a specific mathematical, logical, or manipulative action. C is rich in built-in operators, which can be broadly categorized as follows:

  • Arithmetic Operators
  • Relational Operators
  • Logical Operators
  • Bitwise Operators
  • Assignment Operators
  • Miscellaneous Operators (like sizeof, ternary ? :, address &, indirection *, comma ,)

This section provides an overview of these operators.

These perform standard mathematical calculations. Assume int A = 10; and int B = 21;

OperatorDescriptionExampleResult
+AdditionA + B31
-SubtractionB - A11
*MultiplicationA * B210
/DivisionB / A2 (Integer division truncates)
%Modulus (Remainder)B % A1 (Remainder of 21 / 10)
++Increment (adds 1)A++ (postfix) or ++A (prefix)Increments A to 11. Value of expression depends on prefix/postfix.
--Decrement (subtracts 1)A-- (postfix) or --A (prefix)Decrements A to 9. Value of expression depends on prefix/postfix.

Note on Modulus (%): For negative operands, the sign of the result was implementation-defined before C99. Since C99, the result has the same sign as the dividend (a % b has the sign of a).

These operators compare two values and return either 1 (true) or 0 (false). Assume int A = 10; and int B = 20;

OperatorDescriptionExampleResult
==Equal to(A == B)0 (false)
!=Not equal to(A != B)1 (true)
>Greater than(A > B)0 (false)
<Less than(A < B)1 (true)
>=Greater than or equal to(A >= B)0 (false)
<=Less than or equal to(A <= B)1 (true)

These operators combine or negate logical expressions (expressions that evaluate to true/non-zero or false/zero). They also return 1 (true) or 0 (false). Assume int A = 1; (true) and int B = 0; (false).

OperatorDescriptionExampleResult
&&Logical AND. Result is true only if both operands are true (non-zero). Uses short-circuiting.(A && B)0 (false)
||Logical OR. Result is true if at least one operand is true (non-zero). Uses short-circuiting.(A || B)1 (true)
!Logical NOT (unary). Reverses the logical state: makes true false, and false true.!(A && B)1 (true)

Short-circuiting: For &&, if the left operand is false, the right operand is not evaluated. For ||, if the left operand is true, the right operand is not evaluated.

These operators work directly on the individual bits of integer operands. Assume unsigned char A = 60; (0011 1100) and unsigned char B = 13; (0000 1101).

Truth Table for AND, OR, XOR:

pqp & q (AND)p | q (OR)p ^ q (XOR)
00000
01011
10011
11110

Bitwise Operations on A and B:

A = 0011 1100
B = 0000 1101
-----------------
A & B = 0000 1100 (Decimal 12)
A | B = 0011 1101 (Decimal 61)
A ^ B = 0011 0001 (Decimal 49)
~ A = 1100 0011 (Depends on type size and signedness, for unsigned char this is 195, for signed char might be -61)
OperatorDescriptionExampleResult (Decimal)
&Bitwise AND. Sets a bit if it exists in both operands.A & B12
|Bitwise OR (Inclusive OR). Sets a bit if it exists in either operand.A | B61
^Bitwise XOR (Exclusive OR). Sets a bit if it exists in one operand but not both.A ^ B49
~Bitwise NOT (Ones’ Complement) (unary). Flips all bits.~ADepends on type/size (e.g., 195 for unsigned char, -61 for typical 8-bit signed char)
<<Left Shift. Shifts bits left by specified number, filling with zeros.A << 2 (0011 1100 << 2 = 1111 0000)240
>>Right Shift. Shifts bits right. For unsigned types, fills with zeros (logical shift). For signed types, behavior is implementation-defined or arithmetic (fills with sign bit).A >> 2 (0011 1100 >> 2 = 0000 1111)15

These operators assign values to variables. The basic assignment is =. Compound assignment operators perform an operation and an assignment in one step.

OperatorExampleEquivalent To
=C = AAssigns value of A to C
+=C += AC = C + A
-=C -= AC = C - A
*=C *= AC = C * A
/=C /= AC = C / A
%=C %= AC = C % A
<<=C <<= 2C = C << 2
>>=C >>= 2C = C >> 2
&=C &= AC = C & A
|=C |= AC = C | A
^=C ^= AC = C ^ A

Other important operators:

OperatorDescriptionExample
sizeofReturns the size (in bytes) of a data type or a variable. Result type is size_t.sizeof(int), sizeof(myVariable)
&Address-of operator (unary). Returns the memory address of its operand (which must be an lvalue).&myVariable
*Indirection/Dereference operator (unary). Accesses the value stored at the address pointed to by a pointer operand.*pointerVariable
? :Ternary Conditional Operator. Syntax: condition ? value_if_true : value_if_false.max = (a > b) ? a : b;
,Comma Operator. Evaluates the first operand, discards the result, then evaluates the second operand. The result of the expression is the value of the second operand. Used often in for loops.for (i=0, j=10; i < j; ++i, --j)
[]Array Subscript Operator. Accesses an element in an array.myArray[5]
()Function Call Operator. Invokes a function.myFunction(arg1, arg2)
.Member Access Operator. Accesses a member of a struct or union variable.myStruct.member
->Pointer Member Access Operator. Accesses a member of a struct or union through a pointer.myStructPtr->member

Operator precedence determines the order in which operators are evaluated in an expression. Associativity determines the order when operators have the same precedence.

Example: In x = 7 + 3 * 2;, multiplication (*) has higher precedence than addition (+), so 3 * 2 is evaluated first, resulting in x = 7 + 6;, thus x becomes 13.

Use parentheses () to override precedence or to make the order of evaluation explicit and improve readability.

C Operator Precedence Table (Highest to Lowest):

CategoryOperatorAssociativity
Postfix/Suffix() [] -> . ++ --Left-to-right
Unary/Prefix+ - ! ~ ++ -- (type) * & sizeof _AlignofRight-to-left
Multiplicative* / %Left-to-right
Additive+ -Left-to-right
Shift<< >>Left-to-right
Relational< <= > >=Left-to-right
Equality== !=Left-to-right
Bitwise AND&Left-to-right
Bitwise XOR^Left-to-right
Bitwise OR|Left-to-right
Logical AND&&Left-to-right
Logical OR||Left-to-right
Conditional?:Right-to-left
Assignment= += -= *= /= %= <<= >>= &= ^= |=Right-to-left
Comma,Left-to-right