C 语言运算符优先级
一、引言
C语言作为一门高效、灵活的编程语言,其运算符系统丰富而复杂。正确理解运算符的优先级和结合性,是编写正确、高效代码的基础。本文将基于《编程运算符优先级.doc》的内容,系统讲解C语言中各类运算符的优先级规则,并通过丰富的示例和图表帮助读者深入理解。
二、运算符优先级总览
下表是C语言中所有运算符的优先级从高到低的完整列表,包括其名称、使用形式、结合方向和说明。
优先级 | 运算符 | 名称 | 使用形式 | 结合方向 | 说明 |
---|---|---|---|---|---|
1 | [] | 数组下标 | 数组名[常量表达式] | 左到右 | — |
() | 圆括号 | (表达式)/函数名(形参表) | — | ||
. | 成员选择(对象) | 对象.成员名 | — | ||
-> | 成员选择(指针) | 对象指针->成员名 | — | ||
2 | - | 负号运算符 | -表达式 | 右到左 | 单目运算符 |
~ | 按位取反 | ~表达式 | |||
++ -- | 自增/自减 | ++变量名/变量名++ | |||
* | 取值运算符 | *指针变量 | |||
& | 取地址运算符 | &变量名 | |||
! | 逻辑非 | !表达式 | |||
(类型) | 强制类型转换 | (数据类型)表达式 | — | ||
sizeof | 长度运算符 | sizeof(表达式) | — | ||
3 | * / % | 乘/除/取模 | 表达式 运算符 表达式 | 左到右 | 双目运算符 |
4 | + - | 加/减 | 表达式 运算符 表达式 | 左到右 | 双目运算符 |
5 | << >> | 左移/右移 | 变量 << 表达式 | 左到右 | 双目运算符 |
6 | > >= < <= | 关系运算符 | 表达式 运算符 表达式 | 左到右 | 双目运算符 |
7 | == != | 等于/不等于 | 表达式 运算符 表达式 | 左到右 | 双目运算符 |
8 | & | 按位与 | 表达式 & 表达式 | 左到右 | 双目运算符 |
9 | ^ | 按位异或 | 表达式 ^ 表达式 | 左到右 | 双目运算符 |
10 | ` | ` | 按位或 | 表达式 | 表达式 |
11 | && | 逻辑与 | 表达式 && 表达式 | 左到右 | 双目运算符 |
12 | ` | ` | 逻辑或 | 表达式 | |
13 | ?: | 条件运算符 | 表达式1 ? 表达式2 : 表达式3 | 右到左 | 三目运算符 |
14 | = 及复合赋值 | 赋值运算符 | 变量 = 表达式 | 右到左 | — |
15 | , | 逗号运算符 | 表达式, 表达式, … | 左到右 | — |
三、优先级规则详解与示例
1. 最高优先级:[]
()
.
->
这些运算符用于访问数组、函数、结构体成员等,具有最高的优先级。
int arr[10] = {0};
int value = arr[0]; // 取数组第一个元素struct Point { int x; int y; };
struct Point p = {1, 2};
int x = p.x; // 访问结构体成员struct Point *ptr = &p;
int y = ptr->y; // 通过指针访问结构体成员
2. 单目运算符:-
~
++
--
*
&
!
(类型)
sizeof
这些运算符是右结合的,常用于数值处理、指针操作、逻辑取反等。
int a = 10;
int b = -a; // 取负值
int c = ~a; // 按位取反
int *p = &a; // 取地址
int d = *p; // 取值
int e = !a; // 逻辑非:e为0(假)
int f = (double)a; // 强制类型转换
size_t size = sizeof(a); // 获取变量大小
3. 算术运算符:*
/
%
+
-
int a = 10 * 2; // 乘:20
int b = 10 / 3; // 除:3(整数除法)
int c = 10 % 3; // 取模:1
int d = 10 + 20; // 加:30
int e = 20 - 10; // 减:10
4. 移位运算符:<<
>>
int a = 1 << 3; // 左移3位:8
int b = 8 >> 2; // 右移2位:2
5. 关系运算符:>
>=
<
<=
==
!=
int a = 10 > 5; // 真:1
int b = 10 == 10; // 真:1
int c = 10 != 5; // 真:1
6. 位运算符:&
^
|
int a = 5 & 3; // 按位与:1
int b = 5 ^ 3; // 按位异或:6
int c = 5 | 3; // 按位或:7
7. 逻辑运算符:&&
||
int a = (10 > 5) && (5 < 8); // 真:1
int b = (10 < 5) || (5 < 8); // 真:1
8. 条件运算符:?:
int a = 10 > 5 ? 100 : 200; // 100
9. 赋值运算符:=
及复合赋值
int a = 10;
a += 5; // 等价于 a = a + 5
a <<= 1; // 等价于 a = a << 1
10. 逗号运算符:,
int a = (10, 20, 30); // a的值为30
四、结合方向的重要性
同一优先级的运算符,运算次序由结合方向决定。例如:
int a = 10, b = 20, c = 30;
int result = a = b = c; // 从右向左赋值:a、b、c都变为30
五、记忆口诀
! > 算术运算符 > 关系运算符 > && > || > 赋值运算符
六、运算符优先级关系图(Mermaid)
graph TDA[运算符优先级] --> B[1: [] () . ->]A --> C[2: - ~ ++ -- * & ! (类型) sizeof]A --> D[3: * / %]A --> E[4: + -]A --> F[5: << >>]A --> G[6: > >= < <=]A --> H[7: == !=]A --> I[8: &]A --> J[9: ^]A --> K[10: |]A --> L[11: &&]A --> M[12: ||]A --> N[13: ?:]A --> O[14: =及复合赋值]A --> P[15: ,]
七、生词表(中英对照)
单词/短语 | 音标 | 词性 | 词根/词缀 | 释义 | 搭配 | 例子 |
---|---|---|---|---|---|---|
Operator | /ˈɒpəreɪtə/ | n. | operate + -or | 运算符 | arithmetic operator | + is an operator. |
Precedence | /ˈpresɪdəns/ | n. | pre- + cedence | 优先级 | operator precedence | Precedence determines order. |
Associativity | /əˌsoʊʃiəˈtɪvəti/ | n. | associate + -ivity | 结合性 | right associativity | = has right associativity. |
Unary | /ˈjuːnəri/ | adj. | uni- + -ary | 单目的 | unary operator | - is a unary operator. |
Binary | /ˈbaɪnəri/ | adj. | bi- + -ary | 双目的 | binary operator | + is a binary operator. |
Ternary | /ˈtɜːrnəri/ | adj. | tern- + -ary | 三目的 | ternary operator | ?: is the only ternary operator. |
Bitwise | /ˈbɪtwaɪz/ | adj. | bit + -wise | 按位的 | bitwise AND | & is a bitwise operator. |
Assignment | /əˈsaɪnmənt/ | n. | assign + -ment | 赋值 | assignment operator | = is an assignment operator. |
Comma | /ˈkɒmə/ | n. | - | 逗号 | comma operator | , is used to separate expressions. |
八、结语
掌握C语言运算符的优先级和结合性是编写正确、高效程序的基础。建议读者通过实际编码练习加深理解,并在复杂表达式中合理使用括号明确运算顺序,避免潜在的错误。