C++ 风格: Stroustrup 对指针星号的放置

not*_*orb 31 c++ pointers coding-style conventions

有谁知道为什么Stroustrup的风格是指针的放置如下?具体来说,Stroustrup 就此事提供了哪些指导?

int* p;
Run Code Online (Sandbox Code Playgroud)

对比

int *p;
Run Code Online (Sandbox Code Playgroud)

因为声明多个变量需要在每个变量名称旁边加上星号。这将导致:

int* p, *x;
Run Code Online (Sandbox Code Playgroud)

对比

int *p, *x;
Run Code Online (Sandbox Code Playgroud)

在 K&R C 书中,他们解释说星号/指针用作助记符以帮助理解。我觉得奇怪的是,指针/星号与类型相关联,而不是每个示例的第二个显示的变量。有兴趣了解为什么选择第一种样式的背景。

希望能从 Stroustrup 那里得到一些引述来解释这一点。

我正在添加 K&R C 第二版语法第 235 页,其中星号(指针)与声明符相关联,声明符是一个标识符。

K&R p235 第二版

答案Stroustrup 的这篇关于编码风格的文章中。他解释说两者都是有效的,这取决于程序员的偏好。

我不同意这是一个基于意见的问题。Stroustrup 的文章在没有意见的情况下清楚地回答了这个问题。

H.S*_*.S. 30

Bjarne 建议,C++ 非常重视类型和指针声明,以避免任何形式的混淆Stick to one pointer per declaration

来自Bjarne Stroustrup 的 C++ Style and Technique FAQ [强调已添加]

int* p;对的还是int *p;对的?

两者都是“正确”的,因为它们都是有效的 C 和 C++,并且具有完全相同的含义。就语言定义和编译器而言,我们也可以说int*p;int * p;

int* p;和之间的选择int *p;不是对与错,而是风格和重点。C 强调表达式;声明通常被认为只不过是一种必要的罪恶。另一方面,C++ 非常重视类型。

Atypical C programmer编写int *p;并解释它*p is what is the int强调语法,并可能指向 C(和 C++)声明语法来争论样式的正确性。实际上,*绑定到p语法中的名称。

Atypical C++ programmerint* p;和解释它p is a pointer to an int强调类型。事实上,类型pint*。我显然更喜欢这种强调,并且认为这对于很好地使用 C++ 的更高级部分很重要。

当人们试图用一个声明来声明多个指针时,就会出现严重的混淆(仅):

int* p, p1; // probable error: p1 is not an int*

放置*更接近名称不会显着降低这种错误的可能性。

int *p, p1; // probable error?

为每个声明声明一个名称可以最大程度地减少问题 - 特别是在我们初始化变量时。人们不太可能写:

int* p = &i; int p1 = p; // error: int initialized by int*

如果他们这样做,编译器会抱怨。
每当某事可以通过两种方式完成时,就会有人感到困惑。每当某些事情是品味问题时,讨论就会永远拖延下去。坚持每个声明一个指针并始终初始化变量,混淆的根源就消失了。

有关 C 声明语法的详细讨论,请参阅 C++ 的设计和演化。

  • 有趣的是,Stroustrup 并没有提到这种“风格”对于数组和函数来说是失败的。对于接受“char”并返回“int”的函数,不能编写“int [3] p;”来声明包含 3 个“int”或“int (char) p”的数组。本来可以引入一种新的声明语法,首先放置类型的完整描述,然后放置要声明的标识符列表。相反,我们有这种混杂的东西,由于它与语法的对比而显得丑陋。 (5认同)
  • 在`*p`和`p[3]`中,`*p`和`p[3]`都是与语法中的类型分开的*声明符*。在编写“int* p”时,Stroustrop 滥用了语法中空格的灵活性,将语法中未分组的两个标记分组。事实上,这种滥用在数组和函数中是不可能的,这表明它是一种丑陋的拼凑。 (5认同)

eer*_*ika 22

我不能代表 Bjarne,但是将星号(以及在引用的情况下与符号)绑定到类型是有道理的,因为指针在语义上是变量类型的一部分。变量的名称是p,它的类型是int*。名称不是*p,类型不是int

在单个声明中避免多个变量声明几乎总是可能的,因此这不是问题。

在我看来,这种方法更清晰,尤其是在返回类型的情况下:

T*
function(Args...);

T
*function(Args...);
Run Code Online (Sandbox Code Playgroud)

  • @EricPostpischil我指的是语义,而不是语法。如果你使用“decltype(p)”,你将不会得到“int”。我会补充说明。 (8认同)
  • 如果你看一下语法,就会发现它不是类型的一部分。声明分为多个部分,类型和声明符位于不同的部分中。类型为“int”,声明符为“*p”。该语法将“*”绑定到“p”,然后再将“*p”绑定到“int”。正如 K&R 所解释的,“int *p”给出了如何使用“*p”的图片:它是一个“int”。所以“*”是表达式“*p”图片的一部分。 (3认同)
  • @eerorika我建议将有关“decltype”的部分添加到您的答案中。表明这就是“语言”的看法意义重大。 (2认同)
  • @TheFloatingBrain:这与强类型与弱类型无关。语法清晰无歧义。 (2认同)

小智 10

我相信 stroustrup 的风格意味着应该避免像这样的变量声明。这似乎也是社区的普遍共识。