【问题标题】:Correct way of declaring pointer variables in C/C++ [closed]在 C/C++ 中声明指针变量的正确方法 [关闭]
【发布时间】:2011-10-22 20:58:30
【问题描述】:

我注意到有些人使用以下符号来声明指针变量。

(a) char* p;

而不是

(b) char *p;

我使用 (b)。符号 (a) 背后的理性是什么? 符号 (b) 对我来说更有意义,因为字符指针本身不是类型。相反,类型是字符,变量可能是指向字符的指针。

char* c;

这看起来像有一个类型 char* 并且变量 c 是那个类型。但实际上类型是 char 并且 *c(c 指向的内存位置)属于该类型(char)。如果你一次声明多个变量,这种区别就很明显了。

char* c, *d;

这看起来很奇怪。 c 和 d 都是指向字符的相同类型的指针。在这个因为下一个看起来更自然。

char *c, *d;

【问题讨论】:

  • char 指针不是类型是什么意思?你是说指针不是类型?
  • 我相信这是一个偏好问题,除非您正在查看特定的样式指南(即您的公司可能有您必须遵循的特定编码标准)。我倾向于在选项 b 和中间的某个位置之间混淆。有时我觉得char *t 看起来不合适,所以我可能会改用char * t;。不过,我也经常看到char* t;
  • 另外,你的推理“类型是char并且*c(c指向的内存位置)是那个类型(char)”似乎表明存在一个 char 被声明,而实际上没有。如果它被这样对待,就像初学者有时那样,它肯定会导致内存访问冲突。
  • 两者仍然具有足够的描述性,(b) 表明 *p 是 char 类型,(a) 表明 p 是 pointer to a char
  • 拥有十多年的行业经验,今天是第一次出现这种情况,而且只是阅读其他行业专业人士的文章。显然,那么,我从来没有像使用制表符 v 空格、def 或 dec 的 cmets 或任何其他“没有什么更重要的争论”话题那样,就这些话题进行过宗教对话.这是我的观点,在我职业生涯的最后阶段,我更喜欢经常使用“char * p”。是的,空间之前,空间之后。主要是因为我发现它减少了错误,因为它使指针更加明显。

标签: c++ c pointers coding-style


【解决方案1】:

Bjarne Stroustrup 说:

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

“典型的 C 程序员”会写“int *p;”并解释它“*p is what is the int”强调语法,并可能指向C(和C++)声明语法来论证风格的正确性。事实上,* 绑定到语法中的名称 p。

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

来源:http://www.stroustrup.com/bs_faq2.html#whitespace

我推荐后一种风格,因为在你在一行中声明多个指针的情况下(你的第四个例子),你习惯用星号和变量。

【讨论】:

  • 其他人建议不要在同一个声明中声明多个对象。 :-)
  • 我强调语法背后的逻辑,因此我更喜欢:int *p,意思是:当p被取消引用时,我得到一个int。然后由, 分隔的多个声明是有意义的:int *p, *q, r(当pq 被取消引用时,我得到一个int,当r 被引用时,我得到一个int)。此外,函数指针语法很有意义:int (*f)()(当 f 被取消引用并被调用时,我得到一个 int)。这是有道理的:int *p, (*f)().
  • 这帮助我意识到论点的另一面是有效的。作为一名高级程序员,我主要强调类型;并且更喜欢int*。对我来说,int *p, (*f)() 没有多大意义,但我可以看出在某些情况下它对某些人的影响。
  • @Druesukker,我认为你的陈述比上述任何一个都更有意义。
  • @Druesukker 但是逻辑并不完全适用于void*(并且对于 C++ 引用根本不起作用)。
【解决方案2】:

我个人更喜欢将* 与其他类型放在一起

char* p;  // p is a pointer to a char.

人们会争辩说“但随后char* p, q; 会产生误导”,对此我会说,“所以不要那样做”。

【讨论】:

  • 对 char* p 的论证非常好;选择:)我不介意他们中的任何一个,只要它不会像您展示的示例那样难以阅读,在这种情况下他们不应该这样做。
  • 什么时候输出值呢?你做cout << *p;。那么为什么不在声明时将星号放在 p 之前:*p?在我看来,它会不那么令人困惑。
  • @user1170330,因为在某个地方它是类型定义的一部分,而在另一个地方它是一个取消引用运算符。没有关系。如果有的话,它们看起来不同是件好事,因为不同的东西看起来应该不同。
【解决方案3】:

如何写没有区别。但是如果你想在一行中声明两个或多个指针,最好使用 (b) 变体,因为很清楚你想要什么。往下看:

int *a;
int* b;      // All is OK. `a` is pointer to int ant `b` is pointer to int
char *c, *d; // We declare two pointers to char. And we clearly see it.
char* e, f;  // We declare pointer `e` and variable `f` of char type.
             // Maybe here it is mistake, maybe not. 
// Better way of course is use typedef:
typedef char* PCHAR;
PCHAR g, h;  // Now `g` and `h` both are pointers.
// If we used define construction for PCHAR we'd get into problem too.

【讨论】:

  • typedef“当然”不是更好的方法。有些人可能更喜欢它,但如果有多个人在使用您的代码,就会出现问题。如果我不习惯PCHAR,我可能会写PCHAR *p; 之类的东西,这将是char**,而不是我想要的。一般来说,如果你想要一个char**,你必须写PCHAR*或者定义一个新类型,然后它就开始变得愚蠢了。
  • 如果需要一些复杂的指针类型,例如指向函数的指针,那么制作 typedef 是一个很好的主意。在这种情况下,它们使代码更简单。另一方面,使用 PCHAR 是比日常实践更多的综合示例。但它显然可以满足您的需求。 然后它就开始变得愚蠢了请将所有投诉都提交给 Stroustrup :-)
  • 如果您编写 PCHAR* p 来定义指向 char 的指针,那么很明显您不知道自己在做什么,也没有读取类型 def。答案在他看来。 typedef 还有另一个好处。在 C 中,它是使事情变得不透明的简单方法。公开将符号定义为 VOID ptr,私下类型 def 是别的东西.... C++11 通过 auto 解决了大部分问题
  • 对于那些在大学五年后才想重新开始玩 C++ 的人来说,这是最好的答案之一。
【解决方案4】:

妥协是

char * p;

K&R 使用

char *p;

这取决于您,除非您遵循编码标准——在这种情况下,您应该遵循其他人的做法。

【讨论】:

  • 我很难学到 char* x,y 并不意味着 y 是 char*。现在我明白为什么 K&R 遵循上述风格了。
  • 什么是 K&R,为什么使用单一代码源很重要?我使用char* p;。这是风格问题,而不是惯例或规则。对我来说,p 的类型为char* 更有意义,所以显然 * 应该与类型一起使用。
  • @FalcoGer 我为 K&R 添加了一个链接。单一代码源使用什么并不重要。如果你不遵循他们的标准,你的团队可能会生你的气,因为你让他们更加努力地理解你的代码。这些天来,我希望团队无论如何都使用clang-format
【解决方案5】:

这完全是一个偏好问题,就个人而言,在我看到 char* 的项目中,我倾向于在不同的行上声明多个指针。没有真正的“正确”方法可以做到这一点,这一切都归结为偏好。有人说 (a) 更容易阅读,而另一些人说 (b) 更容易在同一行声明更多相同类型的变量。

我发现 (b) 更常见,在某些情况下我已经看到

char * a;

或类似的东西。再次偏好。无论您喜欢什么,或者我正在从事的项目使用什么,我都会使用(除非我自己编写,在这种情况下我会使用 (a))

【讨论】:

    猜你喜欢
    • 2017-03-01
    • 2021-06-15
    • 2021-07-08
    • 2010-10-10
    • 2011-03-17
    • 1970-01-01
    • 2012-04-04
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多