【问题标题】:pass by reference with increment operator使用增量运算符通过引用传递
【发布时间】:2018-12-18 14:26:38
【问题描述】:

大家好,我在学习 C++ 编码时有一个非常基本的问题。

我正在阅读有关按引用传递和按值传递之间的区别。我写了一个简单的代码来测试它,但它做了一些我没想到的事情。

    #include <iostream>
    using namespace std;

    void MyIncr (float *x);
    int main() {
        float score = 10.0;
        cout << "Orignal Value = " << score << endl;
        MyIncr(&score);
        cout << "New Value = " << score << endl;
     }

     void MyIncr (float *x) {
        *++x;
     }

我怎么两个 couts 都得到 10?但是,如果我将函数更改为:

     void MyIncr (float *x) {
        *x += 1;
     }

我得到 10 的旧值和 11 的新值,这也是我在前一种情况下所期望的。

【问题讨论】:

标签: c++ pass-by-reference pre-increment


【解决方案1】:

添加到 R sahu 的答案。这是由于运算符的优先级及其关联性而发生的。

void MyIncr (float *x) {
    *++x;
 }

预增量(++)和取消引用或间接(*)运算符具有相同的优先级,并且是从右到左关联的。因此,无论哪个运算符在右侧,它将首先执行。因此,在您的情况下,指向x 将首先递增,然后取消引用。因此要获得 11,请执行以下操作:

void MyIncr (float *x) {
    ++*x;//even without the parenthesis this will work
 }

再次通过引用传递是最好的方法。像这样调用函数MyIncr(x),函数应该是这样的

void MyIncr (float& x) {
    ++x;
 }

【讨论】:

    【解决方案2】:

    问题就在这里:

    *++x;
    

    如果您查看C++ Operator Precedence,您将看到前缀++ 运算符与取消引用* 运算符具有相同的优先级,因此从右到左进行评估。这意味着上面的代码行首先递增指针(因为++ 是最右边的运算符),然后尝试取消引用它。如果您希望保留++ 运算符,您可以切换运算符的顺序。

    ++*x;
    

    在我看来,使用括号会更易读。

    ++(*x);
    

    【讨论】:

      【解决方案3】:
       void MyIncr (float *x) {
          *++x;
       }
      

      在这种情况下是未定义的行为。您首先增加指针,然后取消引用它。当指针递增时,它不再指向有效的float 对象。因此,取消引用它是未定义的行为。

      在调用端,指针或指针指向的对象的值没有任何变化。要增加指针指向的对象的值,请使用++(*x)

       void MyIncr (float *x) {
          ++(*x);
       }
      

      通过引用传递对象会更好。会减少混乱。

       void MyIncr (float& x) {
          ++x;
       }
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2012-07-29
        • 2021-10-04
        • 1970-01-01
        • 2023-04-01
        • 1970-01-01
        • 2016-12-11
        相关资源
        最近更新 更多