Introduction
Operators in C are special symbols that perform operations on operands (variables, constants, or expressions). They are fundamental building blocks that enable computation, comparison, logical operations, and data manipulation. Understanding operators and their precedence is essential for writing correct and efficient C programs.
Key Concepts
Operator: Symbol that performs specific operation on operands Operand: Data item on which operation is performed Precedence: Order in which operators are evaluated Associativity: Direction of evaluation for same precedence operators Unary Operator: Operates on single operand Binary Operator: Operates on two operands Ternary Operator: Operates on three operands
Categories of Operators
1. Arithmetic Operators
#include <stdio.h>
int main() {
int a = 15, b = 4;
float x = 15.0, y = 4.0;
printf("Arithmetic Operators Demo:\n");
printf("a = %d, b = %d\n", a, b);
// Basic arithmetic operations
printf("Addition: %d + %d = %d\n", a, b, a + b);
printf("Subtraction: %d - %d = %d\n", a, b, a - b);
printf("Multiplication: %d * %d = %d\n", a, b, a * b);
printf("Division: %d / %d = %d\n", a, b, a / b); // Integer division
printf("Modulus: %d %% %d = %d\n", a, b, a % b);
// Floating-point arithmetic
printf("\nFloating-point operations:\n");
printf("%.2f / %.2f = %.2f\n", x, y, x / y); // Float division
// Mixed operations
printf("\nMixed operations:\n");
printf("Integer/Float: %d / %.2f = %.2f\n", a, y, a / y);
return 0;
}
2. Relational Operators
#include <stdio.h>
int main() {
int a = 10, b = 20, c = 10;
printf("Relational Operators Demo:\n");
printf("a = %d, b = %d, c = %d\n", a, b, c);
// Comparison operations
printf("a == b: %d\n", a == b); // Equal to
printf("a != b: %d\n", a != b); // Not equal to
printf("a < b: %d\n", a < b); // Less than
printf("a > b: %d\n", a > b); // Greater than
printf("a <= c: %d\n", a <= c); // Less than or equal to
printf("a >= c: %d\n", a >= c); // Greater than or equal to
// Using in conditional statements
printf("\nConditional usage:\n");
if (a == c) {
printf("a and c are equal\n");
}
if (a < b) {
printf("a is less than b\n");
}
return 0;
}
3. Logical Operators
#include <stdio.h>
int main() {
int a = 5, b = 10, c = 0;
printf("Logical Operators Demo:\n");
printf("a = %d, b = %d, c = %d\n", a, b, c);
// Logical AND (&&)
printf("(a > 0) && (b > 0): %d\n", (a > 0) && (b > 0));
printf("(a > 0) && (c > 0): %d\n", (a > 0) && (c > 0));
// Logical OR (||)
printf("(a > 10) || (b > 5): %d\n", (a > 10) || (b > 5));
printf("(a > 10) || (c > 5): %d\n", (a > 10) || (c > 5));
// Logical NOT (!)
printf("!(a > b): %d\n", !(a > b));
printf("!c: %d\n", !c);
// Short-circuit evaluation
printf("\nShort-circuit evaluation:\n");
if (a > 0 && b/a > 1) { // b/a evaluated only if a > 0
printf("Both conditions are true\n");
}
return 0;
}
4. Assignment Operators
#include <stdio.h>
int main() {
int a, b, c;
printf("Assignment Operators Demo:\n");
// Simple assignment
a = 10;
printf("a = %d\n", a);
// Compound assignment operators
a += 5; // a = a + 5
printf("After a += 5: a = %d\n", a);
a -= 3; // a = a - 3
printf("After a -= 3: a = %d\n", a);
a *= 2; // a = a * 2
printf("After a *= 2: a = %d\n", a);
a /= 4; // a = a / 4
printf("After a /= 4: a = %d\n", a);
a %= 3; // a = a % 3
printf("After a %%= 3: a = %d\n", a);
// Multiple assignment
a = b = c = 20;
printf("Multiple assignment: a = %d, b = %d, c = %d\n", a, b, c);
return 0;
}
5. Increment and Decrement Operators
#include <stdio.h>
int main() {
int a = 5, b = 5, c, d;
printf("Increment/Decrement Operators Demo:\n");
printf("Initial: a = %d, b = %d\n", a, b);
// Pre-increment and post-increment
c = ++a; // Pre-increment: increment a, then assign to c
d = b++; // Post-increment: assign b to d, then increment b
printf("After c = ++a and d = b++:\n");
printf("a = %d, b = %d, c = %d, d = %d\n", a, b, c, d);
// Pre-decrement and post-decrement
a = 10; b = 10;
c = --a; // Pre-decrement: decrement a, then assign to c
d = b--; // Post-decrement: assign b to d, then decrement b
printf("\nAfter c = --a and d = b--:\n");
printf("a = %d, b = %d, c = %d, d = %d\n", a, b, c, d);
// In expressions
a = 5;
printf("\nIn expressions:\n");
printf("a = %d\n", a);
printf("2 * a++ = %d, a is now %d\n", 2 * a++, a);
printf("2 * ++a = %d, a is now %d\n", 2 * ++a, a);
return 0;
}
6. Bitwise Operators
#include <stdio.h>
void printBinary(int n) {
for (int i = 7; i >= 0; i--) {
printf("%d", (n >> i) & 1);
}
}
int main() {
int a = 12, b = 25; // a = 00001100, b = 00011001
printf("Bitwise Operators Demo:\n");
printf("a = %d (binary: ", a); printBinary(a); printf(")\n");
printf("b = %d (binary: ", b); printBinary(b); printf(")\n");
// Bitwise AND
int and_result = a & b;
printf("\nBitwise AND: %d & %d = %d (binary: ", a, b, and_result);
printBinary(and_result); printf(")\n");
// Bitwise OR
int or_result = a | b;
printf("Bitwise OR: %d | %d = %d (binary: ", a, b, or_result);
printBinary(or_result); printf(")\n");
// Bitwise XOR
int xor_result = a ^ b;
printf("Bitwise XOR: %d ^ %d = %d (binary: ", a, b, xor_result);
printBinary(xor_result); printf(")\n");
// Bitwise NOT
int not_a = ~a;
printf("Bitwise NOT: ~%d = %d\n", a, not_a);
// Left shift
int left_shift = a << 2;
printf("Left shift: %d << 2 = %d (binary: ", a, left_shift);
printBinary(left_shift); printf(")\n");
// Right shift
int right_shift = a >> 1;
printf("Right shift: %d >> 1 = %d (binary: ", a, right_shift);
printBinary(right_shift); printf(")\n");
return 0;
}
7. Conditional (Ternary) Operator
#include <stdio.h>
int main() {
int a = 10, b = 20;
printf("Conditional Operator Demo:\n");
// Basic ternary operator
int max = (a > b) ? a : b;
printf("Maximum of %d and %d is: %d\n", a, b, max);
// Nested ternary operators
int x = 15, y = 10, z = 20;
int largest = (x > y) ? ((x > z) ? x : z) : ((y > z) ? y : z);
printf("Largest of %d, %d, %d is: %d\n", x, y, z, largest);
// Using with different data types
float grade = 85.5;
char *result = (grade >= 60) ? "Pass" : "Fail";
printf("Grade %.1f: %s\n", grade, result);
// Alternative to if-else
int num = 7;
printf("%d is %s\n", num, (num % 2 == 0) ? "even" : "odd");
return 0;
}
Operator Precedence and Associativity
Precedence Demonstration
#include <stdio.h>
int main() {
printf("Operator Precedence Demo:\n");
// Arithmetic precedence
int result1 = 2 + 3 * 4; // Multiplication first
int result2 = (2 + 3) * 4; // Parentheses change order
printf("2 + 3 * 4 = %d\n", result1);
printf("(2 + 3) * 4 = %d\n", result2);
// Mixed operators
int a = 5, b = 10;
int result3 = a < b && b > 0; // Relational before logical
printf("%d < %d && %d > 0 = %d\n", a, b, b, result3);
// Assignment has lowest precedence
int x, y = 5;
x = y + 2 * 3; // Addition and multiplication before assignment
printf("x = %d + 2 * 3 results in x = %d\n", y, x);
return 0;
}
Associativity Examples
#include <stdio.h>
int main() {
printf("Associativity Demo:\n");
// Left-to-right associativity
int result1 = 20 - 10 - 5; // Evaluated as (20 - 10) - 5
printf("20 - 10 - 5 = %d\n", result1);
// Right-to-left associativity for assignment
int a, b, c;
a = b = c = 10; // Evaluated as a = (b = (c = 10))
printf("a = b = c = 10 results in a = %d, b = %d, c = %d\n", a, b, c);
// Unary operators (right-to-left)
int x = 5;
int result2 = ++x * 2; // Pre-increment has higher precedence
printf("++x * 2 where x was 5: result = %d, x = %d\n", result2, x);
return 0;
}
Special Operators
Sizeof Operator
#include <stdio.h>
int main() {
printf("Sizeof Operator Demo:\n");
// Basic data types
printf("sizeof(char): %zu bytes\n", sizeof(char));
printf("sizeof(int): %zu bytes\n", sizeof(int));
printf("sizeof(float): %zu bytes\n", sizeof(float));
printf("sizeof(double): %zu bytes\n", sizeof(double));
// Variables
int x = 100;
float y = 3.14;
printf("sizeof(x): %zu bytes\n", sizeof(x));
printf("sizeof(y): %zu bytes\n", sizeof(y));
// Arrays
int arr[10];
char str[] = "Hello";
printf("sizeof(arr): %zu bytes\n", sizeof(arr));
printf("sizeof(str): %zu bytes\n", sizeof(str));
// Expressions
printf("sizeof(x + y): %zu bytes\n", sizeof(x + y));
return 0;
}
Address and Indirection Operators
#include <stdio.h>
int main() {
int x = 42;
int *ptr;
printf("Address and Indirection Operators:\n");
// Address operator (&)
printf("Value of x: %d\n", x);
printf("Address of x: %p\n", (void*)&x);
// Pointer assignment
ptr = &x;
printf("Value of ptr: %p\n", (void*)ptr);
// Indirection operator (*)
printf("Value pointed to by ptr: %d\n", *ptr);
// Modifying through pointer
*ptr = 100;
printf("After *ptr = 100, x = %d\n", x);
return 0;
}
Operator Overloading Concepts
Operator Combinations
#include <stdio.h>
int main() {
printf("Complex Operator Expressions:\n");
int a = 5, b = 10, c = 15;
// Complex expression evaluation
int result = a + b * c / a - b % a;
printf("a + b * c / a - b %% a = %d\n", result);
printf("Step by step:\n");
printf(" b * c = %d * %d = %d\n", b, c, b * c);
printf(" (b * c) / a = %d / %d = %d\n", b * c, a, (b * c) / a);
printf(" b %% a = %d %% %d = %d\n", b, a, b % a);
printf(" a + %d - %d = %d\n", (b * c) / a, b % a, result);
// Logical combinations
int x = 1, y = 0, z = 5;
int logical_result = x && y || z > 0;
printf("\nLogical expression: x && y || z > 0 = %d\n", logical_result);
return 0;
}
Best Practices
- Use parentheses to clarify operator precedence
- Avoid complex expressions in single statements
- Be careful with increment/decrement in expressions
- Use appropriate operators for the task
- Consider readability over brevity
- Test boundary conditions with operators
- Understand side effects of operators
- Use const for values that shouldn’t change
Common Pitfalls
Operator Precedence Mistakes
#include <stdio.h>
int main() {
printf("Common Operator Mistakes:\n");
// Mistake 1: Bitwise vs logical operators
int a = 1, b = 2;
// Wrong: using & instead of &&
// if (a & b) { ... } // This is bitwise AND, not logical
// Correct: logical AND
if (a && b) {
printf("Both a and b are non-zero\n");
}
// Mistake 2: Assignment vs equality
int x = 5;
// if (x = 10) { ... } // Assignment, not comparison!
// Correct: equality comparison
if (x == 5) {
printf("x equals 5\n");
}
// Mistake 3: Precedence confusion
int result1 = 2 + 3 * 4; // 14, not 20
int result2 = (2 + 3) * 4; // 20
printf("Without parentheses: %d\n", result1);
printf("With parentheses: %d\n", result2);
return 0;
}
Summary
C operators perform operations on operands and include arithmetic (+, -, *, /, %), relational (==, !=, <, >, <=, >=), logical (&&, ||, !), assignment (=, +=, -=, etc.), increment/decrement (++, —), bitwise (&, |, ^, ~, <<, >>), and conditional (?:) operators. Understanding operator precedence and associativity is crucial for writing correct expressions. Proper use of operators with attention to readability and avoiding common pitfalls leads to maintainable code.
Part of BCA Programming with C Course (UGCOA22J201)