![](/img/trans.png)
[英]Why can't I give constant reference of a pointer as function argument
[英]Why can't a function have a reference argument in C?
例如: void foo( int& i );
不被允许。 这有什么原因,还是不是规范的一部分? 据我所知,引用通常是作为指针实现的。 在C ++中, void foo( int* i )
和void foo( int& i )
之间是否存在任何功能差异(不是语法/语义void foo( int& i )
?
因为引用是C ++功能。
参考文献仅仅是用于指针的语法醋。 它们的实现是相同的,但它们隐藏了被调用函数可能修改变量的事实。 他们实际上扮演一个重要角色的唯一一次是让其他C ++功能成为可能 - 想到操作符重载 - 根据你的观点,这些也可能是语法醋。
例如:void foo(int&i); 不被允许。 这有什么原因,还是不是规范的一部分?
它不是规范的一部分。 C ++中引入了引用的语法“type&”。
据我所知,引用通常是作为指针实现的。 在C ++中,void foo(int * i)和void foo(int&i)之间是否存在任何功能差异(不是语法/语义)?
我不确定它是否有资格作为语义差异,但引用提供了更好的防止取消引用空值的保护。
因为&
运算符在C中只有2个含义:
其操作数的地址(一元),
和,按位AND运算符(二进制)。
int &i;
不是C中的有效声明。
对于函数参数,指针和引用之间的差异并不是那么大,但在许多情况下(例如成员变量),引用会大大限制您可以执行的操作,因为它无法反弹。
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中的右值引用如何帮助编译器跳过更多无意义的副本),它的工作效果更好,请参阅http:// cpp- next.com/archive/2009/08/want-speed-pass-by-value/ 。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.