C语言运算符和表达式

运算符是C语言中用于执行特定操作的符号,表达式则是由操作数和运算符组成的计算式。掌握各种运算符的使用方法和优先级是编写正确C程序的关键。本文将详细介绍C语言中的各类运算符及其应用。

算术运算符

算术运算符用于执行基本的数学运算。

基本算术运算符

运算符 描述 示例 结果
+ 加法 5 + 3 8
- 减法 5 - 3 2
* 乘法 5 * 3 15
/ 除法 10 / 3 3(整数除法)
% 取模(余数) 10 % 3 1
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
#include <stdio.h>

int main() {
int a = 10, b = 3;
float x = 10.0, y = 3.0;

printf("整数运算:\n");
printf("%d + %d = %d\n", a, b, a + b);
printf("%d - %d = %d\n", a, b, a - b);
printf("%d * %d = %d\n", a, b, a * b);
printf("%d / %d = %d\n", a, b, a / b); // 整数除法
printf("%d %% %d = %d\n", a, b, a % b);

printf("\n浮点数运算:\n");
printf("%.1f / %.1f = %.2f\n", x, y, x / y); // 浮点除法

return 0;
}

注意事项

  1. 整数除法:两个整数相除结果为整数,小数部分被截断
  2. 取模运算:只能用于整数,不能用于浮点数
  3. 除零错误:除数不能为零,否则程序会崩溃

赋值运算符

基本赋值运算符

1
int x = 10;  // 将10赋值给x

复合赋值运算符

运算符 等价形式 描述
+= x = x + y 加法赋值
-= x = x - y 减法赋值
*= x = x * y 乘法赋值
/= x = x / y 除法赋值
%= x = x % y 取模赋值
1
2
3
4
5
6
7
8
9
int x = 10;

x += 5; // x = x + 5, 结果:x = 15
x -= 3; // x = x - 3, 结果:x = 12
x *= 2; // x = x * 2, 结果:x = 24
x /= 4; // x = x / 4, 结果:x = 6
x %= 4; // x = x % 4, 结果:x = 2

printf("最终结果:%d\n", x);

自增和自减运算符

前缀和后缀形式

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
int a = 5, b = 5;
int result1, result2;

// 前缀自增:先增加,后使用
result1 = ++a; // a先变成6,然后赋值给result1
printf("前缀自增:a = %d, result1 = %d\n", a, result1);

// 后缀自增:先使用,后增加
result2 = b++; // b的值5先赋给result2,然后b变成6
printf("后缀自增:b = %d, result2 = %d\n", b, result2);

// 自减运算符类似
int c = 10;
printf("前缀自减:%d\n", --c); // 输出9,c变成9
printf("后缀自减:%d\n", c--); // 输出9,然后c变成8
printf("最终c的值:%d\n", c); // 输出8

比较运算符

比较运算符用于比较两个值,返回1(真)或0(假)。

运算符 描述 示例
== 等于 a == b
!= 不等于 a != b
> 大于 a > b
< 小于 a < b
>= 大于等于 a >= b
<= 小于等于 a <= b
1
2
3
4
5
6
7
8
9
int a = 10, b = 20;

printf("比较运算结果:\n");
printf("%d == %d: %d\n", a, b, a == b); // 0 (假)
printf("%d != %d: %d\n", a, b, a != b); // 1 (真)
printf("%d > %d: %d\n", a, b, a > b); // 0 (假)
printf("%d < %d: %d\n", a, b, a < b); // 1 (真)
printf("%d >= %d: %d\n", a, b, a >= b); // 0 (假)
printf("%d <= %d: %d\n", a, b, a <= b); // 1 (真)

逻辑运算符

逻辑运算符用于组合或修改布尔表达式。

运算符 描述 示例
&& 逻辑与 a && b
|| 逻辑或 a || b
! 逻辑非 !a
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
int a = 1, b = 0;  // 1表示真,0表示假

printf("逻辑运算结果:\n");
printf("%d && %d = %d\n", a, b, a && b); // 0 (假)
printf("%d || %d = %d\n", a, b, a || b); // 1 (真)
printf("!%d = %d\n", a, !a); // 0 (假)
printf("!%d = %d\n", b, !b); // 1 (真)

// 实际应用示例
int age = 20;
int has_license = 1;

if (age >= 18 && has_license) {
printf("可以开车\n");
} else {
printf("不能开车\n");
}

短路求值

1
2
3
4
5
6
7
8
9
10
11
12
13
14
int x = 0;
int y = 5;

// 逻辑与的短路求值
if (x != 0 && y / x > 2) { // 由于x != 0为假,不会执行y / x
printf("条件成立\n");
} else {
printf("条件不成立\n");
}

// 逻辑或的短路求值
if (x == 0 || y / x > 2) { // 由于x == 0为真,不会执行y / x
printf("至少一个条件成立\n");
}

位运算符

位运算符对整数的二进制位进行操作。

运算符 描述 示例
& 按位与 a & b
| 按位或 a | b
^ 按位异或 a ^ b
~ 按位取反 ~a
<< 左移 a << 2
>> 右移 a >> 2
1
2
3
4
5
6
7
8
9
10
int a = 12;  // 二进制:1100
int b = 10; // 二进制:1010

printf("位运算结果:\n");
printf("%d & %d = %d\n", a, b, a & b); // 8 (1000)
printf("%d | %d = %d\n", a, b, a | b); // 14 (1110)
printf("%d ^ %d = %d\n", a, b, a ^ b); // 6 (0110)
printf("~%d = %d\n", a, ~a); // -13
printf("%d << 1 = %d\n", a, a << 1); // 24 (左移1位)
printf("%d >> 1 = %d\n", a, a >> 1); // 6 (右移1位)

其他运算符

条件运算符(三元运算符)

1
2
3
4
5
6
7
8
9
10
11
12
// 语法:条件 ? 表达式1 : 表达式2
int a = 10, b = 20;
int max = (a > b) ? a : b;
printf("较大值:%d\n", max);

// 等价于
int max2;
if (a > b) {
max2 = a;
} else {
max2 = b;
}

sizeof运算符

1
2
3
4
5
6
7
8
9
10
11
int x = 10;
float y = 3.14f;
char z = 'A';

printf("sizeof运算符:\n");
printf("sizeof(int) = %zu\n", sizeof(int));
printf("sizeof(x) = %zu\n", sizeof(x));
printf("sizeof(float) = %zu\n", sizeof(float));
printf("sizeof(y) = %zu\n", sizeof(y));
printf("sizeof(char) = %zu\n", sizeof(char));
printf("sizeof(z) = %zu\n", sizeof(z));

运算符优先级

运算符优先级决定了表达式中运算的执行顺序。

优先级 运算符 结合性
1 () [] -> . 左到右
2 ! ~ ++ – + - * & sizeof 右到左
3 * / % 左到右
4 + - 左到右
5 << >> 左到右
6 < <= > >= 左到右
7 == != 左到右
8 & 左到右
9 ^ 左到右
10 | 左到右
11 && 左到右
12 || 左到右
13 ?: 右到左
14 = += -= *= /= %= 右到左
1
2
3
4
5
6
7
8
9
// 优先级示例
int result = 2 + 3 * 4; // 结果:14 (不是20)
int result2 = (2 + 3) * 4; // 结果:20
int result3 = 10 > 5 && 3 < 7; // 结果:1 (真)

printf("优先级示例:\n");
printf("2 + 3 * 4 = %d\n", result);
printf("(2 + 3) * 4 = %d\n", result2);
printf("10 > 5 && 3 < 7 = %d\n", result3);

表达式求值

复杂表达式示例

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
#include <stdio.h>

int main() {
int a = 5, b = 10, c = 15;
int result;

// 复杂表达式
result = a + b * c / 5 - 2;
printf("a + b * c / 5 - 2 = %d\n", result); // 33

// 使用括号改变优先级
result = (a + b) * c / (5 - 2);
printf("(a + b) * c / (5 - 2) = %d\n", result); // 75

// 混合使用不同类型的运算符
int x = 8, y = 3;
int complex_result = (x > y) ? x * 2 + y : x / y;
printf("条件表达式结果:%d\n", complex_result); // 19

return 0;
}

常见错误和注意事项

1. 赋值与比较的混淆

1
2
3
4
5
6
7
8
9
10
11
int x = 5;

// 错误:使用赋值而不是比较
if (x = 10) { // 这是赋值,不是比较!
printf("这总是会执行\n");
}

// 正确:使用比较运算符
if (x == 10) {
printf("x等于10\n");
}

2. 整数除法的陷阱

1
2
3
4
5
6
int a = 5, b = 2;
float result1 = a / b; // 结果:2.0 (整数除法)
float result2 = (float)a / b; // 结果:2.5 (浮点除法)

printf("整数除法:%.1f\n", result1);
printf("浮点除法:%.1f\n", result2);

3. 自增自减的副作用

1
2
3
4
5
6
7
8
int i = 5;
int result = i++ + ++i; // 未定义行为,避免这样使用

// 推荐的写法
i = 5;
int temp1 = i++;
int temp2 = ++i;
result = temp1 + temp2;

实践练习

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
#include <stdio.h>

int main() {
// 练习1:计算圆的面积和周长
float radius = 5.0;
float pi = 3.14159;
float area = pi * radius * radius;
float circumference = 2 * pi * radius;

printf("半径为%.1f的圆:\n", radius);
printf("面积:%.2f\n", area);
printf("周长:%.2f\n", circumference);

// 练习2:判断一个数是否为偶数
int number = 42;
int is_even = (number % 2 == 0);
printf("%d是%s数\n", number, is_even ? "偶" : "奇");

// 练习3:交换两个变量的值(不使用第三个变量)
int x = 10, y = 20;
printf("交换前:x = %d, y = %d\n", x, y);

x = x + y; // x = 30
y = x - y; // y = 10
x = x - y; // x = 20

printf("交换后:x = %d, y = %d\n", x, y);

return 0;
}

总结

运算符和表达式是C语言编程的核心组成部分。通过本文的学习,你应该掌握:

  1. 算术运算符:基本数学运算的实现
  2. 赋值运算符:变量值的设置和更新
  3. 比较运算符:条件判断的基础
  4. 逻辑运算符:复杂条件的组合
  5. 位运算符:底层数据操作
  6. 运算符优先级:表达式求值的规则

在实际编程中,要注意运算符的优先级,合理使用括号来明确表达式的含义,避免常见的错误如赋值与比较的混淆。掌握这些知识将为后续学习控制结构和函数打下坚实的基础。

版权所有,如有侵权请联系我