国际访客建议访问 Primers 编程伙伴 国际版站点 > C 教程 > 基本运算 以获得更好的体验。

# C 语言的基本运算

运算就是用值来做各种变化的游戏,例如 1 + 1 得到 2,其中 + 是加法的运算符

C 语言中的所有运算符都是英文字符,输入法自动输入中文符号是新手常见的错误,请注意区分。

# 赋值运算符

C 语言使用 = 作为赋值运算符,用于修改变量的值,而非数学中的“等于”。

实例:

#include <stdio.h>

int main(void)
{
    int x = 10;             // 定义变量 x
    printf("%d\n", x);

    x = 233;                // 修改变量的值
    printf("%d\n", x);

    return 0;
}

运行结果:

10
233

# 算术运算符

算术运算符用于进行算术运算。

运算符 名称 示例 结果 说明
+ 加法运算符 3 + 5 7
- 减法运算符 5 - 3 2
* 乘法运算符 5 * 3 15
/ 除法运算符 5 / 2 2 整型的运算结果是整型,浮点型的运算结果是浮点型
% 取余运算符 5 % 2 1 5 除以 2,得 2 余 1

示例:

#include <stdio.h>

int main(void)
{
    printf("%d + %d = %d\n", 10, 3, 10 + 3);
    printf("%d - %d = %d\n", 10, 3, 10 - 3);
    printf("%d * %d = %d\n", 10, 3, 10 * 3);
    printf("%d / %d = %d\n", 10, 3, 10 / 3);            // 10 除以 3 得 3 余数 1,整型运算结果取整,因此结果为 3
    printf("%d %% %d = %d\n", 10, 3, 10 % 3);           // 10 除以 3 得 3 余数 1,因此结果为 1
    printf("%f / %f = %f\n", 10.0, 3.0, 10.0 / 3.0);    // 10.0 除以 3.0 得 3.333333
    printf("%f / %d = %f\n", 10.0, 3, 10.0 / 3);        // double 与 int 进行运算,int 隐式转换为 double,得 3.333333

    return 0;
}
  • 10 / 3int 除以 int,结果取整得 3

  • 10.0 / 3.0double 除以 double,结果是 3.33333

  • 10.0 / 3double 除以 intint 隐式转换为 double,实际进行 double 除以 double 的运算

运行结果:

10 + 3 = 13
10 - 3 = 7
10 * 3 = 30
10 / 3 = 3
10 % 3 = 1
10.000000 / 3.000000 = 3.333333
10.000000 / 3 = 3.333333

# 正负号

运算符 名称 示例
+ 正号 +3
- 负号 -5

# 比较运算符

比较运算符用于比较两个值的关系,结果为 true(真) 或 false(假)。

运算符 名称 示例 结果
== 等于运算符 3 == 5 0
!= 不等于运算符 3 != 5 1
> 大于运算符 5 > 3 1
< 小于运算符 5 < 2 0
>= 大于或等于运算符 5 >= 5 1
<= 小于或等于运算符 5 <= 2 0

# 逻辑运算符

逻辑运算符用于逻辑运算。

运算符 名称 示例 结果 说明
&& 逻辑与运算符 true && false false 全部为 true 时结果为 true,否则结果为 false
\|\| 逻辑或运算符 true \|\| false true 全部为 false 时结果为 false,否则结果为 true
! 逻辑非运算符 ! false true 将一个布尔值反转

true 为 1, false 为 0,并且所有非零的值均视为 true;参考 布尔类型

在 C23 标准之前需要包含 stdbool.h 头文件才能直接使用 bool 类型以及 truefalse
否则,只能使用 int 类型以及 1 和 0 代替。

示例:

#include <stdio.h>
#include <stdbool.h>

int main(void)
{
    // true 和 false 的值是 1 和 0
    printf("true = %d\n", true);
    printf("false = %d\n", false);

    // 逻辑非
    printf("!true = %d\n", !true);
    printf("!false = %d\n", !false);

    // 逻辑与
    printf("true && true = %d\n", true && true);
    printf("true && false = %d\n", true && false);
    printf("false && true = %d\n", false && true);
    printf("false && false = %d\n", false && false);

    // 逻辑或
    printf("true || true = %d\n", true || true);
    printf("true || false = %d\n", true || false);
    printf("false || true = %d\n", false || true);
    printf("false || false = %d\n", false || false);

    // 非零值均视为 true
    printf("!10 = %d\n", !10);
    printf("10 && 10 = %d\n", 10 && 10);
    printf("10 && 0 = %d\n", 10 && 0);
    printf("10 || 0 = %d\n", 10 || 0);

    return 0;
}

运行结果:

true = 1
false = 0
!true = 0
!false = 1
true && true = 1
true && false = 0
false && true = 0
false && false = 0
true || true = 1
true || false = 1
false || true = 1
false || false = 0
!10 = 0
10 && 10 = 1
10 && 0 = 0
10 || 0 = 1

逻辑运算中存在一个名为短路原则(Short-circuit evaluation)的特性——在逻辑运算中,如果前面的部分运算已经能够确定整个运算的结果,就不再计算后面的表达式。

  • 对于 A && B,如果 Afalse,则无论 B 是什么,整个表达式的结果都必定是 false,因此不会计算 B

  • 对于 A || B,如果 Atrue,则无论 B 是什么,整个表达式的结果都必定是 true,因此不会计算 B

示例:

#include <stdio.h>
#include <stdbool.h>

int main(void)
{
    int x = 10;
    false && (x = 1);       // x = 1 不会被执行
    true || (x = 2);        // x = 2 不会被执行
    printf("x 的值是 %d\n", x);

    return 0;
}

运行结果:

x 的值是 10

# 位运算符

位运算符用于二进制位运算。

运算符 名称 示例 结果 说明
& 位与运算符 0b1100 & 0b0110 0b0100 按二进制位进行计算,两个数在某一位上都是 1,则结果在该位为 1,否则结果在该位为 0
\| 位或运算符 0b1100 \| 0b0110 0b1110 按二进制位进行计算,两个数在某一位上都是 0,则结果在该位为 0,否则结果在该位为 1
^ 异或运算符 0b1100 ^ 0b0110 0b1010 二进制中不同的位结果为 1,相同的位结果位 0
<< 左移运算符 0b0011 << 2 0b1100 二进制位向左移动,右侧补 0
>> 右移运算符 0b1100 >> 1 0b0110 二进制位向右移动,左侧补 0
~ 取反运算符 ~0b1100 0b0011 二进制位取反,即 1 变为 00 变为 1

C 语言标准并不支持二进制字面量,表格中示例的二进制写法仅作用演示。

示例:

#include <stdio.h>

int main(void)
{
    printf("%#x & %#x = %#x\n", 0xfff0, 0x0fff, 0xfff0 & 0x0fff);
    printf("%#x | %#x = %#x\n", 0xfff0, 0x0fff, 0xfff0 | 0x0fff);
    printf("%#x ^ %#x = %#x\n", 0xfff0, 0x0fff, 0xfff0 ^ 0x0fff);
    printf("%#x << %d = %#x\n", 0xfff0, 4, 0xfff0 << 4);
    printf("%#x >> %d = %#x\n", 0xfff0, 4, 0xfff0 >> 4);
    printf("~%#x = %#x\n", 0xfff0, ~0xfff0);

    return 0;
}

运行结果:

0xfff0 & 0xfff = 0xff0
0xfff0 | 0xfff = 0xffff
0xfff0 ^ 0xfff = 0xf00f
0xfff0 << 4 = 0xfff00
0xfff0 >> 4 = 0xfff
~0xfff0 = 0xffff000f

# 复合赋值运算符

复合赋值运算符是一种将运算和赋值合并的简化写法,它将变量的值进行计算后再赋值给该变量。例如 x += 1 相当于 x = x + 1

运算符 等价写法 说明
+= 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 取模并赋值
<<= 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 按位异或并赋值

示例:

#include <stdio.h>

int main(void)
{
    int x = 10;

    x += 2;                 // x = x + 2   ->   12
    printf("%d\n", x);
    
    x -= 3;                 // x = x - 3   ->   9
    printf("%d\n", x);

    x *= 4;                 // x = x * 4   ->   36
    printf("%d\n", x);

    x /= 5;                 // x = x / 2   ->   7
    printf("%d\n", x);

    return 0;
}

运行结果:

12
9
36
7

# 自增与自减

运算符 说明
x++ x = x + 1,返回 x 加一之前的值
x-- x = x - 1,返回 x 减一之前的值
++x x = x + 1,返回 x 加一之后的值
--x x = x - 1,返回 x 减一之后的值

示例:

#include <stdio.h>

int main(void)
{
    int x = 10;
    printf("%d\n", x++);    // x = x + 1,返回 x 加一之前的值,因此打印 10
    printf("%d\n", x);      // x 的值是 11

    int y = 10;
    printf("%d\n", ++y);    // y = y + 1,返回 x 加一之后的值,因此打印 11
    printf("%d\n", y);      // y 的值是 11

    return 0;
}

运行结果:

10
11
11
11

# sizeof

sizeof 运算符可以获取类型或变量的字节数。

示例:

#include <stdio.h>

int main(void)
{
    printf("int 的字节数是 %zu\n", sizeof(int));            // 获取 int 类型的字节数
    printf("long 的字节数是 %zu\n", sizeof(long));          // 获取 long 类型的字节数
    printf("float 的字节数是 %zu\n", sizeof(float));        // 获取 float 类型的字节数
    printf("double 的字节数是 %zu\n", sizeof(double));      // 获取 double 类型的字节数

    return 0;
}

运行结果:

int 的字节数是 4
long 的字节数是 8
float 的字节数是 4
double 的字节数是 8

注意,C 语言是贴近硬件的底层语言,因此 int 等基本类型的大小在不同的环境(硬件、操作系统、编译器等)上可能是不同的。

可以通过 limits.h 头文件中的宏获取整数类型的范围。

在标准库头文件 stdint.h 中定义了固定长度的正数类型。

# 运算符优先级

运算符存在优先级,和数学一样先乘除,后加减。例如 \(3 + 5 * 2\) 结果为 \(13\)
括号为最高优先级,可以使用括号改变计算顺序。例如 \((3 + 5) * 2\) 结果为 \(16\)

下表为优先级列表,优先级由高到低:

没有必要全部记住,大部分符合直觉,拿不准时请使用括号。 部分运算符目前还没有学习,请暂时放下,将在后面的章节中学习。

参考:C Operator Precedence

优先级 运算符 结合性
最高 x++ x-- () [] . -> (type){list} 从左向右
2 ++x --x +x -x (type) * &x sizeof _Alignof 从右向左
3 * / % 从左向右
4 + - 从左向右
5 << >> 从左向右
6 < <= > >= 从左向右
7 == != 从左向右
8 & 从左向右
9 ^ 从左向右
10 \| 从左向右
11 && 从左向右
12 \|\| 从左向右
13 ?: 从右向左
14 = += -= *= /= %= <<= >>= &= ^= \|= 从右向左
最低 , 从左向右
本文 更新于: 2025-11-27 09:38:05 创建于: 2025-11-27 09:38:05