C Language Operators: Unary, Logical, Conditional, and Special Expressions

Unary Operators

The bitwise NOT operator (~) performs a one's complement operation, flipping all bits in the binary representation. Since C stores signed integers using two's complement, applying ~ to zero yields -1:

#include <stdio.h>

int main() {
    int val = 0;
    int result = ~val;
    printf("%d\n", result);  // Outputs: -1
    return 0;
}

This occurs because 0 represents all 32 bits as 0 in two's complement. The inversion sets all bits to 1, which corresponds to -1 in signed integer representation.

Bitwise Complement Algorithm

Consider the problem of finding the binary complement of a decimal integer (similar to finding the bitwise complement). The complement inverts each bit, effectively calculating mask XOR n where mask contains all 1s matching the bit-length of n:

int findComplement(int num) {
    if (num == 0) return 1;
    
    unsigned int mask = ~0;
    while (num & mask) {
        mask <<= 1;
    }
    return ~mask ^ num;
}

Alternatively, using arithmetic progression:

int bitwiseComplement(int n) {
    if (n == 0) return 1;
    
    int power = 1;
    while (power <= n) {
        power <<= 1;
    }
    return power - 1 - n;
}

Increment and Decrement

C provides two forms for increment/decrement operators with distinct evaluation timing:

Prefix Form (++var, --var): The variable modifies before its value participates in the expression.

#include <stdio.h>

int main() {
    int idx = 5;
    int res = --idx;  // idx decrements to 4, then assigns to res
    printf("idx=%d, res=%d\n", idx, res);  // Both output 4
    return 0;
}

Postfix Form (var++, var--): The original value participates in the expression, then the variable modifies.

#include <stdio.h>

int main() {
    int idx = 5;
    int res = idx++;  // res receives 5, then idx increments to 6
    printf("idx=%d, res=%d\n", idx, res);  // Outputs: idx=6, res=5
    return 0;
}

Relational Operators

These operators establish comparisons between operands, yielding boolean results (represented as 1 for true, 0 for false):

Operator Meaning
> Greater than
>= Greater than or equal
< Less than
<= Less than or equal
== Equality comparison
!= Inequality

Note the distinction between assignment (=) and equality comparison (==), a common source of logical errors.

Logical Operators

Logical operators combine boolean expressions:

  • && (Logical AND): Evaluates true only if both operands are non-zero.
  • || (Logical OR): Evaluates true if either operand is non-zero.

Leap Year Calculation Example:

A year qualifies as leap if divisible by 4 but not by 100, unless divisible by 400:

int isLeapYear(int year) {
    return (year % 4 == 0 && year % 100 != 0) || (year % 400 == 0);
}

Short-Circuit Evaluation

C guarantees left-to-right evaluation for logical operators. If the left operand determines the final result, the right operand never executes:

int x = 0;
int y = 5;

// If x < 3 is false, y++ never executes
if (x >= 3 && y++ > 4) {
    printf("Condition met\n");
}
// y remains 5 due to short-circuit

Similarly for OR:

int a = 10;
int b = 0;

// Since a != 0 evaluates true, b++ is skipped
if (a != 0 || b++) {
    printf("Short-circuit prevents b increment\n");
}
// b remains 0

Conditional (Ternary) Operator

The ternary operator ?: provides concise conditional assignment:

condition ? expression_if_true : expression_if_false

Maximum Value Selection:

#include <stdio.h>

int main() {
    int first = 42;
    int second = 17;
    int maximum = (first > second) ? first : second;
    printf("Maximum: %d\n", maximum);
    return 0;
}

For array manipulation:

#include <stdio.h>

int main() {
    int values[3];
    scanf("%d %d", &values[0], &values[1]);
    values[2] = (values[0] > values[1]) ? values[0] : values[1];
    printf("Larger value: %d\n", values[2]);
    return 0;
}

Equivalent to:

int threshold = 5;
int signal = (threshold > 5) ? 3 : -3;

Comma Operator

The comma operator , evaluates expressions left-too-right, returning the rightmost value:

int p = 0;
int q = 0;
int final = (p += 3, q += 5, p + q);  // final equals 8

Loop Optimization:

Consolidating multiple operations within loop controls:

// Verbose approach
int fetchStatus();
void processData(int data);

int data = fetchStatus();
while (data > 0) {
    processData(data);
    data = fetchStatus();
}

// Condensed using comma operator
while (data = fetchStatus(), processData(data), data > 0) {
    // Processing logic
}

Subscript and Function Call Operators

Array Subscript [ ]: Accesses array elements through pointer arithmetic: arr[idx] equals *(arr + idx).

Function Call ( ): Invokes functions with specified arguments: function_name(argument_list).

Type Casting (type): Explicitly converts values between data types:

double pi = 3.14159;
int whole = (int)pi;  // Truncates to 3

float ratio = (float)7 / 4;  // Ensures floating-point division, yields 1.75

Type casting proves essential when mixing arithmetic operations between integer and floating-point types to prevent unintended integer truncation.

Tags: c programming Operators Bitwise Operations logical operators Ternary Operator

Posted on Fri, 02 Oct 2026 16:43:25 +0000 by Visualant