为什么它认为'T * name'是C方式而'T * name'是C ++方式?

时间:2011-06-23 06:12:08

标签: c++ c pointers history conventions

注意:这个问题是关于星号(*)的位置。

在我看到的大多数C代码中(例如,在Beej's guide to network programming中),所有变量声明/定义都使用T *name格式,即将*绑定到变量名称。指针被认为属于变量,而不是类型。

在我看到的大多数C ++代码中,格式为T* name,即它将*绑定到变量的类型。指针被认为属于类型,而不是变量。我自己,作为纯C ++编码器,也使用这种格式,因为指向类型的指针明显(对我来说)属于类型,而不是变量。 (很明显,即使是C ++标准也在示例中使用了这种格式。:))

是否有(历史性)原因?当程序员开始做C ++时,思维方式是否有所改变?

如果一个C编码器(使用前一种格式)可以解释他/她使用它的原因,而不是后者,也会很好。

10 个答案:

答案 0 :(得分:23)

如果我冒险猜测,我会说这是因为C ++人员更有可能认为类型信息本身就是一种东西,因为模板可以在编译时以编程方式操作类型。他们也不太可能在同一声明中声明几个变量。

T*样式将类型信息集中在一个地方并使其脱颖而出,如果您从未声明,使用此语法的T* foo, bar;之类的内容引起的混淆不是问题同一陈述中的两个变量。

就个人而言,我发现T*风格非常令人讨厌并且非常不喜欢它。 *是类型信息的一部分,这是真的,但编译器解析它的方式使它实际上附加到名称而不是类型。我认为T*方式掩盖了正在发生的重要事情。

在我的观察中,似乎我在C ++社区中很少见。我注意到你对最流行的风格也有同样的看法。

当然,要清楚,任何一种风格都适用于任何一种语言。但我确实注意到你做了同样的事情,一种风格在C代码中往往更常见,另一种在C ++中更常见。

答案 1 :(得分:16)

来自Stroustrup's C++ Style and Technique FAQ

  

“典型的C程序员”写int *p;并解释它“*p是什么是int”强调语法,并且可能指向C(和C ++)声明语法争论风格的正确性。实际上,*绑定到语法中的p名称。

     

“典型的C ++程序员”编写int* p;并解释它“p是指向int”强调类型的指针。实际上p的类型是int*。我显然更喜欢这种强调,并认为它对于使用C ++的更高级部分非常重要。

答案 2 :(得分:14)

就个人而言,我不同意这一点 - 我不认为有这样做的C或C ++方式。我从未见过任何证据表明这一点。但是,我确实假设为什么带有星号的语法更靠近C中声明的变量名。

在C中(至少在C89中,绝大多数C在使用中),您必须在块的顶部声明所有变量。这导致程序员在做

T a, b, c;

相对而言,在C ++中这种情况很少见。 (在C ++中,您声明变量接近于它们的使用位置,变量通常具有构造函数参数等;因此很少在一行上声明多个对象)

这也恰好是语法重要的唯一情况,因为声明

T* a, b, c;

声明一个指针,而不是程序员可能期望的三个指针。

由于在一行中放置多个声明在C中更常见,并且也是唯一一个星号位置很重要的情况,程序员更有可能将星号与变量相关联。

那就是说,我从未见过任何证据 - 这只是猜想。

答案 3 :(得分:12)

有几个人提到非常好的观点。我只想指出,虽然C非常强烈地保留了“声明反映使用”的含义,但C ++却没有。 C ++中的几个声明符不反映声明中的用法;

int &ref; // but "&ref" has type "int*", not "int".
int &&ref; // but "&&ref" is not valid at all.

我认为编写不同的C ++程序员实际上并不认为这是他们的理由,但这可能会阻止C ++书籍作者提及它,这可能会影响那些C ++程序员。

答案 4 :(得分:9)

C程序员倾向于使用一种风格而C ++程序员使用其他风格的原因很简单:Kernighan& Ritchie在their book中使用了“C风格”,而Stroustrup在his book中使用了“C ++风格”。

答案 5 :(得分:6)

在K& R中,他们使用type *name符号,因此可能是许多C程序员得到它的地方。

答案 6 :(得分:5)

因为Bjarne有后见之明的好处:他意识到C声明符语法是“失败的实验”(读:C声明符语法被延迟)。其他人已经得到了其他人的回答。

答案 7 :(得分:2)

我认为你的区别不正确,

T *样式中有C ++ code

T*样式中有C code

我认为这只是项目参与者个人偏好的问题。

答案 8 :(得分:2)

只是引起争议:

  • C ++用户通常声明每行一个声明可以将星号放在类型(左侧)上。 int* a; int* b;
  • C和C ++都使用附在名称​​上的星号进行解析(右侧)。 int *a;
  • C ++预处理程序通常会将星号向左移动。 C预处理器将其移动到右侧。
  • 在任何一种语言中,将它放在左边对于在同一语句中声明相同类型的多个变量看起来很奇怪。 int* a, * b, * c;
  • 左边有一些看起来很愚蠢的句法元素。 int* (* func)()

还有其他C元素被错误使用,例如const,它也属于右侧! int const a;。这通常放在类型的左侧,尽管属于左侧的类型。必须修改许多编译器来处理这种用法。在C ++中,您可以观察到这与常量方法一致,因为编译器无法推断它是否放在左侧:int A::a() const。对于constrestricted以及int const *等声明的朋友的嵌套使用,这也会中断。 const的常规用法表明这是一个指向整数的常量指针,但实际上是int *const

TL;博士

你一直都做错了,把一切都放在右边。

答案 9 :(得分:1)

C声明遵循与表达式相同的规则(例如优先级)。事实上,考虑像

这样的声明是完全有效的
int *foo;

将表达式*foo的类型(即应用于foo的间接运算符)声明为int而不是foo作为int*类型

然而 - 正如其他人已经指出的那样 - 在C ++中,将类型视为单独的,并且 - 由于模板 - 可修改的实体,因此使用像

这样的声明是有意义的。
int* foo;