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

news2024/9/19 14:39:53

原因

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

前言

在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运算符,以及一些复杂运算符的使用示例。后续遇到了,会继续补充。最后呢,在编写博客的过程中,我尽量保持内容的准确性和完整性,但也难免会有疏漏或错误之处。欢迎各位读者指出其中的问题,帮助我不断进步。谢谢大家的阅读,祝大家学习愉快!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1907702.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

python爬虫入门(三)之HTML网页结构

一、什么是HTML 1、网页的三大技术要素&#xff1a; HTML定义网页的结构和信息&#xff08;骨架血肉&#xff09;CSS定义网页的样式&#xff08;衣服&#xff09;JavaScript定义用户和网页的交互逻辑&#xff08;动作&#xff09; 2、一个最简单的HTML&#xff1a;用<>…

动态数据库设计

动态数据库设计是一种灵活的方法&#xff0c;用于构建能够适应不断变化的数据需求的数据库结构。它强调在不频繁修改数据库表结构的前提下&#xff0c;有效管理和存储多样化的数据。以下是实现动态数据库设计的一些关键技术点和策略&#xff1a; 实体-属性-值&#xff08;EAV&a…

意得辑ABSJU202优惠15%啦,新用户注册直减哦

不得不说&#xff0c;还得是意得辑&#xff0c;钱不白花&#xff0c;润色的挺好~ 第一篇SCI终于成功见刊&#xff01;&#xff01;&#xff01; 都来接accept&#xff01;&#xff01;&#xff01;谢谢accept小狗&#xff0c;接accept 求求accept小狗&#xff0c;真的想要双证毕…

OpenLayers对要素进行新增绘制、选择、修改等交互操作

1、绘制-Draw 新建一个用来绘制要素的图层&#xff1a; const vector new VectorLayer({source: new VectorSource(),style: {"fill-color": "rgba(255, 255, 255, 0.2)","stroke-color": "#ffcc33","stroke-width": 2,&q…

如何提升美国Facebook直播的整体体验?

Facebook作为全球最大的社交媒体平台之一&#xff0c;提供了直播功能&#xff0c;用户可以实时分享生活、见解和创意。许多商家通过美国Facebook直播来获取更多客户&#xff0c;但直播时可能会遇到网络卡顿的问题&#xff0c;导致观看体验不佳。本文将探讨如何解决这个问题&…

Ubuntu开源软件LibreOffice将Excel多表转PDF多目录示例

一、实现的起因&#xff1a; Windows平台下&#xff0c;常见的WPS办公自动化套件中电子表格软件&#xff0c;其中具备将Excel工作表中数据转为PDF文档表格的功能。现在进一步的需求是&#xff1a;像PDF标准的电子书那样&#xff0c;具备一本书的目录结构或章节结构&#xff0c…

[C++]入门基础(1)

Hello大家好&#xff0c;今天通过本篇文章&#xff0c;我们来初步学习C&#xff0c;C可以说是对C语言的一个升级&#xff0c;我们会一步一步的由浅入深的学习C。 目录 1.第一个C程序 2.命名空间 2.1 命名空间出现的意义 2.2 namespace的定义 2.3 命名空间的使用 3.C输入…

Spring Cloud - 代码生成器

1、代码生成器概述 Spring Cloud 并没有提供类似于 Spring Data 中的“代码生成器”&#xff0c;因为它主要提供的是分布式系统中服务发现和配置管理的一套解决方案。如果你想要为你的微服务应用生成样板代码&#xff0c;你可能需要考虑使用其他工具或者方案&#xff0c;例如 S…

基于SSM的志愿者服务平台

基于SSM的志愿者服务平台系统主要其系统包括不同的端组成&#xff0c;前端主要包括系统用户管理、新闻数据管理、变幻图管理、志愿者管理、培训视频管理、志愿者项目管理、服务时长管理、交流分享管理、志愿者表彰管理。前台主要包括网站首页、培训视频、志愿者项目、交流分享、…

【python中级】图像从笛卡尔坐标系转换为极坐标系

【python中级】图像从笛卡尔坐标系转换为极坐标系 1.背景2.生成二维图3.极坐标转换1.背景 笛卡尔坐标系就是我们常说的直角坐标系。 笛卡尔坐标系,也称为直角坐标系,是由法国数学家和哲学家勒内笛卡尔(Ren Descartes)发明的一种二维或三维坐标系统。它使用两个或三个相互垂…

李彦宏: 开源模型是智商税|马斯克: OpenAI 闭源不如叫 CloseAI

在 2024 年世界人工智能大会&#xff08;WAIC 2024&#xff09;上&#xff0c;百度创始人、董事长兼首席执行官李彦宏发表对开源模型的评价。 李彦宏认为&#xff1a;开源模型实际上是一种智商税&#xff0c;而闭源模型才是人工智能&#xff08;AI&#xff09;行业的未来。 马…

基于LangChain的RAG开发教程(二)

v1.0官方文档&#xff1a;https://python.langchain.com/v0.1/docs/get_started/introduction/ 最新文档&#xff1a;https://python.langchain.com/v0.2/docs/introduction/ LangChain是一个能够利用大语言模型&#xff08;LLM&#xff0c;Large Language Model&#xff09;能…

git恢复到之前提交的记录

项目搞崩了&#xff0c;还提交上去了怎么办&#xff1f; 那当然是恢复到之前的提交记录了&#xff0c;那怎么操作呢&#xff1f; 首先&#xff0c;到代码托管平台找到你想恢复的提交记录(在此以github为例) 获取 commit id 首先&#xff0c;通过如下图操作获取到commit id {% a…

Spring Cloud: OpenFeign 超时重试机制

超时重试是一种用于网络通信的常用策略&#xff0c;目的是在请求未能在规定时间内获得响应或响应超时的情况下&#xff0c;重新发送请求。具体来说&#xff0c;当发起请求后&#xff0c;如果在设定的时间内未能收到预期的响应&#xff0c;就会启动超时重试机制&#xff0c;重新…

徒手绘制 Android 通用进度条

拖动条&#xff08;FlexSeekBar&#xff09;&#xff0c;在Android的各个地方都非常常用&#xff0c;本文旨在自研一套通用的进度条&#xff0c;非常适合车载App使用 样式如下&#xff1a; 使用示例 <!--默认用法--> <com.max.android.ui.seekbar.FlexSeekBarandroi…

python获取文件列表按照文件修改时间进行排序,默认按照文件名时间戳排序

python获取文件列表按照文件修改时间进行排序,默认按照文件名时间戳排序 1、流程 1、获取文件绝对路径下的所有文件 2、通过os.path.getmtime获取每个文件的修改时间,并与文件组成元组,方便后续排序 3、默认按照时间戳降序,否则按照按修改时间排序文件列表(从最晚到最早)…

Linux忘记密码重置root密码、重置普通用户密码

重启看到选项按e reboot 或 init 62、移动到Linux开头的行在末尾添加 rw init/bin/bash3、按下Ctrlx引导启动 mount -o remount,rw /输入命令回车更改密码,输入新密码&#xff0c;别用小键盘&#xff0c;容易出错 passwd输入两次校验&#xff0c;出现updated successfully就…

几何建模基础-样条曲线和样条曲面介绍

1.概念介绍 1.1 样条曲线的来源 样条的英语单词spline来源于可变形的样条工具&#xff0c;那是一种在造船和工程制图时用来画出光滑形状的工具&#xff1a;富有弹性的均匀细木条/金属条/有机玻璃条&#xff0c;它围绕着按指定位置放置的重物或者压铁做弹性弯曲&#xff0c;以…

SAPUI5基础知识12 - 应用程序描述符(manifest.json)

1. 背景 在SAPUI5中&#xff0c;manifest.json是一个配置文件&#xff0c;它包含了应用程序的所有配置信息。这个文件是SAPUI5应用程序的核心&#xff0c;它定义了应用程序的元数据&#xff0c;包括应用程序的名称、描述、版本、模型、路由等信息。 manifest.json的主要功能和…

如何使用Vue3创建在线三维模型展示?

本文由ScriptEcho平台提供技术支持 项目地址&#xff1a;传送门 代码相关的技术博客 代码应用场景介绍 本段代码使用 RoughJS 库在 HTML5 Canvas 上创建了手绘风格的图像&#xff0c;展示了 RoughJS 库的强大功能&#xff0c;可用于创建具有有机手绘外观的图形。 代码基本…