一元前缀运算符&
应用于对象时,会产生对象的地址:&obj
。类型修饰符
在应用于即将声明的变量时,会将变量的类型修改为引用类型:。&
int&
这同样适用于*
:当作为一元前缀运算符应用于指针时,它将取消引用指针,产生引用的对象:*ptr
。
当用作即将声明的变量的类型修饰符*
时,会将类型修改为指针: int*
。
以类似的方式,应用于正在声明的变量的类型修饰符[]
会将变量的类型修改为数组,而应用于数组类型对象的二进制中缀运算符将访问数组的子对象之一。[]
类型修饰符应用于声明的变量而不是声明它们的类型是没有帮助的。例如,这个
int *p, **pp, i, a[10], &r = i;
定义了一个int
指针、一个指向an 的指针int
、一个 vanilla int
、一个 10 的数组int
和一个int
引用。(后者会立即初始化,因为您不能有未初始化的引用。)请注意,类型修饰符在语法上属于它们正在修改的类型的声明变量,而不是声明变量的类型。然而,类型修饰符 (*
和&
) 修改变量的类型。
然而,在以下情况下,with p
, i
, anda
假定为已声明的变量
*pp = &i;
a[0] = i;
*
和&
是一元前缀运算符,解引用pp
并产生 的地址i
,同时[]
产生int
数组中的第一个对象a
。
事实上,C 和 C++ 不关心类型修饰符周围的空格,这导致了在放置它们时出现了不同的阵营,这并没有真正让事情变得更容易。
有些人将类型修饰符放在靠近类型的位置。他们争辩说它修改了类型,所以它应该去那里:
int* ptr;
缺点是在声明多个对象时会变得混乱。这
int* a, b;
定义a
为指向 的指针int
,但定义b
为int
. 这就是为什么有些人喜欢写作
int *ptr;
int *a, *b;
我建议永远不要在同一个语句中声明多个对象。IMO 使代码更易于阅读。此外,它让您可以自由选择任一约定。
更复杂的是,除了类型修饰符和一元前缀运算符 &
and之外*
,还有二元中缀运算符 &
and *
,意思是“按位与”和“乘法”。雪上加霜的是,在 C++ 中,您可以为用户定义的类型重载这些运算符(以及二进制中缀)的一元前缀和二进制中缀变体,并且完全自由地使用它们的语义。 []