Operators

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

  1. Use parentheses to clarify operator precedence
  2. Avoid complex expressions in single statements
  3. Be careful with increment/decrement in expressions
  4. Use appropriate operators for the task
  5. Consider readability over brevity
  6. Test boundary conditions with operators
  7. Understand side effects of operators
  8. 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)