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文章
4752浏览量
68360 -
编译器
+关注
关注
1文章
1618浏览量
49055 -
C代码
+关注
关注
1文章
89浏览量
14289
发布评论请先 登录
相关推荐
评论