【问题标题】:c: assignment used in calculationc:计算中使用的赋值
【发布时间】:2013-08-21 08:45:33
【问题描述】:

我有一个问题想用谷歌搜索,但我不知道该问她/她/它什么(谷歌:))

在网上的几个示例代码中找到了这样的分配(这个特定的代码源自here,他们从Numerical Recipes in C 第508 页复制了代码)。

我试图理解下一行中赋值的用法:

wr = (wtemp = wr) * wpr - wi * wpi + wr;

就我自己对编程逻辑的理解而言,我会把它翻译成

wtemp = wr;
wr = wtemp * wpr - wi * wpi + wr;

是这样吗?还是应该是wpr * wpr - wi [...]?还是完全不同的东西:D?

(根据wikipedia,赋值运算符返回对受让人的引用,根据the free dictionary - 我检查确定 - 是某物被分配的值)

【问题讨论】:

  • 那篇维基百科文章是关于 C++,而不是 C。C 没有重载的运算符或引用。

标签: c assignment-operator


【解决方案1】:

表达式a = b的值是a的值赋值后,所以:

wr = (wtemp = wr) * wpr - wi * wpi + wr;

相当于:

wtemp = wr;
wr = wtemp * wpr - wi * wpi + wr;

或:

wtemp = wr;
wr = wr * wpr - wi * wpi + wr;

参考:

6.5.16 赋值运算符

赋值表达式在赋值后具有左操作数的值 (...)。

【讨论】:

  • +1;尽管编写这样的代码很可爱,但要非常小心,因为未定义的行为永远不会太远;例如wr = wr++ 在 C 中未定义。
  • 好的,谢谢。当您将wtemp = wr; 赋值移动到上面的一行时,wtemp 和 wpr 显然是相同的,因此没有区别。谢谢:)
  • @Bathsheba:而且它的可读性不是很强。所以很明显,在生产代码中应该避免这种语句。
  • @Bathsheba:哪一部分可能是未定义的? wr = wr++ 会被翻译成 wr = wr += 1; 不是吗?
  • @Asmodiel:不,不会。 C 标准说这是未定义的行为,因为 wr 的值在没有序列点的情况下被修改和访问。 Google it. ;)
【解决方案2】:

@md5 有正确的答案,但我看到这个被滥用了很多次,我觉得有必要进一步评论。在几乎所有情况下,做这样的作业都是错误的。不是“不会编译”错误,而是“我不知道这是否是你真正想要做的”错误。它立即要求读者停下来认真思考你在做什么。如果有一种实用的方法可以避免在过程中进行分配,请使用它。创建一个临时变量,将评估分成多个阶段,等等。

现在,有时这确实很有帮助。例如,这里有一些代码调用了一个非常慢的函数(canFreelyStop),但前提是它确实必须这样做。同时它正在对系统状态进行一些评估:

        //determine whether transport motor should be running and make it happen
        bool canStop = true;
        if (    m_requestErrorStop
             || (    !m_receiving                       // not receiving new items from upstream.
                  && ((canStop = canFreelyStop()) != 0) // can stop without damaging anything (!=0 to avoid compiler warning)
                )
           )
        {
           //ready to turn it off
           ...
        }
        else if (!canStop)
        {
           //only failed to stop due to documents in transit.  Wait a "cycle" and check again
           ...
        }

重写此代码以消除内部分配并非易事(它也依赖于短路评估)。这是我写过的唯一条件之一,其中内部分配实际上比替代方案更好。如果有人想要更改/调试此代码,我希望他们必须停下来认真考虑一下。

【讨论】:

    猜你喜欢
    • 2017-01-26
    • 2015-06-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-01-24
    • 1970-01-01
    • 1970-01-01
    • 2014-06-17
    相关资源
    最近更新 更多