为什么C++指针*与声明的变量相关联,而不是类型?

22

C++为什么被设计成这样,使得在同一行声明两个int *的正确方式是:

int *x, *y;

int* x,y;

我知道一些人认为你应该避免使用这两种形式并且每个变量都要在自己的行上声明,但我对为什么做出这个语言决定感兴趣。


9
因为这是在C语言中的惯例。 - user784668
2
也许他们认为这样更灵活,用户可以同时声明指针和普通变量。 - Vijay
6
阅读此链接 http://www.research.att.com/~bs/bs_faq2.html#whitespace 了解C++的原因,关于C的原因请参考:http://cm.bell-labs.com/cm/cs/who/dmr/chist.html - Adriano Repetti
1
我认为最奇怪的部分在于初始化。假设我们有 int* p = new int[5]; 然后 int* a = &p; 就没问题了:“将指针a赋值为p的地址”。但是 int *b = &p; 就很奇怪了:“将整数*b赋值为p的地址”。考虑到 *b 是一个整数,为什么要给地址呢?这就是为什么我认为指针的链式声明毫无意义的原因。 - Morwenn
3个回答

24
为了与C代码兼容,因为这就是C的工作方式。
Bjarne在他的风格和技术FAQ中提出了一个很好的观点
引用: 选择int* p;和int *p;不是关于对错,而是关于风格和强调。 C强调表达式;声明通常被认为只是必要的邪恶。另一方面,C ++非常强调类型。 典型的C程序员写int *p;并解释它* p是int强调语法,并可能指向C(和C ++)声明语法来证明样式的正确性。实际上,*在语法中将名称p绑定在一起。 典型的C ++程序员编写int * p;并解释它p是指向int的指针,强调类型。实际上,p的类型是int *。我明确地偏爱这种强调,并认为这对于使用C ++的更高级部分非常重要。
因此,在C ++中使其按照这种方式工作的动机是它在C中的工作方式。
它之所以在C语言中这样工作的原因是,正如上面所述,C强调表达式而不是类型。

4
啊,但那是完全不同的问题 :P - Luchian Grigore
简短的答案如下:“C强调表达式;声明常被认为只是必要之恶。” - Mike DeSimone
1
只有当你完全没有好奇心的时候,才不需要关注 @LuchianGrigore :) - Sideshow Bob
2
我通常使用 int * p,因为我觉得两种方式都不太好看 :) - nikolas
1
@nijansen,这是所有中最丑的,我读成“通过乘法计算intp的积”! - leftaroundabout
1
你需要注意,Bjarne的最后一段话是错误的。我从未见过C++程序员这样做,而且它与实际含义不一致。考虑OP的例子:int* p,q;并不意味着q是指向int的指针。 - user207421

8
简单的答案是:因为C语言就是这样做的。当然,这只是引出了另一个问题:为什么C要这样做呢?
早期的C语言哲学是声明必须与使用完全一致。所以当你写下:
int *p;

当你声明表达式*p的类型为int时(编译器相应地计算出p的实际类型)。

当然,在C引入typedef和后来的struct之后,这个说法已经不再成立了。随着const的引入(先是在C++中引入,然后再次加入C语言),任何类似于以下的东西都彻底消失了。

int *const p;

没有关联使用。但那时候,局势已经不可逆转了。

1

答案

这来自于“C语言”(“纯C”,“原生C”等)。

当一个指针变量已经声明时,它的使用方式如下:

...
*p = &x;
*q = SomePointerFunc();
....

我读到过,“C”语言的原始发明者希望程序员使用与指针变量相同的语法来声明指针变量,在变量标识符之前加上星号

...
int *p;
int *q;
...

同样适用于数组:
...
x[5]  = 'a';
y[77] = SomeItemFunc();
...

...
char x[5];
int  y[100];
...

我曾经遇到的一些老师坚持要这样声明变量和函数类型(星号靠近标识符):

...
int *p;
int *q;
...

不要使用这个(类型标识符旁边的星号):

...
int* p;
int* q;
...

额外内容

在Java和其他语言中,如C#,数组或指针的声明与类型紧挨着,变量或函数标识符单独出现,就像这个伪代码一样:

*int p;
*int q;
char[5] x;
int[100]  y;

我更喜欢这种技术。

干杯。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接