自学内容网 自学内容网

# 深入解析C/C++中的关键运算符:i++, ++i, a=i++, a=++i 及复杂表达式的运算顺序

原因

  • 有没有人跟我一样,根本记不住那么多的运算符优先级,凭感觉猜的运算
    顺序,导致代码出错,调试半天,最后发现是优先级的问题
  • 有没有跟我一样,看到复杂表达式就头大
  • 看到一些复杂的表达式,不知道怎么去分析,只能硬着头皮去写,然后运行看结果,有时候还不懂为啥是那样运行的
  • 痛定思痛,决定写一篇博客,总结一下,以后再遇到复杂的表达式,可以更新上去,参考这篇博客,加深理解

前言

在C/C++编程中,运算符的优先级和结合性是理解复杂表达式运算顺序的关键。本文将深入探讨i++++ia=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运算符,以及一些复杂运算符的使用示例。后续遇到了,会继续补充。最后呢,在编写博客的过程中,我尽量保持内容的准确性和完整性,但也难免会有疏漏或错误之处。欢迎各位读者指出其中的问题,帮助我不断进步。谢谢大家的阅读,祝大家学习愉快!


原文地址:https://blog.csdn.net/m0_47673526/article/details/140278821

免责声明:本站文章内容转载自网络资源,如本站内容侵犯了原著者的合法权益,可联系本站删除。更多内容请关注自学内容网(zxcms.com)!