为什么人们认为'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?
注意:这个问题是关于星号(*
(的位置。
在我看到的大多数 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
。这也分解了嵌套使用const
、restricted
和朋友,如int const *
这样的声明。const
的常规用法表明这是一个指向整数的常量指针,但这实际上是int *const
。
博士
你们一直都做错了,把一切都放在正确的地方。
C 声明遵循与表达式相同的规则(例如优先级(。事实上,考虑这样的声明是完全有效的
int *foo;
将表达式的类型声明为*foo
(即应用于foo
的间接运算符(为int
而不是foo
为int*
类型。
但是 - 正如其他人已经指出的那样 - C++通常将类型视为一个单独的,并且 - 由于模板 - 可修改的实体,因此使用像这样的声明是有意义的
int* foo;
- 如何在c++中为模板函数实例创建快捷方式
- 在c代码之间共享数据的最佳方式
- 在C++中将函数压缩为两种方式
- 以螺旋方式打印矩阵的程序.(工作不好)
- 为字符串中每 N 个字符插入空格的函数没有按照我认为的方式工作?
- 创建引用向量的优雅方式
- Constexpr替代了新的放置方式,可以让内存中的对象保持未初始化状态
- 使用模板进行堆栈实现; "name followed by :: must be a class or namespace"
- 使用QQuickFramebufferObject时同步数据的最佳方式是什么
- 不同/较旧的处理器运行c++代码的方式是否不同
- 从嵌套在std::映射中的std::列表中删除元素的最佳方式
- 如果条件为TRUE(最佳方式?),则在do while循环中后置增量
- 重载方法的方式会在使用临时调用时生成编译器错误
- 在reactor中存储eventHandlers的最佳方式是什么
- 如何以优化的方式同时迭代两个间距不相等的数组
- 以线程安全的方式调用"QQuickPaintedItem::updateImage(const QImage&image)"(no QThread)
- 为什么C++有不同的变量初始化方式?
- 在AVX通道中混洗的最佳方式
- C++中"dependent name"的定义是什么?
- 为什么人们认为'T *name'是C方式,而'T* name'是C++方式?