为什么在定义指针时我们使用“type * var”而不是“type& var”?

时间:2009-06-30 01:54:14

标签: c++ syntax

我对C ++比较陌生(大约一年的经验,开关)。我很好奇导致type * name作为定义指针的语法的决定。在我看来,语法应该是type & name,因为&符号在代码中的其他地方用于引用变量的内存地址。因此,要使用int指针的传统示例:

int a = 1;
int * b = &a;

会变成

int a = 1;
int & b = &a

我确信这有一些原因,我只是没有看到,我很想听到C ++老手的一些意见。

谢谢, -S

6 个答案:

答案 0 :(得分:7)

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是一个指向int的指针数组大小为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 ;)

答案 1 :(得分:4)

我认为Dennis Ritchie在 The Development of the C Language 中回答了这个问题:

  

对于这样一个组成的每个对象   类型,已经有办法了   提到底层对象:索引   数组,调用函数,使用   指针上的间接运算符。   类比推理导致了一个   名称镜像的声明语法   其表达式语法   名称通常出现。因此,

int i, *pi, **ppi;
     

声明一个整数,指向一个   整数,指向指针的指针   整数。这些的语法   声明反映了观察   我,* pi和** ppi都会产生一个   在表达式中使用时的int类型。   类似地,

int f(), *f(), (*f)();
     

声明一个函数返回一个   整数,返回一个函数   指向整数的指针,指向a的指针   函数返回一个整数;

int *api[10], (*pai)[10];
     

声明一个指针数组   整数和指向数组的指针   整数。在所有这些情况下   变量的声明类似于   它在表达式中的用法   是一个以头部命名的人   声明。

因此我们使用type * var来声明指针,因为这允许声明镜像指针的使用(解除引用)。

在本文中,Ritchie还在“NB”中重述了“B”编程语​​言的扩展版本,他使用int pointer[]来声明指向int的指针,而不是{ {1}}声明一个int array[10] s。

数组

答案 2 :(得分:3)

如果您是视觉思考者,可能有助于将星号想象为导致数据值的黑洞。因此,它是一个指针。

&符号是洞的另一端,将其视为解开的星号,或者当飞行员越过从黑洞出来的过渡时,飞船在不稳定的路线中摇摆不定。

我记得我很困惑C ++重载&符号的含义,给我们参考。他们绝望地试图避免使用任何更多的角色,这是由国际观众使用C和键盘限制的已知问题所证明的,他们增加了一个混乱的主要来源。

在C ++中可能有用的一件事是将引用视为预先准备好的解引用指针。传入参数时,不是使用& someVariable,而是在定义someVariable时已经使用了尾随符号。那么,这可能会让你更进一步混淆!

我的一个宠物的讨厌,我感到不满苹果Objective-C的样品中看到颁布,是布局风格int *someIntPointer,而不是int* someIntPointer

恕我直言,用变量保留星号是一种老式的C方法,强调了你如何在数据类型上定义变量的机制。

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

虽然人们争辩说,有意识地在同一行上声明混合指针和值的能力是一个强大的功能,但我已经看到它会导致微妙的错误和混乱。

答案 3 :(得分:1)

你的第二个例子不是有效的C代码,只有C ++代码。区别在于一个是指针,而另一个是参考。

在右侧'&'总是意味着地址。在定义中,它表示变量是参考。

在右侧,'*'始终表示地址价值。在定义中,它表示变量是一个指针。

引用和指针类似,但不一样。这个article解决了这些差异。

答案 4 :(得分:1)

不是将int* b读作“b是指向int的指针”,而是将其读作int *b:“* b是一个int”。然后,你有&作为反*:* b是一个int。 *b的地址为&*b,或仅为b。

答案 5 :(得分:-2)

我认为答案很可能是“因为这就是K& R的做法。”

贬低傻瓜。解释为什么我错了。

K& R是那些决定用于声明指针的C语法的人。

这不是int& X;而不是int * x;因为这就是语言由制造它的人定义的方式 - K& R.