【问题标题】:Declaring pointers; asterisk on the left or right of the space between the type and name? [duplicate]声明指针;类型和名称之间空格的左侧或右侧的星号? [复制]
【发布时间】:2011-02-09 06:40:36
【问题描述】:

可能的重复:
What makes more sense - char* string or char *string? Pointer declarations in C++: placement of the asterisk

我在很多代码中都看到过这种混合版本。 (顺便说一句,这适用于 C 和 C++。)人们似乎以两种方式中的一种来声明指针,我不知道哪一种是正确的,甚至不知道它是否重要。

将星号放在类型名称旁边的第一种方式,如下所示:

someType* somePtr;

第二种方法是将星号放在变量名旁边,如下所示:

someType *somePtr;

这已经让我发疯了一段时间了。有没有声明指针的标准方法?指针的声明方式是否重要?我以前使用过这两种声明,而且我知道编译器并不关心它是哪种方式。然而,我看到指针以两种不同的方式声明的事实让我相信这背后是有原因的。我很好奇这两种方法是否在我所缺少的某种方式上更具可读性或逻辑性。

【问题讨论】:

标签: c++ c pointers


【解决方案1】:

这是一个偏好问题,有点像圣战,就像括号样式一样。

风格

someType* somePtr;

是强调指针变量的类型。它本质上是说“somePtr 的类型是指向someType 的指针”。

风格

someType *somePtr

强调指向数据的类型。它本质上是说“somePtr指向的数据类型是someType”。

它们的含义相同,但这取决于给定程序员在创建指针时的心理模型是“专注”的,可以说是指向数据还是指针变量。

把它放在中间(如someType * somePtr)试图避免承诺任何一个。

【讨论】:

  • 我在*周围放了一个空格,但不是为了避免提交。我的重点肯定是类型,但我将其视为类型的修饰符。类似于我们不说intconst,而是说int const。当您使用const 时,“周围的空间”版本似乎也更好读。 int const * const p; vs int const* const q;(或者可能是人们更喜欢int const*const r;的最小空间?)
  • 我可以理解使用你的理由将空间放在两边,但我还是会避免它。让整个事情在我看来太像乘法了。
  • 除了变量声明之外,同样的争论也适用于 typedefs,即指针在逻辑上属于类型还是被定义的东西...... (a) typedef Cat *CatPointer; (b) typedef Cat* CatPointer; 当写一个虽然通过“使用”来键入另一个顺序,但星号在 typedef 中属于哪个单词变得更加清楚,因为第一个有效,第二个是不可编译的废话。 (a)using CatPointer = Cat*; (b)using *CatPointer = Cat;
  • 我更喜欢someType*,并且在声明参数时总是使用它。 然而在声明字段时有一个很好的逻辑论据反对这种风格。因为对于不习惯 C++ 的人来说,声明 someType* value1, value2; 几乎肯定会被解释为 value1value2 都是指针。 (只有value1 是一个指针。)简而言之,星号不是类型说明符本身的修饰符,而是必须应用于 each 变量,因此它属于该变量。不幸的是,我仍然觉得someType* 更容易阅读。 :(
  • the type of data pointed to by somePtr is someType -> 那么你会如何阅读someType * const somePtr?注意const* 的修饰符,而不是变量。您不能说“常量变量 somePtr 指向的数据类型是 someType”。你的模棱两可。 “somePtr 的类型是指向 someType 的常量指针”是唯一一致的。说“变量 somePtr 不断指向的数据类型是 someType”也有点过时了。它不再是关于被声明为常量的参数。
【解决方案2】:

没关系。现在有人会出现并以骗子的身份结束问题,如果您在同一声明中声明多个变量,其他人将展示int* a 方式如何中断,而int *a 更好地反映了代码的句法结构,另一个将表明 Stroustrup 更喜欢 int* a 方式并将类型放在左侧。

许多意见,但这里没有“正确”的方式。

【讨论】:

  • 我不确定,但是否存在与语言语法如何创建星号解析相关的实际实用原因?如果我想到函数指针声明 (rt (*f) ()) 和多变量声明 (t *a, *b),我倾向于相信星号在其 right 处限定标识符,类似于 @ 987654326@ 实际上限定了其左侧的标识符(语句中的第一个除外)。
  • @v.odd 这个论点是我总结为“int *一种更好地反映句法结构的方式”:) 但是编写好的代码的目的不是以某种方式模仿在标准。首先,代码应该可以工作并且可以维护。
  • 同意。但是当它变得有点做作时,它有助于了解规则以记住如何写东西。中间还有一个星号学校type * var 的人声称这是有道理的,因为 const 也没有被写在标识符上。 type const*const v;type const* const v;type const *const v; 他们选择:type const * const v; 到处都是空格,这样没有优惠。
  • @v.oddou 星号不是const 之类的限定符。限定符属于类型说明符(这不是语法问题,而是语法问题,顺便说一句。),而 * 是声明符的一部分。也写int *p; 类似后面的用法。或者有人写* p?最后同样重要的是:有编码标准强制执行int *p 变体,但我还没有看到需要其他之一的编码标准。而关于int* p, q; 给出错误视觉印象的论点在imo 中相当强烈。所以,如果写int *p, q;,为什么写int* p;?保持一致!
  • 我确信int *aint* a 好,但后来我有int* restrict a 的功能,但int restrict *a 不起作用。
【解决方案3】:

没关系,个人喜好。

有些人喜欢把字体放在一起:

int* p;

其他人说它应该放在变量旁边,原因如下:

int *p, x;//declare 1 int pointer and 1 int
int *p, *x;//declare 2 int pointers.

随着时间的推移,你会忽略这一点并接受这两种变化。

【讨论】:

  • 是的,正是这种情况帮助我选择了int *p 而不是int* p。对我来说,这意味着星号与标识符有关系。
【解决方案4】:

之所以出现差异,是因为 C++ 在 C 之上添加了更强大的类型系统。C 程序员通常从“值”的角度思考,所以

int  *pValue;

读取“pValue 的取消引用是一个 int” 而 C++ 程序员在“类型”中思考,所以

int* pValue;

读取“pValue 类型是指向 int 的指针” 当然,编译器根本看不出有什么区别。但是你会发现,在 C++ 编程中,坚持“值语义”的是 C 程序员。

【讨论】:

  • 仅针对“值语义”的这种狭隘、非常规的定义。对于通用定义,即尽可能/实用地返回和传递值是首选,那么这绝对是 C++ 的事情。 C++ 逐渐添加了许多特性来促进按值语义,而 C 除了 as-if 规则之外没有任何特性,这往往会鼓励人们通过指针传递。
【解决方案5】:

我认为将星号放在变量名称旁边更清楚。

您可能错误地声明someType* one, two; 认为它们都是指针,但只有变量one 是指针; two 只是一个 someType。声明为someType *one, *two 可以避免这个问题。

【讨论】:

  • 好的,但是当你第一次输入 two->doSomething() 时,你会立即看到你在任何现代 IDE 中犯的错误,所以这真的没什么大不了的。
  • @mrt 您的论点仅在类型是具有成员的类型时才成立;如果类型是int 或float 之类的标量,则没有要调用的成员。
  • @ShammelLee 是的,你说得对!我发表此评论时没有考虑过简单类型。
【解决方案6】:

我见过的每一种方式都是

TheType *myPointer

因为您声明的是 TheType 类型的 POINTER。类似声明

TheType myVar

将声明一个 TheType 类型的实例变量。

您也可以清楚地做到这一点并使其易于阅读

TheType myVar, *myPointer;

【讨论】:

  • 我也见过这种情况;但是,我从不喜欢经常重复的理由。在我看来,指针是一个 type ,因此它与 type 的其余部分一起使用,就像 const 修饰符一样。括号中的类型“(const char *)var”比“(const char *)var”稍微好一点。此外,大多数解释在一个或另一个领域都分崩离析。声明倾向于将星号放在变量名旁边,但强制转换倾向于将星号放在类型名旁边(如果您是为了便于阅读而编写的。这是 C 语言编写的不一致之一。
猜你喜欢
  • 2020-01-28
  • 2020-10-20
  • 1970-01-01
  • 2020-02-12
  • 2022-11-19
  • 2011-02-01
  • 2016-06-08
相关资源
最近更新 更多