Operators in C languages
Operator characteristics
- Operators are actions that run over operands, giving a particular result.
- Expressions are arbitrarily complex compositions of operand and operator.
- Operators can be applied to one operand (unary operator) or to two operands (binary operators).
- There is also one operator with three operands, which is ? : (explained later).
Example:
int result = (a < b) ? a : b; // the ternary operator returns 10 because a is less than b
Aritmetics operators
| Operator | Using | Description |
|---|---|---|
| + | op1+op2 | addition of two numbers |
| - | op1-op2 | subtraction two numbers |
| * | op1*op2 | Multiplication of two numbers op1 and op2 |
| / | op1/op2 | Division two numbers |
| % | op1%op2 | Calculates the rest of division of two numbers |
Solution:
scanf(" %lf%lf ", &R1, &R2); //The user enters R1 and R2
Re=R1*R2 / (R1+R2); // The solution obtained is given by the equation
printf("%f",Re);
The rest of the division of two numbers. Operator "%"
Suppose we want to divide two integer values: 7 & 3
If we write 7/3 we get for result 2. The result is an integer because we have divided two integer constants
If we want to get the rest of the division then we would use the operator %
7 % 3 = 1
Example: Load time in minutes and print as mm: ss
scanf(" %d ", &Vr); //The user inputs time in seconds
/*Suppose the user entered during the 132s. Since one minute has 60s,
of these 132s we will convert 2 * 60s in two minutes, and what remains to be put as a second, in this
example it's 132- (2 * 60) = 12s. This calculation can be obtained using the division operator and the remainder of the division, "/" and "%". */
mm=Vr / 60; // mm=132/60=2
ss=Vr % 60; // mm=132%60=12
printf("%2d : %2d",mm,ss);
| The data type for the result | Data type for values |
|---|---|
| long | None of the values is float or double (whole number artifacts), a At least one of the operators is long type |
| int | None of the values is float or double (integer arithmetic). No operand is long. |
| double | At least one value is double type |
| float | At least one value is a float type. None is double type |
Unary operators "++", "-"
Relational and conditional operators
| Operator | Usage | Returns true if |
|---|---|---|
| > | op1 > op2 | op1 is greater than op2 |
| >= | op1 >= op2 | op1 is greater than or equal to op2 |
| < | op1 < op2 | op1 is less than op2 |
| <= | op1 <= op2 | op1 is less than or equal to op2 |
| == | op1 == op2 | op1 is equal to op2 |
| != | op1 != op2 | op1 is not equal to op2 |
An example of relational operators
printf("a is greater than b");
}
| Operator | Usage | Returns true if |
|---|---|---|
| && | op1 && op2 | Both op1 and op2 are true. op2 is evaluated only if op1 is true (short-circuit). |
| || | op1 || op2 | Either op1 or op2 is true, or both. op2 is evaluated only if op1 is false (short-circuit). |
| ! | !op | op is false. |
| & | op1 & op2 | Both op1 and op2 are true. Always evaluates both operands (bitwise AND). |
| | | op1 | op2 | Either op1 or op2 is true, or both. Always evaluates both operands (bitwise OR). |
| ^ | op1 ^ op2 | op1 and op2 are different — one is true, the other is false (bitwise XOR). |
Examples of logical operators:
bool x = true;
bool y = false;
bool rezultat = (x && y); // the result is false because both expressions are not true
Example: For the set values of integer variables a, b, c, determine the values of logical expressions:
a = 4, b = 7, c = 11
a > b
! (a > b && !(b < c))
a != 0 || !(a > (b > c))
The values of the logical expressions in the C language are in fact integers. This expression evaluates to 1 if the logical expression is true, and 0 if it is false.
If 3 integers are defined with values 4, 7, and 11, the values of the required logical expressions will be:
a > b // value 0, because 4 is not greater than 7
! (a > b && !(b < c)) // value 1
! ((4 > 7) && !(7 < 11)) = !((0) && (1)) = !(0) = 1
a != 0 || !(a > (b > c)) // value 1
4 != 0 || (4 > (7 > 11))
(4 != 0) || (4 > (7 > 11))
(1) || (4 > (0))
1 || 1 = 1
The displayed brackets show the order in which the operators are executed. Operators with the highest priority (>, <) are executed first, followed by &&, and finally the negation (!). For example:
// Step by step evaluation:
4 > 7 // 0 (false)
7 < 11 // 1 (true)
0 && 1 // 0
! (0) // 1
Therefore, a != 0 || !(a > (b > c)) evaluates to 1:
4 != 0 || (4 > (7 > 11))
(4 != 0) || (4 > 0)
1 || 1
= 1
Solution of this example:
// Summary of logical expression values:
a > b // 0
! (a > b && !(b < c)) // 1
a != 0 || !(a > (b > c)) // 1
#include <iostream>
using namespace std;
int main()
{
int a, b, c;
bool e, f, g;
a = 4;
b = 7;
c = 11;
// Calculating Logical Expressions
e = a > b;
f = !(a > b && !(b < c));
g = a != 0 || !(a > (b > c));
// Print the expression value
cout << "e=" << e << endl;
cout << "f=" << f << endl;
cout << "g=" << g << endl;
return 0;
}
Operators by bit
- operators to perform logical operations between pairs of bits on the same positions within their operands
- shift operators
- ~ It performs complementing (negating) the value of its operand by bit. Thus, it converts from state 0 to state 1 and vice versa
- & Logical "and" for bit operations.
- | Logic included "or" for bit operations.
- ^ Logic exclusively "or" for bit operations.
- << It moves the left operand for as many binary places as the right-hand value of the right operand
- >> Moving the left operand for as many binary places to the right is the value of the right operand. Moving to the right of the n position is equivalent to dividing the number with 2 ^ n
Examples for operators by bits
- 25 & 5 = 1 0000000000011001 &
0000000000000001
- 25 | 5 = 29 0000000000011001 |
0000000000011101
- 25 ^ 5 = 28 0000000000011001 ^
0000000000011100
- 25 << 2 = 100 0000000000011001 <<2 =
- 25 >> 3 = 3 0000000000011001 &
0000000000000011
Assignment operator
| Operator | Using | Equivalent to: |
|---|---|---|
| += | op1 += op2 | op1 = op1 + op2 |
| -= | op1 -= op2 | op1 = op1 - op2 |
| *= | op1 *= op2 | op1 = op1 * op2 |
| /= | op1 /= op2 | op1 = op1 / op2 |
| %= | op1 %= op2 | op1 = op1 % op2 |
| &= | op1 &= op2 | op1 = op1 & op2 |
| |= | op1 |= op2 | op1 = op1 | op2 |
| ^= | op1 ^= op2 | op1 = op1 ^ op2 |
For instance:
int N=28;
N=N<<3;
The starting number 28 will be transformed to number 224 and this value is assigned to the same memory N.
- 28 << 3 = 224 0000000000011100 <<2 =
Difference between relational and logical operators
- Relational operators perform a comparison between two values, and the result of the comparison is a logical value (true or false). For example, is the number a greater than b.
- Logical operators combine or negate logical values. They do not work directly on numeric values like relational operators, but on results that are already true or false.
int b = 20;
int c = 15;
// First we use relational operators to get boolean values
bool condition1= (a < b); // true because 10 is less than 20
bool condition2= (c == 15); // true because c is equal to 15
// We then use logical operators to combine the results
bool finalResult = condition1 && condition2; // true because both conditions are true
The other operators in C, C++
Conditional expression: ? :
For entered integers a and b, specify a greater number.
We reserve the memory for 3 data, and b and larger than the two will be placed in the new variable maxAB.
int a,b,maxAB;
The user then enters a and b from the console:
scanf("%d%d", &a, &b);
To assign a value of maxAB, two variants are possible:
maxAB = a; if a >= b or
maxAB = b, if a < b
If you put both variants, the first value of the maxAB would be, and later it would change to b and it would always be b.
It is first necessary to ask whether a> b, and if it is true then maxAB = a is executed, otherwise maxAB = b;
For this, the conditional expression is used:
maxAB=(a>b) ? a : b;
Finally, this value should be displayed:
printf("maxAB=%d", maxAB);
SIZEOF operator
#include <stdlib.h>
int main(int argc, char *argv[])
{
char b;
short c;
long d;
long long e;
unsigned long int f;
printf("\nEnter the integer value a="); scanf("%d", &a);
printf("\nEnter the integer value b="); scanf("%d", &b);
printf("\nEnter the integer value c="); scanf("%d", &c);
printf("\nEnter the integer value d="); scanf("%d", &d);
printf("\nEnter the integer value e="); scanf("%d", &e);
printf("\nEnter the integer value f="); scanf("%d", &f);
printf("\nLength of data int is %d byte and this is equal a=%d bajta", sizeof(int), sizeof(a));
printf("\nLength of data char is %d byte and this is equal b=%d bajta", sizeof(char), sizeof(b));
printf("\nLength of data short is %d byte and this is equal c=%d bajta", sizeof(short), sizeof(c));
printf("\nLength of data long is %d byte and this is equal d=%d bajta", sizeof(long), sizeof(d));
printf("\nLength of data long long is %d byte and this is equal e=%d bajta", sizeof(long long), sizeof(e));
printf("\nLength of data unsigned long int is %d bajta byte and this is equal f=%d bajta", sizeof(unsigned long int), sizeof(d));
return 0;
Comma operator ","
Other operators
| Operator | description of operators |
|---|---|
| [] | Indexing |
| () | call function |
| . | access to the member (element) of the structure |
| -> | access to the member (element) of the structure using pointers |
| *(unary) | access to data by pointers (indirect addressing) |
| &(unary) | variable address |
Operator Priority Table
The table below describes the order of priorities and association of operators in C / C ++. The advantage of the operator decreases from top to bottom.
| Priority | Number of operands | Grouping Direction: | Operators: |
|---|---|---|---|
| 15 | 2 | -> | [] () . -> |
| 14 | 1 | -> | ! ~ ++ -- + - * & (tip) sizeof |
| 13 | 2 | -> | * / % |
| 12 | 2 | -> | + - |
| 11 | 2 | -> | << >> |
| 10 | 2 | -> | < <= > >= |
| 9 | 2 | -> | == != |
| 8 | 2 | -> | & |
| 7 | 2 | -> | ^ |
| 6 | 2 | -> | | |
| 5 | 2 | -> | && |
| 4 | 2 | -> | || |
| 3 | 2 | -> | ?: |
| 2 | 2 | -> | = += -= *= /= %= &= ^= |= <<= >>= |
| 1 | 2 | -> | , |
Advanced topic — additional operators and examples
This section adds explanations for bitwise operators, assignment and compound assignment operators,
sizeof, casts and the comma operator. Short examples show typical uses and common pitfalls.
Bitwise operators
Bitwise operators operate bit-by-bit (usually on integer types):
& (AND), | (OR), ^ (XOR), ~ (NOT),
<< (left shift) and >> (right shift). They are commonly used for masking,
testing bits and combining flags. For predictable shift behavior prefer unsigned types.
// example: masking and testing bits
unsigned int flags = 0x5; // ...0101b
// test: is bit 0 set?
if (flags & 0x1) { /* bit 0 is 1 */ }
// set bit 2
flags |= (1u << 2);
// clear bit 0
flags &= ~(1u << 0);
// XOR to toggle selected bits
flags ^= (1u << 1);
Note: Right shifts on signed types can be implementation-defined — prefer unsigned when shifting for predictable behavior.
Assignment and compound assignment operators
Basic assignment is =. Compound assignment operators combine an operation and assignment:
+=, -=, *=, /=, %=, &=, |=, ^=, <<=, >>=. They often avoid repeating the variable name and can be more efficient.
int x = 10;
x += 5; // same as x = x + 5;
x &= 0xF; // mask lower 4 bits
sizeof, casts and the comma operator
sizeof returns the size (in bytes) of a type or object. Casts use the syntax (type)value.
The comma operator , evaluates the left operand, then the right, and returns the right value — useful in some idioms but reduces readability.
int a = 0;
// print size of int (use %zu for portability)
printf("size of int: %zu\n", sizeof(int));
double d = 3.14;
int di = (int)d; // explicit cast: truncates fractional part
// comma operator example
int v = (a = 1, a + 2); // a=1 then v = a+2 => v == 3
Advanced topic — logical vs bitwise operators, promotions and undefined behavior
Difference between logical and bitwise operators
&& and || are logical operators: they treat operands as boolean values and have short-circuit behavior
(the second operand is evaluated only if needed). &, |, ^ are bitwise operators: they operate bit-by-bit
and always evaluate both operands. This difference is a common source of bugs.
int a = 0;
int b = 1;
if (a && (b++ > 0)) {
// here (b++ > 0) is NOT evaluated because a == 0 -> short-circuit
}
// b remains 1
if (a & (b++ > 0)) {
// here (b++ > 0) IS evaluated; & does not short-circuit
}
// b becomes 2
Integer promotions and usual arithmetic conversions (brief)
Expressions with different integer types follow promotion rules: smaller types (e.g. char, short) are usually promoted to int
(or unsigned int in some cases). Then usual arithmetic conversions determine a common type for the operation.
Mixing signed and unsigned types can lead to surprising results — prefer explicit casts when the intent must be clear.
unsigned short us = 60000;
int i = -1;
auto r = us + i;
// us may be promoted and the result is influenced by unsigned vs signed rules
Undefined behavior: modifying the same variable multiple times in one expression
Expressions that modify and read the same variable without sequencing between those accesses lead to undefined behavior. A classic confusing example:
int i = 1;
i = i++ + 1; // undefined behavior — result not defined by the standard
Write code explicitly and sequentially instead:
int i = 1;
int tmp = i;
i = tmp + 1; // clear and defined
// or simpler forms
i++;
i = i + 1; // or i += 1; depending on intent
Tip: avoid complex expressions that modify the same variable multiple times — they are hard to reason about and brittle across compilers/optimizations.
Technical sources — linking suggestions
I recommend adding authoritative references so readers can dig deeper and verify technical details.
Recommended sources
- cppreference (C) — logical operators — detailed page on logical operators in C: cppreference — C logical operators
- cppreference (C) — arithmetic operators — arithmetic operators and notes on integer division: cppreference — C arithmetic operators
- cppreference (C) — bitwise & other operators — bitwise operators and other operator pages: cppreference — C bitwise operators
- cppreference (C++) — operators — comprehensive coverage of operators in C++ (including overloading): cppreference — C++ operators
- cppreference (C++) — operator precedence — operator precedence table (useful for avoiding ambiguous expressions): cppreference — operator precedence
- Integer promotions / implicit conversions — rules that affect mixed-type integer expressions: cppreference — integer promotion (C) • cppreference — implicit conversions (C++)
- ISO/IEC 9899 (C standard) — the official standard for C (formal/authoritative; typically paid): ISO/IEC 9899 (C standard)
- Kernighan & Ritchie — The C Programming Language (K&R) — classic concise reference: K&R — Wikipedia (info & editions)
|
Previous
|< Data in C++ language |
Next
Selection statements >| |
Related articles
Podešavanja kolačića
Koristimo kolačiće da bismo vam pružili najbolje moguće iskustvo. Takođe nam omogućavaju da analiziramo ponašanje korisnika kako bismo stalno poboljšavali veb lokaciju za vas.