Operators and Expressions

Operators are like kitchen tools — you use a knife for chopping and a pan for frying. Different ingredients need different tools, and different calculations need different operators.

Arithmetic Operators

C provides 7 basic arithmetic operators for the most common mathematical calculations.

Operator Meaning Example Result
+ Addition 5 + 3 8
- Subtraction 5 - 3 2
* Multiplication 5 * 3 15
/ Division 7 / 2 3
% Modulo 7 % 2 1
+ Unary plus +5 5
- Unary minus -5 -5

The Integer Division Trap

When two integers are divided, the result is also an integer — the fractional part is simply discarded, not rounded.

C
#include <stdio.h>

int main(void) {
    int a = 7;
    int b = 2;
    printf("%d / %d = %d\n", a, b, a / b);
    printf("%d %% %d = %d\n", a, b, a % b);
    return 0;
}
TEXT
7 / 2 = 3
7 % 2 = 1
💡 Tip: To get a result with decimals, make at least one operand a float: 7.0 / 2 gives 3.5.

Uses of the Modulo Operator

The modulo operator % only works with integers. It has several very practical use cases:

C
#include <stdio.h>

int main(void) {
    int n = 12345;
    printf("Last digit: %d\n", n % 10);
    printf("Is even: %s\n", n % 2 == 0 ? "Yes" : "No");
    return 0;
}
TEXT
Last digit: 5
Is even: No

Increment and Decrement Operators

The increment operator ++ adds 1 to a variable, and -- subtracts 1. Each comes in two forms: prefix and postfix, which differ in what the expression returns.

Prefix vs. Postfix

Form Name Effect Expression Value
++i Prefix increment i increases by 1 The new (increased) value
i++ Postfix increment i increases by 1 The old (original) value
--i Prefix decrement i decreases by 1 The new (decreased) value
i-- Postfix decrement i decreases by 1 The old (original) value
C
#include <stdio.h>

int main(void) {
    int a = 5;
    int b = ++a;
    printf("Prefix: a=%d, b=%d\n", a, b);

    int c = 5;
    int d = c++;
    printf("Postfix: c=%d, d=%d\n", c, d);
    return 0;
}
TEXT
Prefix: a=6, b=6
Postfix: c=6, d=5
⚠️ Note: Don't use ++ or -- on the same variable multiple times within one expression, like a = ++a + a++. The behavior is undefined, and different compilers will give different results.

Relational Operators

Relational operators compare two values, returning "true" (1) or "false" (0).

Operator Meaning Example Result
== Equal to 5 == 5 1
!= Not equal to 5 != 3 1
< Less than 3 < 5 1
> Greater than 3 > 5 0
<= Less than or equal 5 <= 5 1
>= Greater than or equal 3 >= 5 0
C
#include <stdio.h>

int main(void) {
    int a = 10;
    int b = 20;
    printf("a == b: %d\n", a == b);
    printf("a != b: %d\n", a != b);
    printf("a < b:  %d\n", a < b);
    return 0;
}
TEXT
a == b: 0
a != b: 1
a < b:  1
⚠️ Note: == is comparison, = is assignment. Mixing them up turns the comparison into an assignment that won't produce an error. A good habit is to put the constant on the left: 5 == a — if you accidentally write 5 = a, the compiler will catch it.

Logical Operators

Logical operators combine multiple conditions, also returning 1 (true) or 0 (false).

Operator Meaning Example Result
&& Logical AND 1 && 0 0
` ` Logical OR
! Logical NOT !0 1

Truth Table

| A | B | A && B | A || B | !A | |---|---|--------|--------|----| | 0 | 0 | 0 | 0 | 1 | | 0 | 1 | 0 | 1 | 1 | | 1 | 0 | 0 | 1 | 0 | | 1 | 1 | 1 | 1 | 0 |

Short-Circuit Evaluation

With &&, if the left side is false, the right side is never evaluated. With ||, if the left side is true, the right side is skipped. This feature can be used to avoid illegal operations:

C
#include <stdio.h>

int main(void) {
    int divisor = 0;
    int value = 10;
    if (divisor != 0 && value / divisor > 5) {
        printf("Condition met\n");
    } else {
        printf("Condition not met, and no division by zero\n");
    }
    return 0;
}
TEXT
Condition not met, and no division by zero
💡 Tip: In C, 0 is false and any non-zero value is true (including negatives). So -5 is "true" in a logical context.

Assignment Operators

The basic assignment operator = stores the right-hand value into the left-hand variable. C also provides compound assignment operators that combine an operation with assignment.

Compound Equivalent
a += b a = a + b
a -= b a = a - b
a *= b a = a * b
a /= b a = a / b
a %= b a = a % b
C
#include <stdio.h>

int main(void) {
    int score = 80;
    score += 10;
    printf("After bonus: %d\n", score);
    score -= 25;
    printf("After penalty: %d\n", score);
    score *= 2;
    printf("After doubling: %d\n", score);
    return 0;
}
TEXT
After bonus: 90
After penalty: 65
After doubling: 130

The Conditional Operator (Ternary Operator)

The conditional operator ?: is C's only ternary operator. Its syntax is:

TEXT
condition ? expression1 : expression2

If the condition is true, expression1 is evaluated; otherwise, expression2 is evaluated. It's a shorthand for if-else.

C
#include <stdio.h>

int main(void) {
    int age = 20;
    char *status = age >= 18 ? "Adult" : "Minor";
    printf("Age %d, %s\n", age, status);

    int a = 15, b = 28;
    int max = a > b ? a : b;
    printf("Larger value: %d\n", max);
    return 0;
}
TEXT
Age 20, Adult
Larger value: 28

The Comma Operator

The comma operator , evaluates each expression from left to right, and the value of the entire comma expression is the value of the last expression.

C
#include <stdio.h>

int main(void) {
    int a, b, c;
    c = (a = 1, b = 2, a + b);
    printf("a=%d, b=%d, c=%d\n", a, b, c);
    return 0;
}
TEXT
a=1, b=2, c=3
⚠️ Note: The comma operator has the lowest precedence of all operators. Don't confuse the comma operator with the commas between function arguments — those are not comma operators.

The sizeof Operator

sizeof returns the number of bytes a data type or variable occupies in memory. It's evaluated at compile time, not runtime.

C
#include <stdio.h>

int main(void) {
    printf("char:   %zu bytes\n", sizeof(char));
    printf("int:    %zu bytes\n", sizeof(int));
    printf("float:  %zu bytes\n", sizeof(float));
    printf("double: %zu bytes\n", sizeof(double));

    int arr[5] = {1, 2, 3, 4, 5};
    printf("Array total size: %zu bytes\n", sizeof(arr));
    printf("Array element count: %zu\n", sizeof(arr) / sizeof(arr[0]));
    return 0;
}
TEXT
char:   1 bytes
int:    4 bytes
float:  4 bytes
double: 8 bytes
Array total size: 20 bytes
Array element count: 5
💡 Tip: sizeof requires parentheses for type names (sizeof(int)) but not for variables (sizeof a). However, for consistency, it's best to always use parentheses.

Operator Precedence

When an expression contains multiple operators, the one with higher precedence is evaluated first. The table below lists them from highest to lowest:

Precedence Operators Associativity
1 (highest) () [] -> . Left to right
2 ! ~ ++ -- +(unary) -(unary) *(dereference) &(address-of) sizeof Right to left
3 * / % Left to right
4 + - Left to right
5 << >> Left to right
6 < <= > >= Left to right
7 == != Left to right
8 & Left to right
9 ^ Left to right
10 ` `
11 && Left to right
12 `
13 ?: Right to left
14 = += -= *= /= %= etc. Right to left
15 (lowest) , Left to right
🔥 Common Mistake: Can't memorize the precedence table? Don't bother — when in doubt, add parentheses. They always have the highest priority and make your code clearer.

Example

Combine various operators to calculate the sum of each digit in a three-digit number:

C
#include <stdio.h>

int main(void) {
    int num = 952;
    int hundreds = num / 100;
    int tens = (num / 10) % 10;
    int ones = num % 10;
    int sum = hundreds + tens + ones;

    printf("Number: %d\n", num);
    printf("Hundreds: %d, Tens: %d, Ones: %d\n", hundreds, tens, ones);
    printf("Sum of digits: %d\n", sum);
    return 0;
}
▶ Try it Yourself
TEXT
Number: 952
Hundreds: 9, Tens: 5, Ones: 2
Sum of digits: 16

Example

Use logical and relational operators to determine whether a year is a leap year:

C
#include <stdio.h>

int main(void) {
    int year = 2024;
    int is_leap = (year % 4 == 0 && year % 100 != 0) || (year % 400 == 0);

    printf("%d is %sa leap year\n", year, is_leap ? "" : "not ");
    return 0;
}
▶ Try it Yourself
TEXT
2024 is a leap year

Type Conversion

Implicit Conversion

When different types are mixed in an expression, the compiler automatically converts the lower-precision type to the higher-precision type:

C
#include <stdio.h>

int main(void) {
    int a = 5;
    double b = 2.0;
    double c = a / b;
    printf("5 / 2.0 = %f\n", c);

    char ch = 'A';
    int code = ch + 1;
    printf("'A' + 1 = %c (ASCII %d)\n", code, code);
    return 0;
}
TEXT
5 / 2.0 = 2.500000
'A' + 1 = B (ASCII 66)

Conversion direction: charintlongdouble, intunsignedlongdouble.

Explicit Casting

Use (type_name) to force a value to a specific type:

C
#include <stdio.h>

int main(void) {
    int a = 7, b = 2;
    double result = (double)a / b;
    printf("With cast: %f\n", result);
    return 0;
}
TEXT
With cast: 3.500000
⚠️ Note: Casting doesn't change the original variable's value or type — it only produces a temporary new value.

❓ FAQ

Q Is there a difference between a++ and ++a when used on their own line?
A No. The difference only matters when you use the return value inside an expression. On their own, the effect is identical, though prefix increment is theoretically slightly more efficient.
Q How do I keep = and == straight?
A = is assignment ("becomes"), == is comparison ("equals?"). Writing if (a = 0) by mistake won't cause an error but completely changes the logic. A good habit: put the constant on the left — if (0 == a) — so a typo like if (0 = a) will be caught by the compiler.
Q Can the % operator be used with floating-point numbers?
A No. % only works with integer types. For floating-point modulo, use the fmod() function from #include <math.h>.
Q Do I need to memorize the entire operator precedence table?
A No. Just remember that multiplication/division/modulo come before addition/subtraction, and logical NOT comes before AND before OR. For everything else, add parentheses — it's safer.

📖 Summary

📝 Exercises

  1. Write a program that takes a number of seconds (e.g. 3661) and uses / and % to calculate the corresponding hours, minutes, and seconds, then outputs the result.
  2. Write a program that takes two integers and uses the ternary operator to find and output the larger and smaller values.
  3. Write a program that uses sizeof to print the sizes of short, int, long, and long long on your computer and observe the results.
100%

🙏 帮我们做得更好

我们是刚上线的编程教程站,几个人的小团队,精力有限。页面虽经检查,难免还有疏漏——链接失效、排版错乱、内容有误、语言生硬……

如果您发现了,麻烦告诉我们,我们会在收到反馈后第一时间进行修复,再次感谢您的光临 🙏