原因
- 有没有人跟我一样,根本记不住那么多的运算符优先级,凭感觉猜的运算
顺序,导致代码出错,调试半天,最后发现是优先级的问题 - 有没有跟我一样,看到复杂表达式就头大
- 看到一些复杂的表达式,不知道怎么去分析,只能硬着头皮去写,然后运行看结果,有时候还不懂为啥是那样运行的
- 痛定思痛,决定写一篇博客,总结一下,以后再遇到复杂的表达式,可以更新上去,参考这篇博客,加深理解
前言
在C/C++编程中,运算符的优先级和结合性是理解复杂表达式运算顺序的关键。本文将深入探讨i++
、++i
、a=i++
和a=++i
这四个关键运算符的运算顺序,并分析它们在不同情况下的行为。如果绝对对您有所帮助,请可以点个关注收藏一下,谢谢!
墨小羽ovo
1.运算符优先级和结和性
1.1 算数运算符
+
、-
、*
、/
、%
:算术运算符,按照从左到右的顺序进行运算。++
、--
:自增和自减运算符,按照从右到左的顺序进行运算。
1.2 赋值运算符
=
:赋值运算符,按照从右到左的顺序进行运算。
1.3 关系运算符
==
、!=
、<
、>
、<=
、>=
:关系运算符,按照从左到右的顺序进行运算。
1.4 逻辑运算符
&&
、||
:逻辑运算符,按照从左到右的顺序进行运算。
1.5 位运算符
&
、|
、^
、~
、<<
、>>
:位运算符,按照从左到右的顺序进行运算。
示例程序:
#include <stdio.h>
int main() {
int a = 1, b = 2, c = 3;
int d = a + b<<1
printf("d = %d\n", d); // 输出:d = 5
return 0;
}
输出结果:
d = 6
注意 可能好多人以为等于5,我也这样以为哩,看了好久没想明白
<<
运算符的优先级低于+
运算符,所以先进行+
运算,再进行<<
运算。- 运算顺序:先算a+b,再算<<1,最后赋值给d。
1.6 条件运算符(三元运算符)
?:
:条件运算符,按照从右到左的顺序进行运算。
示例:
int a = 1, b = 2, c = 3;
int d = a > b ? a : b; // 等价于 int d = (a > b) ? a : b;
`d = 2`
1.7 指针运算符
*
、&
:指针运算符,按照从右到左的顺序进行运算。
1.8 sizeof运算符
sizeof
:sizeof运算符,按照从右到左的顺序进行运算。
结合方向
- 从右到左:双目运算符中的赋值运算符 单目运算符,三目运算符
- 从左到右:算数运算符,关系运算符,逻辑运算符,位运算符
- 优先级:! > 算术运算符 > 关系运算符 > && > || > 赋值运算符
运算符结合的优先级表
参考这位大佬的博客,很详细
运算符结合优先级表
2. i++
和++i
i++
:后置递增运算符,先返回i
的当前值,然后将i
的值增加1。++i
:前置递增运算符,先将i
的值增加1,然后返回增加后的值。
示例程序
#include <stdio.h>
int main() {
int i = 0;
int a = i++;
printf("i = %d, a = %d\n", i, a); // 输出:i = 1, a = 0
i = 0;
a = ++i;
printf("i = %d, a = %d\n", i, a); // 输出:i = 1, a = 1
return 0;
}
3. a=i++
和a=++i
a=i++
:先将i
的当前值赋给a
,然后将i
的值增加1。a=++i
:先将i
的值增加1,然后将增加后的值赋给a
。
示例程序
#include <stdio.h>
int main() {
int i = 0;
int a = i++;
printf("i = %d, a = %d\n", i, a); // 输出:i = 1, a = 0
i = 0;
a = ++i;
printf("i = %d, a = %d\n", i, a); // 输出:i = 1, a = 1
return 0;
}
4.*(pDataByte++)*pDataByte++区别
*(pDataByte++)
:先解引用pDataByte
指向的地址,然后将pDataByte
的值增加1。*pDataByte++
:先将pDataByte
的值增加1,然后解引用增加后的地址。
示例程序
#include <stdio.h>
int main() {
int data[] = {1, 2, 3};
int *pDataByte = data;
# if 1
// int a = *(pDataByte++);
printf("a = %d\n",*(pDataByte++)); // 输出:a = 1
#else
//int b = *pDataByte++;
printf("b = %d\n", *pDataByte++); // 输出:b = 1
#endif
return 0;
}
运行结果:
a = 1 b = 1
5.USART_RX_BUF[USART_RX_LEN++]=Res;
USART_RX_BUF[USART_RX_LEN++]=Res
:先将Res
的值赋给USART_RX_BUF[USART_RX_LEN]
,然后将USART_RX_LEN
的值增加1。
示例程序
#include <stdio.h>
int main() {
char USART_RX_BUF[10] = {0};
int USART_RX_LEN = 0;
char Res = 'A';
USART_RX_BUF[USART_RX_LEN++] = Res;
printf("USART_RX_BUF[%d] = %c\n", USART_RX_LEN - 1, USART_RX_BUF[USART_RX_LEN - 1]); // 输出:USART_RX_BUF[0] = A
return 0;
}
输出结果:
USART_RX_BUF[0] = A
a+++b
a+++b
:先返回a
的当前值,然后将a
的值增加1,最后返回b
的值。- 执行顺序:先执行
a++
,所以a等于0,在执行a+b再执行b
,最后返回a
的当前值。
示例程序
#include <stdio.h>
int main() {
int a = 0;
int b = 1;
int c = a+++b;
printf("a = %d, b = %d, c = %d\n", a, b, c); // 输出:a = 1, b = 1, c = 1
return 0;
}
输出结果:
a = 1, b = 1, c = 1
a++,(a++) (*a)++ *++a,
- a++和(a++)都返回a原来指向的值,并将a指向下一个内存位置。
- (*a)++返回a指向的值,并将该值增加1,但不影响a的指向。
- *++a先将a指向下一个内存位置,然后返回新位置的值。
示例程序
#include <stdio.h>
int main() {
int data[] =
{ 1, 4, 7 };
int *a = data;
//printf("%d\n", *a++); // 输出:1
// printf("%d\n", *(a++)); // 输出:1
// printf("%d\n", (*a)++); // 输出:1
// printf("%d\n", *++a); // 输出:4
printf("%d\n", ++*a); // 输出:2
return 0;
}
参考资料
运算符结合优先级表
C语言基础知识:操作符详解(附操作符优先级及结合性一览表
总结
这篇博客,主要介绍了C语言中的运算符,包括算术运算符、关系运算符、逻辑运算符、位运算符、赋值运算符、条件运算符、指针运算符、sizeof运算符,以及一些复杂运算符的使用示例。后续遇到了,会继续补充。最后呢,在编写博客的过程中,我尽量保持内容的准确性和完整性,但也难免会有疏漏或错误之处。欢迎各位读者指出其中的问题,帮助我不断进步。谢谢大家的阅读,祝大家学习愉快!