我对C ++比较陌生(大约一年的经验,开关)。我很好奇导致type * name
作为定义指针的语法的决定。在我看来,语法应该是type & name
,因为&
符号在代码中的其他地方用于引用变量的内存地址。因此,要使用int
指针的传统示例:
int a = 1;
int * b = &a;
会变成
int a = 1;
int & b = &a
我确信这有一些原因,我只是没有看到,我很想听到C ++老手的一些意见。
谢谢, -S
答案 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.