C通过值或带有指针的引用传递

时间:2019-09-16 16:25:58

标签: c function pointers reference

哪个函数调用按值传递,哪些按引用传递?

int *a;

int b;

int **c;

f(a);

g(&b);

h(*c);

只是简单的示例,我只是对指针以及如何告诉它们如何传递感到困惑。

4 个答案:

答案 0 :(得分:1)

一个古怪的答案是,所有这些值都是通过值传递的,但有时值是一个地址。

更有用的是,假设此处没有错误,所有这些函数都是传递地址,与C传递引用的距离几乎一样。它们采用指针作为参数,并且可以取消引用该指针以将数据写入其指向的任何位置。这些行仅对g()的调用是安全的,因为其他指针未定义。

这是C API中用于输入/输出参数的标准,不需要重新分配。

需要返回一个新的可变大小缓冲区的函数通常会带一个指向指针的指针,因此它们可以取消引用参数以在调用程序中获取地址,然后将指针写入指向其分配的缓冲区的地址,或者是该函数的静态变量。

如注释中所述,可以仅从函数返回指针。没有它,内存分配将无法在C中工作。但是,看到具有size_t **参数或类似参数以返回指针的函数仍然很常见。多数情况下,这可能是Unix模式,其中几乎每个函数都返回成功/错误代码,因此实际函数输出会转移到参数上。

答案 1 :(得分:1)

形式上,C没有通过引用传递。它只有按值传递。

您可以通过两种方式通过引用模拟

  • 您可以将函数参数声明为指针,并显式使用&将指针传递给调用方中的对象。
  • 您可以将函数参数声明为指针,并传递一个数组,因为当您尝试传递数组时,实际发生的情况是该数组的值“衰减”到了指向其第一个元素的指针中。 (而且您还可以将函数参数声明为数组,以使其看起来更像是传递了数组,但实际上无论如何您都在声明一个指针。)

因此,更多的问题是您认为通过引用传递的参数。

您经常会听到它说“数组是在C中通过引用传递的”,这不是错误的,但是可以说它也不是严格正确的,因为(如上所述)实际发生的是按值传递指向数组第一个元素的指针。

答案 2 :(得分:0)

最简单的判断方法是算术的大小,但是对于char类型却不是。对于地址算术,将调用sizeof operator,而对于普通算术,则不会像unsigned int类型那样调用。

#include <iostream>
using namespace std;

int main() {
    unsigned int ui, *uiPtr;

    ui = 11;
    cout << ui << endl;
    ui += 1; //increases value by 1
    cout << ui << endl;
    uiPtr = &ui;
    cout << uiPtr << endl;
    uiPtr += 1; //increases value by sizeof
    cout << uiPtr << endl;

    return 0;
}

答案 3 :(得分:-1)

为使您的问题更清楚,让我们初始化变量

int b;

int *a = &b;

int **c = &a;

然后拨打电话

f(a);

通过指针b通过引用传递对象a。指针本身通过值传递,该函数处理指针a的值的副本。

此电话

g(&b);
实际上,

等同于相对于接受值的先前调用。变量b通过引用传递。

此呼叫也等同于上一个呼叫

h(*c);

变量b通过指针*c的值等于指针a的值通过引用传递。

因此,所有三个函数均通过引用接受变量b