为什么人们认为'T *name'是C方式,而'T* name'是C++方式?

Why is it thought of 'T *name' to be the C way and 'T* name' to be the C++ way?

本文关键字:name 方式 C++ 为什么      更新时间:2023-10-16

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

在我看到的大多数 C 代码中(例如,在 Beej 的网络编程指南中(,所有变量声明/定义都使用 T *name 格式,即将*绑定到变量名。指针被认为属于变量,而不是类型。

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

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

如果一个C程序员(使用前一种格式(可以解释为什么他/她使用它,而不是后者,那也很好。

如果我冒昧地猜测,我会说这是因为C++人们更有可能将类型信息本身视为一回事,因为模板使得在编译时以编程方式操作类型成为可能。它们也不太可能在同一声明中声明多个变量。

T*样式将类型信息集中在一个位置并使其突出显示,如果您从不在同一语句中声明两个变量,则使用此语法的类似T* foo, bar;会导致的混淆不是问题。

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

根据我的观察,我似乎在C++社区中很少见。我注意到你对什么风格最受欢迎的看法是一样的。

当然,需要明确的是,这两种风格都适用于任何一种语言。但我确实注意到你所做的同样的事情,一种风格在 C 代码中更常见,而另一种风格在 C++ 中更常见。

来自Stroustrup的C++风格和技术常见问题解答。

一个"典型的C程序员"写int *p;并解释它"*p是什么int"强调语法,并可能指向C(和C++(声明语法来论证样式的正确性。事实上,*与语法中的名称p绑定。

一个"典型的C++程序员"写int* p;并解释说"p是一个指向int的指针"强调类型。确实,p的类型是int* .我显然更喜欢这种强调,并认为这对于很好地使用C++的更高级部分很重要。

就个人而言,我不同意这一点——我认为没有 C 或 C++ 的方法可以做到这一点。我从未看到任何证据表明这一点。但是,我确实有一个假设,为什么星号的语法更接近 C 中声明的变量名。

在 C 中

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

T a, b, c;

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

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

T* a, b, c;

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

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

也就是说,我从未看到任何证据 - 这只是猜想。

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

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

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

C程序员倾向于使用一种风格而C++程序员使用另一种风格的原因很简单:Kernighan和Ritchie在他们的书中使用了"C风格",而Stroustrup在他的书中使用了"C++风格"。

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

因为Bjarne有事后诸葛亮的好处:他意识到C声明符语法是"一个失败的实验"(阅读:C声明符语法是迟钝的(。其余的已经被其他人回答了。

我认为你的区别不正确,

T *样式中有C++代码。

T*样式中有 C 代码。

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

只是为了对此事提出一些争议:

  • 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

博士

你们一直都做错了,把一切都放在正确的地方。

C 声明遵循与表达式相同的规则(例如优先级(。事实上,考虑这样的声明是完全有效的

int *foo;

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

但是 - 正如其他人已经指出的那样 - C++通常将类型视为一个单独的,并且 - 由于模板 - 可修改的实体,因此使用像这样的声明是有意义的

int* foo;