【问题标题】:subtleties of passing by reference in C在 C 中通过引用传递的微妙之处
【发布时间】:2011-12-07 16:50:57
【问题描述】:

我正在维护一些 C 代码,这些代码是由我最后一份工作的人编写的。关于通过引用传递的情况出现了。这是我正在使用的一个简短的、人为的示例:

static int b;

void SetToTen(int *a){
    b = 10;
    /* >>>>>>>  Need to set a equal to b on this line <<<<<<<< */
return;
}

int main{
    int a = 0;
    SetToTen(&a);
    /* Now a should be equal to 10*/
  . 
  .
  .
return 0;
}

在 SetToTen 函数中,我可以这样写:

*a = b;

a = &b;

我认为这两个在功能上是等效的(其中任何一个都等于 10。)但我的问题是:是否有任何与另一个相关的偷偷摸摸的微妙之处?具体来说,如果我使用 a = &b 是否意味着如果我将来更改 b,a 也会更改?如果我使用 *a = b 不是这样吗?

想法/沉思/评论将不胜感激。

【问题讨论】:

    标签: c pass-by-reference


    【解决方案1】:

    它们在功能上根本不等效。这段代码:

    *a = b;
    

    取消引用 a 并将其值设置为 b 的值。这段代码:

    a = &b;
    

    a 指针更改为指向 b。如果您使用第二段代码,则不会发生任何事情,因为您正在按值更改 a 指针,它实际上根本不会更改 a

    【讨论】:

      【解决方案2】:
      *a = b;
      

      这是正确的。

      a = &b;
      

      这只是将地址复制到值中。 C 语言按值传递所有 参数。 (C++有引用的概念)如果要修改传入函数的参数,需要传入地址或数组,修改地址或数组成员所引用的值。

      最好如下声明和定义函数:

      void setToTen(int *pa){
          *pa = 10;
      }
      

      您的这些更改:

      1. pa (pointer-to-a) 避免混淆使用 a 作为主函数中的值和 a 作为 SetToTen() 中的指针
      2. 如果目标是将传入地址的变量设置为 10,则没有真正的理由在任何地方使用 b。
      3. 样式/语法:大多数 C 编码约定使用以小写开头的符号作为变量/方法,使用以大写开头的符号作为类型。
      4. 样式/语法:不需要显式的return 语句,除非您尝试返回一个值(您的函数被声明为 void),或者如果您希望在函数结束之前提前返回。

      类比:有两间房子:史密斯先生在 Main St. 115 号,是蓝色的,琼斯先生在 205 Elm St.,这是绿色的。您有一张包含史密斯先生地址的纸条。

      *a = b;就像把纸条上地址的房子涂成和琼斯先生的房子一样的颜色。

      a = &amp;b;就像把纸条上的地址改成琼斯先生的地址;它实际上并没有造成任何后果。

      【讨论】:

      • +1 现在每个人都跟我重复一遍:“C 中没有‘通过引用传递’”。
      • 先生,我看到了您关于 StackOverflow 好坏的文章。我只想与您分享一个问题,询问您的意见,这个问题是否值得如此多的反对。 stackoverflow.com/questions/34826036/… 。我是新来的,但现在我不能问任何问题,因为这个问题被否决了,但我看不出任何理由。请你检查一下。我问你是因为我喜欢你的帖子,并认为你可以帮助我。
      • 说实话,这个问题写得不是很好,你在说“我是 C 的初学者”之后自己回答了,所以看起来你发帖只是为了获得声望点地点。我会回应 underscore_d 的评论:“在这个网站和更广泛的互联网上有很多关于别名、指针转换等的问题和答案。在这里重复所有这些是没有意义的。”就您而言,我认为您需要努力学习发布清晰简洁的问题或答案。如果您因为声誉问题而无法发布问题,请联系版主,看看他们是否可以解决问题。
      • 不,先生,我不是因为这个而回答的,我问的问题不同,当没有答案时,我尝试在其他地方搜索,当我找到答案时,我发布了它。答案得到+3。但是这个问题获得了很多反对票,然后我改变了问题和答案。我问问题的目的是为了不学别的东西,但是在这里,只要有一个新来的提问版主就开始跑向他,以记下这个问题。我将重新提出我的问题。我的回答对吗?
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2020-05-14
      • 1970-01-01
      • 2011-01-14
      • 1970-01-01
      • 2010-09-24
      • 2014-12-25
      • 1970-01-01
      相关资源
      最近更新 更多