C Programming Language Operators Comprehensive Guide

Symbol Description Example Result
+ Addition 10 + 5 15
- Subtraction 10 - 5 5
* Multiplication 10 * 5 50
/ Division 10 / 5 2
% Modulus 10 % 3 1
++ Pre-increment x=2; y=++x; x=3; y=3;
++ Post-increment x=2; y=x++; x=3; y=2;
-- Pre-decrement x=2; y=--x; x=1; y=1;
-- Post-decrement x=2; y=x--; x=1; y=2;

Sample code:

#include <stdio.h>

int main() {
    // For division to produce decimal results, at least one operand must be floating point
    double result = 5/2; // Both operands are integers, truncates to integer
    printf("result1 = %lf\n", result);

    result = 5.0/2; 
    printf("result2 = %lf\n", result);

    result = 5/2.0; 
    printf("result3 = %lf\n", result);

    int counter = 0;
    // Pre-increment
    // Increment first, then use value
    int value = ++counter; 
    printf("Pre-increment: value = %d, counter = %d\n", value, counter);

    // Post-increment
    // Use value first, then increment
    counter = 0;
    value = counter++;
    printf("Post-increment: value = %d, counter = %d\n", value, counter);

    return 0;
}

Output:

result1 = 2.000000
result2 = 2.500000
result3 = 2.500000
Pre-increment: value = 1, counter = 1
Post-increment: value = 0, counter = 1

Assignment Operators

Symbol Description Example Result
= Assign x=2; y=3; x=2; y=3;
+= Add and assign x=0; x+=2; Same as x = x + 2; x=2;
-= Subtract and assign x=5; x-=3; Same as x = x - 3; x=2;
*= Multiply and assign x=2; x*=2; Same as x = x * 2; x=4;
/= Divide and assign x=4; x/=2; Same as x = x / 2; x=2;
%= Modulus and assign x=3; x%=2; Same as x = x % 2; x=1;

Sample code:

#include <stdio.h>

int main() {
    int num = 10;
    num += 5;
    printf("num = %d\n", num);

    return 0;
}

Output:

num = 15

Relational Operators

In C language comparisons, "true" is represented by the number "1" and "false" by the number "0".

Symbol Description Example Result
== Equal to 4 == 3 0
!= Not equal to 4 != 3 1
< Less than 4 < 3 0
> Greater than 4 > 3 1
<= Less than or equal 4 <= 3 0
>= Greater than or equal 4 >= 1 1

Sample code:

#include <stdio.h>

int main() {
    int left = 10;
    int right = 20;
    printf("%d\n", left == right);
    printf("%d\n", left != right);
    printf("%d\n", left > right);
    printf("%d\n", left < right);
    printf("%d\n", left >= right);
    printf("%d\n", left <= right);

    return 0;
}

Logical Operators

Symbol Description Example Result
! Logical NOT !a If a is false, !a is true; if a is true, !a is false
&& Logical AND a && b Result is true only if both a and b are true
Logical OR

Sample code:

#include <stdio.h>

int main() {

    // && (AND), can be understood as "and"
    // Example: Check if both boyfriend and girlfriend meet legal marriage age
    int male_age = 25;
    int female_age = 21;
    int outcome = male_age >= 22 && female_age >= 20;
    printf("%d\n", outcome);

    // || (OR), can be understood as "or"
    // Example: Girlfriend needs gems for Genshin Impact, check if sufficient funds
    double wechat_balance = 100;
    double alipay_balance = 300;
    outcome = wechat_balance >= 398 || alipay_balance >= 398 || wechat_balance+alipay_balance >= 398;
    printf("%d\n", outcome);
    
    // ! (NOT), can be understood as "not"
    printf("%d\n", !0);
    printf("%d\n", !!1);

    // Short-circuit behavior
    // && left side false, right side not executed
    0 && printf("I am on the right\n");
    // || left side true, right side not executed
    1 || printf("I am on the right\n");
    
    return 0;
}

Bitwise Operators

Common bitwise operators include &, |, ^, ~, >>, <<, representing the following operations:

Symbol Description Example Result
& Bitwise AND 011 & 101 Both bits must be 1, result is 001
Bitwise OR 011
^ Bitwise XOR 011 ^ 101 Different bits become 1, result is 110
~ Bitwise NOT ~011 Inverts all bits, result is 100
<< Left shift 1010 << 1 Shifts left, result is 10100
>> Right shift 1010 >> 1 Shifts right, result is 0101

Note: NOT and shift operations work on two's complement representation.

& - (AND Operation)

Bitwise AND (&) operation: Compares each bit position, if both are 1, result is 1, otherwise 0;

/**
     * Bitwise AND (&): compares bit by bit, result is 1 if both are 1, otherwise 0
     * Example:
     *          40    &     15    =     8
     *      0010 1000 
     *    & 0000 1111 
     * -------------------
     *      0000 1000
     */
printf("40 & 15 = %d\n", 40 & 15);

| - (OR Operation)

Bitwise OR (|) operation: Compares each bit position, if both are 0, result is 0, otherwise 1;

/**
     * Bitwise OR (|): compares bit by bit, result is 0 if both are 0, otherwise 1
     * Example:
     *          40    |     15    =     47
     *      0010 1000 
     *    | 0000 1111
     * ----------------
     *      0010 1111
     */
printf("40 | 15 = %d\n", 40 | 15);

^ - (XOR Operation)

Bitwise XOR operation: Compares each bit position, same values become 0, different values become 1;

/**
     * Bitwise XOR: compares bit by bit, same becomes 0, different becomes 1
     * Example:
     *          40    ^     15    =     39
     *      0010 1000 
     *    ^ 0000 1111 
     * ------------------
     *      0010 0111
     */
printf("40 ^ 15 = %d\n", 40 ^ 15);

~ - (NOT Operation)

Bitwise NOT operation: Two's complement is inverted, then convert the inverted two's complement back to original form;

Note: For unsigned data, even if MSB becomes 1 after inversion, no reverse conversion is needed.

/**
 * Bitwise NOT: invert two's complement, then convert back from two's complement to original form.
 *      1. Positive number inversion: Since positive numbers have identical original and two's complement forms, the process is simpler.
 *              Two's complement (original) -> Invert -> Reverse two's complement -> Reverse one's complement (sign bit unchanged) -> Inverted original
 *      2. Negative number inversion:
 *              Original -> One's complement -> Two's complement -> Invert -> Inverted two's complement is original
 * Example:
 *            Original (Two's comp)  Inverted Two's comp   Reverse two's comp-1  Reverse one's comp
 *      ~40 = 0010 1000 -> 1101 0111 -> 1101 0110 -> 1010 1001 = -41
 *
 *            Original (Two's comp)  Inverted Two's comp   Reverse two's comp-1  Reverse one's comp
 *      ~15 = 0000 1111 -> 1111 0000 -> 1110 1111 -> 1001 0000 = -16
 *
 *                Original         One's comp          Two's comp          Invert
 *      ~-15 = 1000 1111 -> 1111 0000 -> 1111 0001 -> 0000 1110 = 14
 */
printf("~40 = %d\n", ~40);
printf("~15 = %d\n", ~15);
printf("~-15 = %d\n", ~(-15));

<< - (Left Shift Operator)

Shifts the binary two's complement of the number completely to the left, filling empty positions with 0, discarding overflow bits;

For signed data, if MSB becomes 1 after left shift, reverse conversion is required;

Important notes:

  • For unsigned data, even if MSB becomes 1 after left shift, no reverse conversion is needed;
  • -128: 1000 0000 special case also doesn't require reverse conversion;
/**
     * Examples:
     *      40 << 4 = 0010 1000 << 4 = 1000 0000 = -128 (special case, no reverse conversion needed)
     *      41 << 4 = 0010 1001 << 4 = 1001 0000 = 1000 1111 = 1111 0000 = -112
     *       7 6 5 4 3 2 1 0
     *       1 0 0 1 0 0 0 0
     */

    int8_t val = 40;
    val <<= 4;    //  val = val << 4;
    printf("40 << 4 = %d\n", val);

>> - (Right Shift Operator)

Shifts the binary two's compliment of the number completely to the right, filling empty positions based on the original MSB. If original MSB was 1, fill with 1; if original MSB was 0, fill with 0. This can be simplified as: positive numbers fill 0, negative numbers fill 1;

	/*
	  23: 0001 0111[Original] ----  0001 0111[One's comp] ----  0001 0111 [Two's comp]
						  >> 2
	  -----------------------------------------------
					  0000 0101[Two's comp] --->  5
	 */
	printf(" 23 >> 2 = %d \n" , 23 >> 2) ; 
	
	
	/*
	  -23: 1001 0111[Original] ----  1110 1000[One's comp]----  1110 1001[Two's comp]
						  >> 2
	  -----------------------------------------------
						1111 1010[Two's comp] --->  1111 1001[One's comp]- ----- 1000 0110 [Original]===> -6
	 */
	printf(" -23 >> 2 = %d \n" , -23 >> 2) ; 

Sample code:

#include <stdio.h>
#include <inttypes.h>

int main() {
    uint8_t alpha = 3;          // 0000 0011
    uint8_t beta = 10;         // 0000 1010
    // Print with 2 characters, pad with 0 if needed
    printf("%02x\n", alpha & beta); // 0000 0010, hexadecimal is 02
    printf("%02x\n", alpha | beta); // 0000 1011, hexadecimal is 0b
    printf("%02x\n", alpha ^ beta); // 0000 1001, hexadecimal is 09

    uint8_t gamma = 10;          // 0000 1010
    uint8_t temporary = ~gamma;       // 1111 0101
    printf("%02x\n", temporary);   // 1111 0101, hexadecimal is f5
    printf("%02x\n", gamma << 1); // 0001 0100, hexadecimal is 14
    printf("%02x\n", gamma >> 1); // 0000 0101, hexadecimal is 05

    return 0;
}

Output:

02
0b
09
f5
14
05

Practical scenarios:

// Set bit 2 of variable alpha to 1, keep other bits unchanged
uint8_t alpha = 0b10110011; // 0xb3;

// Set bits 2 and 6 of variable beta to 1, keep other bits unchanged
uint8_t beta = 0b10110011; // 0xb3;

// Set bit 5 of variable gamma to 0, keep other bits unchanged
uint8_t gamma = 0b10110011;  // 0xb3;

// Set bits 0-3 of variable delta to 0, keep other bits unchanged
uint8_t delta = 0b11111111;  // 0xff;

// Toggle bit 2 of variable epsilon, keep other bits unchanged
uint8_t epsilon = 0b10110011;  // 0xb3;

// Extract bits 8-15 from variable zeta
uint32_t zeta = 0x12345678;

Sample implementation:

#include <stdio.h>
#include <inttypes.h>

int main() {
    // Set bit 2 of variable alpha to 1, keep other bits unchanged
    uint8_t alpha = 0b10110011; // 0xb3;
    alpha |= (1 << 2);          // Or x = x | (1 << 2);
    printf("%02x\n", alpha);    // b7,  10110111

    // Set bits 2 and 6 of variable beta to 1, keep other bits unchanged
    uint8_t beta = 0b10110011; // 0xb3;
    beta |= (1 << 2 | 1 << 6);
    printf("%02x\n", beta);    // f7,11110111

    // Set bit 5 of variable gamma to 0, keep other bits unchanged
    uint8_t gamma = 0b10110011;  // 0xb3;
    gamma &= ~(1 << 5);
    printf("%02x\n", gamma);    // 93,10010011

    // Set bits 0-3 of variable delta to 0, keep other bits unchanged
    uint8_t delta = 0b11111111;  // 0xff;
    delta &= ~(1 << 0 | 1 << 1 | 1 << 2 | 1 << 3);
    printf("%02x\n", delta);    // f0,11110000

    // Toggle bit 2 of variable epsilon, keep other bits unchanged
    uint8_t epsilon = 0b10110011;  // 0xb3;
    epsilon ^= (1 << 2);
    printf("%02x\n", epsilon);    // b7,  10110111

    // Extract bits 8-15 from variable zeta
    uint32_t zeta = 0x12345678;
    uint32_t temporary = (zeta & 0x0000ff00) >> 8;
    printf("%#x\n", temporary);

    return 0;
}

Operator Precedence

  • Different operators have default precedence levels. With many symbols, it's better to look up when needed rather than memorize.
  • When uncertain about precedence, add parentheses to resolve ambiguity.
Level Operator Name/Meaning Usage Associativity Notes
1 [] Array subscript array_name[constant_expression] Left to right --
() Parentheses (expression)/function_name(formal_params) -- --
. Member access (object) object.member_name -- --
-> Member access (pointer) pointer_object->member_name -- --
2 - Unary minus -expression Right to left Unary operators
~ Bitwise NOT ~expression
++ Increment ++variable_name/variable_name++
-- Decrement --variable_name/variable_name--
*** Dereference *pointer_variable
& Address-of &variable_name
! Logical NOT !expression
(type) Type cast (data_type)expression
sizeof Size operator sizeof(expression)
3 / Division expression/expression Left to right Binary operators
* Multiplication expression*expression
% Modulus integer_expression%integer_expression
4 + Addition expression+expression Left to right Binary operators
- Subtraction expression-expression
5 << Left shift variable<<expression Left to right Binary operators
>> Right shift variable>>expression
6 > Greater than expression>expression Left to right Binary operators
>= Greater than or equal expression>=expression
< Less than expression<expression
<= Less than or equal expression<=expression
7 == Equal to expression==expression Left to right Binary operators
!= Not equal to expression!= expression
8 & Bitwise AND expression&expression Left to right Binary operators
9 ^ Bitwise XOR expression^expression Left to right Binary operators
10 ** ** Bitwise OR expression expression
11 && Logical AND expression&&expression Left to right Binary operators
12 ** ** Logical OR expression
13 ?: Condisional expression1? expression2: expression3 Right to left Ternary operator
14 = Assignment variable=expression Right to left --
/= Divide and assign variable/=expression -- --
*= Multiply and assign variable*=expression -- --
%= Modulo and assign variable%=expression -- --
+= Add and assign variable+=expression -- --
-= Subtract and assign variable-=expression -- --
<<= Left shift and assign variable<<=expression -- --
>>= Right shift and assign variable>>=expression -- --
&= Bitwise AND and assign variable&=expression -- --
^= Bitwise XOR and assign variable^=expression -- --
** =** Bitwise OR and assign variable =expression
15 , Comma expression,expression,… Left to right --

Tags: c programming Operators arithmetic operators logical operators bitwise operators

Posted on Sat, 09 May 2026 01:11:44 +0000 by lisaNewbie