0
  • 聊天消息
  • 系统消息
  • 评论与回复
登录后你可以
  • 下载海量资料
  • 学习在线课程
  • 观看技术视频
  • 写文章/发帖/加入社区
会员中心
创作中心

完善资料让更多小伙伴认识你,还能领取20积分哦,立即完善>

3天内不再提示

C代码中的惊喜

刘勇 来源:阿兵888824 作者:阿兵888824 2022-07-15 08:17 次阅读
加入交流群
微信小助手二维码

扫码添加小助手

加入工程师交流群

C 语言非常灵活且富有表现力;这些是它成功并能够被“更好”的语言取代的一些原因。其灵活性的一个例子是可以以多种功能等效的方式编写表达式。这使得编码风格能够适应个人需求。但是,有一个问题:有时,表面上等效的代码有细微的差别。这可以在最简单的代码中发生,我们将在本文中探讨一些可能性。

C 提供几种不同的方法来做某事是很常见的,所有这些方法都是完全等价的。例如,假设x是一个普通的int变量,以下每个语句都将执行完全相同的工作:

x = x + 1; x += 1; x++; ++x;

在每种情况下,都会将1添加到x。唯一可能的区别是,功能较弱的编译器可能会为最后两个选项生成稍微更好的代码(这暗示着获得更好的编译器是值得的)。

以这种方式使用的两种形式的++运算符产生相同的结果。但是,如果使用表达式的值,则前置增量和后置增量是不同的,因此:

y = x++; // y 在增量之前具有 x 的值 y = ++x; // y 在增量后具有 x 的值

有趣的是,后增量稍微“昂贵”一些,因为需要分配存储以保持x的旧值。但是,编译器可能会将其优化掉。如果在不使用表达式值时分配存储,那么肯定需要新的编译器!

如果x不是int,而是指向int的指针,则加1将具有加4的效果(在 32 位机器上)。如果这是一个很大的惊喜,那么重新学习指针算法是必要的。

然而,有时看起来等价的结构会有非常细微的差异……

在任何编程语言中,您可以做的最简单的事情可能就是为变量赋值。因此,在 C 语言中,我们可以这样写:

阿尔法 = 99; 贝塔 = 99; 伽玛 = 99;

当然,这可能会写得更紧凑,如下所示:

阿尔法 = 贝塔 = 伽马 = 99;

这些是 100% 等效的。还是他们?

大多数情况下,这两种结构是完全等价的,但是(至少)有四种情况选择其中一种可能会有所不同:

首先,也是最平淡无奇的,每个变量都是独立的,也许一个注释说明为什么它被设置为这个值可能是合适的。

其次,编写可维护的代码总是好的。也许,在将来的某个时候,可能需要更改代码,以便所有三个变量都不会设置为相同的值。第一种格式更容易修改。

第三个原因与不合标准的编译器有关,它可能会为第一个构造生成如下代码:

mov r0, #99 移动阿尔法,r0 mov r0, #99 mov beta, r0 mov r0, #99 mov 伽马, r0

第二个构造暗示r0只需要加载一次。同样,更好的编译器不需要提示。

最后是执行顺序的问题。在第一个构造中,很明显 alpha 将首先分配,而 gamma 最后分配。编译器将这样解释第二个构造:

阿尔法 = (贝塔 = (伽马 = 99));

这意味着分配顺序是颠倒的。但这有关系吗?大多数时候,它没有。但如果这些是设备寄存器,而不是普通变量,它可能会产生很大的不同。硬件需要以精确的顺序加载设置值是很常见的。

所以,我想说应该避免在一个语句结构中进行多个赋值。

总体而言,尽管 C 是一种小型语言,但可以说它可以通过提供更少的做事方式来变得更小。结果可能是更清晰、更易于维护的代码。

审核编辑:郭婷

声明:本文内容及配图由入驻作者撰写或者入驻合作网站授权转载。文章观点仅代表作者本人,不代表电子发烧友网立场。文章及其配图仅供工程师学习之用,如有内容侵权或者其他违规问题,请联系本站处理。 举报投诉
  • 代码
    +关注

    关注

    30

    文章

    4976

    浏览量

    74369
  • 编译器
    +关注

    关注

    1

    文章

    1672

    浏览量

    51903
  • C代码
    +关注

    关注

    1

    文章

    90

    浏览量

    15227
收藏 人收藏
加入交流群
微信小助手二维码

扫码添加小助手

加入工程师交流群

    评论

    相关推荐
    热点推荐

    80后硬件人 I 青春藏在焊盘里,热爱写在代码

    导语:技术从来不是一成不变的教条,而是一场漫长且充满惊喜的探索。今天,想和大家聊聊80后硬件工程师,深耕硬件多年,藏在焊盘与代码里的时光与感悟。这些年,一直扎根在硬件领域,从一块简单的PCB版图绘制
    的头像 发表于 02-27 17:12 1237次阅读
    80后硬件人 I 青春藏在焊盘里,热爱写在<b class='flag-5'>代码</b><b class='flag-5'>中</b>

    在Keil中进行C代码与汇编代码的混合编程

    1. 在 C 代码调用汇编程序代码C 代码
    发表于 01-23 06:36

    深度解析SPL阶段A/B分区启动:spl_ab.c代码全拆解

    ( Secondary Program Loader ,二级程序加载器)作为系统启动的早期阶段,负责初始化硬件、选择启动分区, spl_ab.c 正是 SPL 层处理 A/B 分区启动的核心代码。本文将从函数
    的头像 发表于 01-20 07:07 1w次阅读
    深度解析SPL阶段A/B分区启动:spl_ab.<b class='flag-5'>c</b><b class='flag-5'>代码</b>全拆解

    c语言中的代码优化

    在性能优化方面永远注意80-20原则,即20%的程序消耗了80%的运行时间,于是咱们要改进效率,最主要是考虑改进那20%的代码。不要优化程序开销不大的那80%,这是劳而无功的。 第一招:以空间换
    发表于 01-12 09:45

    FLASH代码是如何得到运行的呢

    以ARM为例: ARM-cortex-M3/4的单片机(比如STM32 等):该类单片机的代码在nor flash,cortex内核可以直接运行,不需要将代码加载到ram运行
    发表于 12-04 08:06

    求助,关于C代码的printf打印的疑问求解

    在使用E203 testbench执行附带的benchmark测试用例时候,得到如下打印信息: CPU验证小白一枚,有个问题不是很理解:黄色框框内的字符看起来应该是C代码的printf语句
    发表于 11-10 07:54

    超值钜惠,惊喜不断!解锁你的双11省钱攻略!

    超值钜惠,惊喜不断!解锁你的双11省钱攻略!
    的头像 发表于 10-23 18:49 330次阅读
    超值钜惠,<b class='flag-5'>惊喜</b>不断!解锁你的双11省钱攻略!

    请问cypd3125在 ( EZ-PD™ CCGx Host SDK) 的流程代码如何从main.c到所有.c运行里面有文件吗?

    到所有 .c文件代码流我需要知道 CYPD3125-40LQXI_notebook 很复杂才能理解 sdk 的工作流程您能否提供任何文档或解释 CYPD3125-40LQXI_notebook
    发表于 08-15 06:58

    嵌入式系统,FLASH 的程序代码必须搬到 RAM 运行吗?

    嵌入式系统里,FLASH 的程序代码并非必须搬到 RAM 运行,这得由硬件配置、实际性能需求和应用场景共同决定。就像很多低端单片机,无论是依赖片内 Flash 还是外挂的 SPI NOR
    的头像 发表于 08-06 10:19 1519次阅读
    嵌入式系统<b class='flag-5'>中</b>,FLASH <b class='flag-5'>中</b>的程序<b class='flag-5'>代码</b>必须搬到 RAM <b class='flag-5'>中</b>运行吗?

    Perforce QAC产品简介:面向C/C++的静态代码分析工具(已通过SO 26262认证)

    Perforce QAC专为C/C++开发者打造,支持多种编码规范、功能安全标准(ISO 26262)等,广泛用于汽车、医疗、嵌入式开发领域,可帮助快速识别关键缺陷、提升代码质量、实现合规交付。
    的头像 发表于 07-10 15:57 1451次阅读
    Perforce QAC产品简介:面向<b class='flag-5'>C</b>/<b class='flag-5'>C</b>++的静态<b class='flag-5'>代码</b>分析工具(已通过SO 26262认证)

    深入理解C语言:函数—编程的“积木块”艺术

    在编程的世界里,函数就像建筑的“积木块”——它们是构建复杂程序的基石。通过灵活组合这些模块,开发者能打造出功能强大且结构清晰的代码。函数之所以成为C语言的核心,正是因为它解决了编程
    的头像 发表于 06-30 17:26 2030次阅读
    深入理解<b class='flag-5'>C</b>语言:函数—编程<b class='flag-5'>中</b>的“积木块”艺术

    用CubeMX生成代码时会将main.c文件的汉字变成乱码,怎么解决?

    使用CubeMX生成代码时,经常会遇到原main.c文件的汉字全部变成乱码,如下图所示: 将这些乱码字符重新修改后,只要再次用CubeMX生成代码,这些汉字又会成为乱码,请问该如何
    发表于 06-23 08:02

    在OpenVINO™ C++代码启用 AddressSanitizer 时的内存泄漏怎么解决?

    在 OpenVINO™ C++代码启用 AddressSanitizer 时遇到内存泄漏: \"#0 0xaaaab8558370 in operator new(unsigned
    发表于 06-23 07:16

    6.18年终狂欢购!满额即赠,惊喜享不停!

    6.18年终狂欢购!满额即赠,惊喜享不停!
    的头像 发表于 05-30 18:04 805次阅读
    6.18年终狂欢购!满额即赠,<b class='flag-5'>惊喜</b>享不停!

    深入理解C语言:C语言循环控制

    C语言编程,循环结构是至关重要的,它可以让程序重复执行特定的代码块,从而提高编程效率。然而,为了避免程序进入无限循环,C语言提供了多种循环控制语句,如break、continue和
    的头像 发表于 04-29 18:49 2209次阅读
    深入理解<b class='flag-5'>C</b>语言:<b class='flag-5'>C</b>语言循环控制