当前位置 博文首页 > 英雄哪里出来:??三万字《C语言运算符优先级面试错题100例》??
??运算符优先级一直是让人头疼的东西,趁着 字节取消大小周 的势头来临,通宵整理了一个思维导图出来,希望对你有所帮助。这篇文章,我会仔细分析这张思维导图。
??所有的 C语言运算符的用法都在这里了,并且还有优先级的例子解析,总共 100 道题都在这篇文章里了,激(累)动(死)人(我)心(了)
~
,用法诸如:~a
、~(a + b)
。!
,用法诸如:!a
、!(a + b)
。(type)
也是一种单目运算符,用法诸如:(int)a
,(int)(a + b)
。+-*/%
),都是双目运算符,用法诸如:a + b
、a * b
、a - b
、a % b
。==
、<=
、>
也都是双目运算符,用法诸如:a > b
、a <= b
、a != b
、a == b
。?:
,考虑这样一句话: if(a + b > 5) {
a++;
}else {
b++;
}
a + b > 5 ? a++ : b++;
运算符 | 名称 | 形式 | 举例1 | 举例2 |
---|---|---|---|---|
[] | 数组下标 | 数组名[常量表达式] | a[2] | a[2][3] |
() | 圆括号 | (表达式) 或 函数名(形参表) | (a+1) | fun(x,y,z) |
. | 对象的成员选择 | 对象.成员名 | a.b | a.b.c |
-> | 指针的成员选择 | 指针.成员名 | a->b | a->b->c |
运算符 | 名称 | 形式 | 举例1 | 举例2 |
---|---|---|---|---|
+ | 正号 | +表达式 | +5 | +a[3] |
- | 负号 | -表达式 | -5 | -a[3] |
(type) | 强制类型转换 | (数据类型)表达式 | (int)a | (int)a[0] |
++ | 自增运算符 | ++变量名 / 变量名++ | ++i | i++ |
-- | 自增运算符 | –变量名 / 变量名– | --i | i-- |
! | 逻辑非 | !表达式 | !a[0] | !a[0]++ |
~ | 按位取反 | ~表达式 | ~a | ~~a |
& | 取地址 | &变量名 | &a | &(a+1) |
* | 解引用 | *指针变量名 | *a | *(a+1) |
sizeof | 取长度 | sizeof(表达式) | sizeof(a) | sizeof(a + b) |
运算符 | 名称 | 形式 | 举例1 | 举例2 |
---|---|---|---|---|
* | 乘 | 表达式 * 表达式 | 3 * 5 | 3 * a |
/ | 除 | 表达式 / 表达式 | 3 / 5 | 3 / 5.0 |
% | 模 | 整型表达式 % 整型非零表达式 | 3 % 5 | b % -1 |
运算符 | 名称 | 形式 | 举例1 | 举例2 |
---|---|---|---|---|
+ | 加 | 表达式 + 表达式 | a + b | (a++) + b |
- | 减 | 表达式 - 表达式 | a - b | a - b-- |
运算符 | 名称 | 形式 | 举例1 | 举例2 |
---|---|---|---|---|
<< | 左移 | 变量<<表达式 | 1<<5 | 1<<(i+j) |
>> | 右移 | 变量>>表达式 | x>>1 | x>>a |
运算符 | 名称 | 形式 | 举例1 | 举例2 |
---|---|---|---|---|
< | 小于 | 表达式<表达式 | 1 < 2 | x < y |
<= | 小于等于 | 表达式<=表达式 | 1 <= 2 | x <= y |
> | 大于 | 表达式>表达式 | 1 > 2 | x > y |
>= | 大于等于 | 表达式>=表达式 | 1 >= 2 | x >= y |
运算符 | 名称 | 形式 | 举例1 | 举例2 |
---|---|---|---|---|
== | 等于 | 表达式==表达式 | 1 == 2 | x == y |
!= | 不等于 | 表达式!=表达式 | 1 != 2 | x != y |
运算符 | 名称 | 形式 | 举例1 | 举例2 |
---|---|---|---|---|
& | 等于 | 表达式&表达式 | 1 & 2 | x & y |
^ | 等于 | 表达式^表达式 | 1 ^ 2 | x ^ y |
| | 等于 | 表达式\表达式 | 1 | 2 | x | y |
运算符 | 名称 | 形式 | 举例1 | 举例2 |
---|---|---|---|---|
&& | 逻辑与 | 表达式&&表达式 | a && b | a + 5 && b + 5 |
|| | 逻辑与 | 表达式|| 表达式 | a || b | a + 5 || b + 5 |
运算符 | 名称 | 形式 | 举例1 | 举例2 |
---|---|---|---|---|
?: | 条件运算符 | 表达式1? 表达式2: 表达式3 | a>b?a:b | a<b?a:b |
运算符 | 名称 | 形式 | 举例1 | 举例2 |
---|---|---|---|---|
= | 赋值 | 变量=表达式 | a = b | a = 1 |
+= | 加后赋值 | 变量+=表达式 | a += b | a += 1 |
-= | 减后赋值 | 变量-=表达式 | a -= b | a -= 1 |
*= | 乘后赋值 | 变量*=表达式 | a *= b | a *= 1 |
/= | 除后赋值 | 变量/=表达式 | a /= b | a /= 1 |
%= | 模后赋值 | 变量%=表达式 | a %= b | a %= 1 |
>>= | 右移后赋值 | 变量>>=表达式 | a >>= b | a >>= 1 |
<<= | 左移后赋值 | 变量<<=表达式 | a <<= b | a <<= 1 |
&= | 位与后赋值 | 变量&=表达式 | a &= b | a &= 1 |
^= | 异或后赋值 | 变量^=表达式 | a ^= b | a ^= 1 |
|= | 位或后赋值 | 变量|= 表达式 | a |= b | a |= 1 |
运算符 | 名称 | 形式 | 举例1 | 举例2 |
---|---|---|---|---|
, | 逗号运算符 | 表达式1,表达式2,… | a+b,a-b | a||b,a&b |
,
将语句分隔,而无需添加多余的括号了。结合方向只有 3 个是 从右往左,其余都是 从左往右(比较符合人的直观感受)。
??(1)一个是单目运算符;
??(2)一个是双目运算符中的 赋值运算符;
??(3)一个条件运算符,也就是C语言中唯一的三目运算符。
后缀运算符和单目运算符优先级一般最高,逗号运算符的优先级最低。快速记忆如下:
单目逻辑运算符 > 算术运算符 > 关系运算符 > 双目逻辑运算符 > 赋值运算符
#include <stdio.h>
int a[2][2] = { {0, 1}, {2, 3}};
int main() {
printf("%d\n", a[1][0]);
return 0;
}
【运行结果】2
【结果答疑】这个例子体现的是下标运算符[]
的结合性是从左到右的。
#include <stdio.h>
int a[5] = {1, 2, 3, 4, 5};
int main() {
printf("%d\n", a[a[a[a[0]]]]);
return 0;
}
【运行结果】4
【结果答疑】这个例子体现的是下标运算符[]
的嵌套应用,从内层开始计算,a[0] == 1
,从而计算a[1]
,而a[1] == 2
,以此类推,得出最后的值为a[3]
,即 4。
#include <stdio.h>
int main() {
return 0;
}
【运行结果】
【结果答疑】这个例子就是给大家看一下圆括号的,大家看到了吗?没错!main()
是个函数,后面的括号里面跟的是参数列表,然而参数列表为空,就变成这个样子了。
#include <stdio.h>
int a[5] = {5, 4, 3, 2, 1};
int main() {
printf("%d\n", (a)[2] );
return 0;
}
【运行结果】3
【结果答疑】这个例子展示了()
和[]
的组合应用,这里的()
可有可无。
#include <stdio.h>
struct A {
int a;
}a;
int main() {
a.a = 5;
printf("%d\n", a.a );
return 0;
}
【运行结果】5
【结果答疑】这个例子体现了结构体的应用,并且我们可以通过.
获取到结构体的成员变量。
#include <stdio.h>
struct B {
int c;
};
struct A {
struct B b;
}a;
int main() {
a.b.c = 5;
printf("%d\n", a.b.c );
return 0;
}
【运行结果】5
【结果答疑】这个例子体现了结构体的嵌套,我们可以通过.
获取到结构体的成员变量,成员变量是一个结构体,所以可以继续通过.
获取它的成员变量,也间接了解了.
运算符的结合性是从左往右的。
#include <stdio.h>
struct A {
int b;
}a[10];
int main() {
a[0].b = 5;
printf("%d\n", a[0].b);
return 0;
}
【运行结果】5
【结果答疑】这个例子体现了结构体数组的应用,即当数组元素是一个结构体时,我们如何去访问它的成员变量。体现了[]
和.
的混合应用:优先级相同,结合性从左到右。
#include <stdio.h>
struct A {
int b;
}a;
struct A *pa;
int main() {
a.b = 9;
pa = &a;
printf("%d\n", pa->b);
return 0;
}
【运行结果】9
【结果答疑】这个例子体现了指针的的应用,->
左边的操作数是指针本针,右边的就指针指向对象的成员变量。有关于指针的内容,在后面的例题中会反复提到,现在只需要知道pa->b
是取成员变量就行了。
#include <stdio.h>
int a = 3, b = 4;
int main(