在C中通过引用传递

时间:2009-12-17 05:51:53

标签: c function pointers reference

我正在尝试在C中使用传递引用,以便该函数可以修改传递给它的参数的值。这是函数签名:

int locate(char *name, int &s, int &i)

然而,当我尝试编译它时,我得到这个错误,特指上述行:

  

错误:预期';',','或')'之前   '&安培;'令牌

如果我删除'&'该程序将编译,但显然无法正常运行。这有什么不对?如何通过参考工作拨打电话?

7 个答案:

答案 0 :(得分:37)

C没有参考。您需要将指针传递给您想要修改的变量:

int locate(char *name, int *s, int *i)
{
    /* ... */

    *s = 123;
    *i = 456;
}

int s = 0;
int i = 0;
locate("GMan", &s, &i);

/* s & i have been modified */

答案 1 :(得分:20)

C没有引用变量,但您可以将引用视为指向数据的const指针,

const指针指向数据,这样指针不能指向其他数据,但可以更改指向的数据。

int  locate (char *name,  int  * const s, int * const i)

答案 2 :(得分:7)

C不支持按推荐传递。你需要用C ++来编写它,或者修改成

int locate(char *name, int *s, int *i)

并将指针传递给第二个和第三个参数变量。

答案 3 :(得分:2)

给出的早期答案似乎缺少上下文,并且没有解决C指针过载的属性。声称C"通过引用传递是完全公平的。"指针也是引用。然而,更正式地说,C"参考"是表示符号的内存地址的机制。

  • 指针只是内存中的一个变量,其值被视为一个 地址。
  • 引用只是内存地址的值 - 文字。
  • C语言允许通过引用传递 - 但仅限于正确的上下文!

上下文的分离是签名定义和签名调用。

考虑原语int a = 0x22e8;以及我们声明int* b = &a;的其他地方(我会在一分钟内完成功能)。

我们可以在内存中想象这一点(假设字节顺序对于这个例子并不重要):

...
0x00000200:        22e8        ; this is the variable for int a's literal value:
                               ; a == 0x000022e8
                               ; &a == 0x00000200
0x00000???:        9090        ; ... more code ...
0x00000400:        0200        ; this is pointer b pointing to a's address:
                               ; b == 0x00000200
                               ; *b == 0x000022e8
                               ; &b == 0x00000400
...

很容易看出我们可以在没有任何特殊技巧的情况下为任何地址指定指针。指针只是一个变量,但C允许我们引用它指向的地址;我们可以"取消引用"来自其value-address的指针在调用上下文期间将指针视为其指针的基础值:while ( *b == a ) ...。我们可以轻松调用b == &a

将此应用于函数调用时,必须将函数(签名)定义与调用的上下文分开,以区分传递引用。

int* foo(int* blah, int nah) { .. }     // signature definition context:
                                        // These are parameters
... vs ...

b = foo( &a, 4);                        // invocation context:
                                        // These are arguments

在定义函数签名时,我们并没有告诉编译器从哪个地址访问参数 - 运行时甚至还不知道!定义void bar(int &blah) {...}只是胡说八道。相反,我们使用解除引用的指针语法 - "传入的任何参数都将被加载到指向"的地址。 - 在运行时发生时引用所需的参数值。因此C可以通过引用传递参数。

函数签名定义和函数调用的上下文改变了编译器查看指针重载与引用的方式,以及运行时如何实际解决它们。

答案 4 :(得分:1)

你不能在c中这样做。 c没有引用,你可以改用指针。

答案 5 :(得分:1)

如果希望使用pass by reference方法修改函数调用中使用的参数,请始终使用指针作为函数的形式参数。

因此,而不是使用此

int locate(char *name, int &s, int &i)

使用,

int locate(char *name, int *s, int *i)

当您调用此功能时,您可以使用

.........

int a=5;
int d=10;
char c='A'; 
int result;

result=locate(&c, &a, &d);

我希望现在一切都会清楚,

关于通过值传递或通过引用传递以及哪一个更好的更多想法,此源对初学者有用

http://www.learnc.net/call-by-reference.php

玩得开心。

答案 6 :(得分:1)

(我一直在使用C一段时间,但我对C中的一些概念还很陌生。我想尽我所知回答这个问题,如果我错了,请随时纠正我)

当你说通过引用传递时你会传递地址,并且这样做你会使用指向地址的指针。所以你需要将指针传递给你的函数原型,但你正在做的是直接传递地址。

你的函数尝试的是取消引用(使用&)你的指针,但是你从来没有指向参数的指针'和'我'去引用它。

为函数原型/定义做正确的方法是

int locate(char *name, int *s, int *i)

当您必须调用此函数时,您可以在main或调用函数中使用以下声明

int locate(char *name, &s, &i)