[英]Why do we use “type * var” instead of “type & var” when defining a pointer?
我对 C++ 比较陌生(大约一年的经验,断断续续)。 我很好奇是什么导致决定将type * name
作为定义指针的语法。 在我看来,语法应该是type & name
因为&
符号在代码中的其他任何地方都用于引用变量的内存地址。 因此,要使用int
指针的传统示例:
int a = 1;
int * b = &a;
会成为
int a = 1;
int & b = &a
我确信这有一些我没有看到的原因,我很想听听 C++ 老手的一些意见。
谢谢,-S
C++ 采用 C 语法。 正如“ The Development of the C Language ”(Dennis Ritchie 着)中所揭示的,C 使用*
作为类型声明中的指针,因为它决定类型语法应该遵循使用。
对于[复合类型]的每个对象,已经有一种提及底层对象的方法:索引数组,调用函数,在指针上使用间接运算符[
*
]。 类比推理导致名称的声明语法与名称通常出现的表达式语法的声明语法相同。 因此,int i, *pi, **ppi;
声明一个整数,一个指向整数的指针,一个指向整数指针的指针。 这些声明的语法反映了当在表达式中使用时 i、*pi 和 **ppi 都产生 int 类型的观察结果。
这是一个更复杂的例子:
int *(*foo)[4][];
这个声明意味着一个表达式*(*foo)[4][0]
具有类型int
,并且从那个(并且[]
具有比一元*
更高的优先级)你可以解码类型: foo 是一个指向大小数组的指针4 个指向整数的指针数组。
这种语法在 C++ 中被采用是为了与 C 兼容。另外,不要忘记 C++ 在声明中使用了 &。
int & b = a;
上面这行表示引用另一个int
类型变量的引用变量。 引用和指针的大致区别在于,引用只是初始化,不能改变指向的位置,最后总是自动解引用。
int x = 5, y = 10;
int& r = x;
int sum = r + y; // you do not need to say '*r' automatically dereferenced.
r = y; // WRONG, 'r' can only have one thing pointing at during its life, only at its infancy ;)
我认为 Dennis Ritchie 在The Development of the C Language 中回答了这个问题:
对于这种组合类型的每个对象,已经有一种方法可以提及底层对象:索引数组、调用函数、在指针上使用间接运算符。 类比推理导致名称的声明语法与名称通常出现的表达式语法的声明语法相同。 因此,
int i, *pi, **ppi;
声明一个整数,一个指向整数的指针,一个指向整数指针的指针。 这些声明的语法反映了当在表达式中使用时 i、*pi 和 **ppi 都产生 int 类型的观察结果。 相似地,
int f(), *f(), (*f)();
声明一个返回整数的函数,一个返回整数指针的函数,一个返回整数的函数指针;
int *api[10], (*pai)[10];
声明一个指向整数的指针数组,以及一个指向整数数组的指针。 在所有这些情况下,变量的声明类似于它在表达式中的用法,该表达式的类型是在声明开头命名的类型。
所以我们使用type * var
来声明一个指针,因为这允许声明反映指针的使用(取消引用)。
在本文中,Ritchie 还讲述了在“NB”(“B”编程语言的扩展版本)中,他使用int pointer[]
声明指向int
的指针,而不是使用int array[10]
声明数组的int
s。
如果您是一名视觉思想家,将星号想象成导致数据值的黑洞可能会有所帮助。 因此,它是一个指针。
&符号是黑洞的另一端,可以把它想象成一个解开的星号或一艘宇宙飞船,当飞行员克服从黑洞出来的过渡时,它在不稳定的航线中摇摆不定。
我记得被 C++ 重载 & 号的含义所迷惑,给我们提供参考。 他们不顾一切地试图避免使用更多字符,国际观众使用 C 和已知的键盘限制问题证明了这一点,他们增加了一个主要的混乱来源。
在 C++ 中可能有帮助的一件事是将引用视为预先准备好的解引用指针。 在传递参数时没有使用 &someVariable,而是在定义 someVariable 时使用了尾随与符号。 再说一次,这可能只会让你更加困惑!
我的一个最厌恶的,我就不高兴了苹果的Objective-C的样品中看到的颁布,是布局风格int *someIntPointer
而不是int* someIntPointer
恕我直言,在变量中保留星号是一种老式的 C 方法,它强调如何定义变量的机制,而不是它的数据类型。
someIntPointer
的数据类型someIntPointer
是一个指向整数的指针,声明应该反映这一点。 这确实导致要求您每行声明一个变量,以避免出现细微的错误,例如:
int* a, b; // b is a straight int, was that our intention?
int *a, *b; // old-style C declaring two pointers
int* a;
int* b; // b is another pointer to an int
虽然人们认为在同一行上有意地声明混合指针和值的能力是一个强大的功能,但我已经看到它会导致微妙的错误和混乱。
你的第二个例子不是有效的 C 代码,只有 C++ 代码。 区别在于一个是指针,而另一个是引用。
右侧的“&”始终表示地址。 在定义中,它表明该变量是一个引用。
在右侧,“*”始终表示地址处的值。 在定义中,它表明该变量是一个指针。
引用和指针相似,但又不一样。 本文解决了这些差异。
与其将int* b
读作“b 是一个指向 int 的指针”,不如将其读作int *b
:“*b 是一个 int”。 然后,您将&
作为反*
:*b 是一个 int。 *b
的地址是&*b
,或者只是 b。
我认为答案很可能是“因为 K&R 就是这样做的。”
K&R 决定了声明指针的 C 语法是什么。
这不是 int & x; 而不是 int * x; 因为这就是语言的组成者定义语言的方式——K&R。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.