C代码中的惊喜

电子说

1.3w人已加入

描述

  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 是一种小型语言,但可以说它可以通过提供更少的做事方式来变得更小。结果可能是更清晰、更易于维护的代码。

       审核编辑:郭婷

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

全部0条评论

快来发表一下你的评论吧 !

×
20
完善资料,
赚取积分