为什么函数在C中不能有引用参数?

时间:2010-10-17 19:09:10

标签: c++ c function reference

例如:void foo( int& i );是不允许的。这有什么原因,还是不是规范的一部分?据我所知,引用通常是作为指针实现的。在C ++中,void foo( int* i )void foo( int& i )之间是否存在任何功能差异(不是句法/语义)?

6 个答案:

答案 0 :(得分:31)

因为引用是C ++特性。

答案 1 :(得分:8)

参考文献仅仅是用于指针的语法醋。它们的实现是相同的,但它们隐藏了被调用函数可能修改变量的事实。他们实际扮演重要角色的唯一一次是让其他C ++功能成为可能 - 想到操作符重载 - 根据你的观点,这些也可能是语法醋。

答案 2 :(得分:4)

  

例如:void foo(int& i);不被允许。这是否有原因,或者它只是规范的一部分?

这不是规范的一部分。语法“type&”引用是在C ++中引入的。

  

据我所知,引用通常作为指针实现。在C ++中,void foo(int * i)和void foo(int& i)之间是否存在任何功能差异(不是语法/语义)?

我不确定它是否符合语义差异,但引用可以更好地防止取消引用空值。

答案 3 :(得分:0)

因为&运算符在C中只有2个含义:

  1. 其操作数的地址(一元),

  2. 和,按位AND运算符(二进制)。

  3. int &i;不是C中的有效声明。

答案 4 :(得分:0)

对于函数参数,指针和引用之间的区别并不是那么大,但在很多情况下(例如成员变量),引用会大大限制你可以做的事情,因为它不能反弹。

答案 5 :(得分:0)

C中没有引用。但是,C确实具有通过引用传递的可变参数。例如:
    int foo(int in,int * out){return(* out)++ + in; }
    // ...     int x = 1; int y = 2;
    x = foo(x,& y);
    // x == y == 3.
但是,忘记在更复杂的foo()s中的每次使用中取消引用“out”是一个常见的错误。 C ++引用允许更平滑的语法来表示闭包的可变成员。在这两种语言中,这可能会通过使多个符号引用相同的存储来混淆编译器优化。 (考虑“foo(x,x)”。现在未定义“++”是仅在“* out”之后还是在“in”之后,因为在两次使用之间没有序列点,并且仅需要增量在取得左表达式的值之后的某个时间发生。)

此外,显式引用将两种情况消除歧义为C ++编译器。传递给C函数的指针可以是可变参数或指向数组的指针(或许多其他东西,但这两个充分说明了歧义)。对比“char * x”和“char * y”。 (...或者没有按预期这样做。)通过引用传递给C ++函数的变量明确地是闭包的可变成员。例如,我们有     //在班巴兹的范围中     private:int bar(int& x,int& y){return x - y};
    public:int foo(int& x,int& y){return x + bar(x,y);}

    //退出范围并漫步......     int a = 1; int b = 2;巴兹c;
    a = c.foo(a,b);
我们知道几件事:
bar()仅从foo()调用。这意味着可以编译bar(),以便在foo()的堆栈框架中找到它的两个参数,而不是它自己的。它被称为复制省略,这是一件好事。

当函数的格式为“T& foo(T&)”时,​​复制省略变得更令人兴奋,编译器知道临时进出,编译器可以推断结果可以是用来代替论证。然后不需要编译临时输入或结果输出的复制.foo()可以被编译以从一些封闭的堆栈帧获取其参数并将其结果直接写入一些封闭的堆栈帧。

最近关于复制省略的文章和(惊喜)如果你在现代编译器中传递它会更好(并且C ++ 0x中的rvalue引用如何帮助编译器跳过更加无意义副本),见http://cpp-next.com/archive/2009/08/want-speed-pass-by-value/