【问题标题】:I ask for clarification about ''not pass by reference'' in C我要求澄清 C 中的“不通过引用传递”
【发布时间】:2019-03-08 02:22:55
【问题描述】:

在尝试编译void some_function(int * & some_pointer);并收到编译器错误:expected ';', ',' or ')' before '&' token.后,我意识到只有删除函数的引用才能编译 void some_function(int * some_pointer);

研究我找到了解决方案:“不能在 C 中通过引用传递”。它不会编译那个函数。

然而,它引起了人们的注意:scanf("%d", &my_var);我们一直通过引用传递...... 它是如何工作的? 我假设我们不能创建请求引用的函数,因为我们可以使用引用作为参数。程序将按值传递它,然后更改原始变量。这是正确的吗?

或者是函数要求一个指针,当我们使用&它创建一个指向该变量的指针?我很困惑。

【问题讨论】:

  • 传递变量的地址(按值)不是按引用传递。
  • @Shawn:传递对象的地址就是通过引用传递。 “通过引用传递”的意思就是,传递某种引用对象的方式,而不是直接传递对象的值。 C++ 和其他语言将此作为语言直接提供的功能,因此您可以将左值放在参数位置,编译器会通过引用自动传递它(编译器主要通过传递地址来实现)。但是,自己动手传递地址的方式仍然是通过引用传递。
  • @Eric 这完全取决于您与之通信的抽象级别。 C++“引用”是实现更广泛的“按引用传递”计算概念的方法的子集,如果您在该领域讨论,那么当您传递一个指针完全错误。但在其他时候它是完全正确的。最好避免在这个话题上做出笼统的陈述,因为你永远是错的,同时你也永远是对的,同时你也会让别人感到困惑;)
  • @Eric 否。如果它是通过引用传递的,您可以为传递的指针分配一个新地址,并将该更改反映在调用者中,就像您在 C++ 中为引用分配一个新值一样。 C只有传值;所有函数参数都被复制,调用者看不到对它们的更改。修改所指向的值不应与通过引用相混淆,尽管它可以通过额外的间接层来模拟这个概念。
  • @Shawn:指向的对象是通过引用传递的。可以通过为其分配一个新值来更改它(通过将* 应用于指针形成的左值)。指针按值传递。我可以告诉你,在 C++ 存在之前,我们指的是在通过地址传递事物时通过引用传递事物。 C++ 只是提供了一种速记的内置方式来执行此操作;它并没有改变这样一个事实,即它也可以通过手动方式完成,并且将引用(在常见的英语含义中)传递给某物是通过引用传递。

标签: c pointers reference


【解决方案1】:

虽然 C 中的函数不支持按引用传递,但它们可以通过接受指针值来模拟按引用传递,然后在调用函数时,可以将变量的地址传递给它。通过这样做,调用函数可以取消引用指针并更改调用函数中的变量。

例如:

void f(int *x)
{
    *x = 4;
}

int main()
{
    int x = 0;
    printf("x=%d\n", x);    // prints 0
    f(&x);
    printf("x=%d\n", x);    // prints 4
}

当我们调用像f(&x) 这样的函数时,& 运算符获取其操作数的地址并将该地址传递给f。它不是参考。

【讨论】:

    【解决方案2】:

    或者是函数要求一个指针,当我们使用 & 时,它会创建一个指向该变量的指针?

    完全正确。

    在 C++ 中,符号& 有多种含义:

    • 在表达式中作为一元运算符应用时,表示“取地址”,并产生一个指针;
    • 当属于int&(或者实际上是int*&)之类的类型时,它表示“引用”;
    • (并且,当用作两个算术表达式之间的二元运算符时,它的意思是“按位AND”。)

    选择使用& 作为引用类型,我认为这个想法是为了节省创建新符号并尝试在指针和引用之间创建一些对称性。我认为它不起作用;我觉得这真的很混乱。

    但是对你来说,在 C 中,它没有实际意义,因为(正如你所发现的那样!)C 没有引用。相反,您的函数可以编写为采用指向指针的指针 (int**)。具有讽刺意味的是,您可能需要在调用站点使用 & 来向此类函数提出您的论点!

    更复杂的是,您有时会听到广义上的“通过引用传递”一词。这在 C++ 领域是令人困惑的,因为“引用”在那里具有更具体的含义。事实上,C++ 语言中专门引入了引用,以使“按引用传递”更加优雅和直观。但回到 C 语言中,更一般地说,它只是一种表示“我们指的是事物而不是复制它”的方式;从技术上讲,在 C 中我们这样做的方式确实是传递一个指针

    【讨论】:

      【解决方案3】:

      严格来说,您不能在 C 中通过引用传递。相反,就像在您的 scanf() 示例中一样,您可以通过值将变量(又名指针)的地址传递给函数,并且您可以 假装你已经通过引用传递了变量,但你的 C 代码的字面解释不会同意这一点。

      另一方面,您可以使用 C++ 引用来真正通过引用传递变量。这种机制,不像前面提到的那样,不会求助于reification 的内存位置,即在这种情况下,C++(语言)对变量的地址一无所知(尽管 C++ 编译器知道)。

      所以,在 C 语言中,

      • 可以通过引用传递(在“解释”意义上)。
      • 你的 C 代码本身不能通过引用传递任何东西。

      另一方面,在 C++ 中使用引用时,

      • 可以通过引用传递。
      • 您的 C++ 代码也可以通过引用传递。

      【讨论】:

        猜你喜欢
        • 2011-11-12
        • 2021-01-29
        • 2015-12-22
        • 2023-03-09
        • 2018-10-02
        • 1970-01-01
        • 1970-01-01
        • 2011-01-17
        • 1970-01-01
        相关资源
        最近更新 更多