我从来没有像Python(隐式)或PHP(显式和放大)那样引用问题。在PHP中,您编写$p = &$myvar;
,并$p
作为指向$myVar
的参考。
所以我在C ++中知道你可以这样做:
void setToSomething( int& var )
{
var = 123;
}
int myInt;
setToSomething( myInt );
不&是指C ++中“x的内存地址”?如果var只是myInt
的地址而不是指针,我该怎么办?
void setToSomething( int* var )
{
*var = 123;
}
int myInt;
int* myIntPtr = &myInt;
setToSomething( myIntPtr );
我不明白*和&之间的区别在C ++中完全。他们告诉你&用于获取变量的地址,但为什么它可以帮助您处理函数等。就像在第一个示例中一样?
答案 0 :(得分:28)
不&是指C ++中“x的内存地址?”
简短回答:这取决于。
更长的答案: 一元前缀运算符&
,当应用于对象时,确实会生成 地址 对象:&obj
。但是,还有 类型修饰符&
,当应用于某个类型时,会将其修改为 引用输入 :int&
。
这同样适用于*
:当用作 一元前缀运算符 时,它将 取消引用 指针:*ptr
。当用作 类型修饰符 时,它会将类型修改为 指针 :int*
。
类型修饰符适用于声明的变量 也没有用。例如,这个
int *p, **pp, i, &r = i;
定义了一个int
指针,一个指向int
指针的指针,一个vanilla int
和一个int
引用。 (后者立即被初始化,因为你不能有一个未初始化的引用。)注意 类型修饰符在语法上属于它们正在修改它的类型的声明变量 ,而不是声明变量的类型。不过,类型修饰符(*
和&
)会修改变量的类型。
但是,在以下情况中,假定p
和i
是已经声明的变量
*pp = &i;
*
和&
是一元前缀运算符,取消引用pp
并产生i
的地址。
(同样, 类型修饰符[]
当应用于正在声明的变量时,会将变量的类型修改为数组,而 二进制中缀运算符[]
,当应用于数组类型的对象时,将访问其中一个子对象。)
除了类型修饰符和一元前缀运算符 &
和*
之外,还要进一步复杂化,还有 二进制中缀运算符 &
和*
,意思是“按位AND”和“乘法”。并且为了增加侮辱伤害,在C ++中你可以 overload 一元前缀和二进制中缀这些运算符的变体(以及二进制中缀 []
)用于用户定义的类型,并且对于它们的语义完全免费。
答案 1 :(得分:12)
在第一个示例中,&
用于声明引用类型。
它与用于获取对象地址的&
运算符不同。
您可以将引用类型视为在封面下使用永远不会是NULL
的指针的类型。
答案 2 :(得分:2)
实际上,& -operator有两个目的,如上所述。
第一个目的是解除引用,使用如下:
int i = 123; //declare an integer variable named i with the value of 123
int *pI = &i; //declare an pointer-to-integer
//variable name pI pointing to the memory address of i
& -operator的含义是'给我内存地址'
第二个目的是模拟按引用调用(c本身没有)
像
这样的声明void foo(int& theInt)
{
theInt = 123;
}
将使函数foo接受一个int参数,在执行foo期间将对其进行任何修改。
如果没有& -operator,对theInt的修改只会在foo的范围内进行,并在函数终止后被丢弃。
答案 3 :(得分:1)
&
用于函数,而不像返回单个变量的return
语句。
答案 4 :(得分:0)
在第二个例子中,它应该是
*var = 123
将参数声明中的&符号视为Pascal中的var
关键字,它用于指定变量如果更改将更新。我不确定C ++语义是否指定它总是通过引用传递,或者它可以通过值传递来完成,如果对于给定的情况更有效则可以在返回时复制...