在C / C ++中声明指针变量的正确方法


91

我注意到有人使用以下表示法声明指针变量。

(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;

谢谢。


7
您是什么意思char指针不是类型?您是在说指针不是类型吗?
本杰明·林德利

1
我相信除非您正在查看特定的样式指南(即您的公司可能必须遵循一定的编码标准),否则这是一个偏爱。我倾向于将其混合在选择b和中间的某些位置之间。有时候我觉得自己char *t看起来不合适,所以我可以改做char * t;。但是,我也经常看到char* t;
RageD

1
同样,您的推理“类型为char并且* c(由c指向的内存位置)属于该类型(char)”似乎表明已声明了一个char,而实际上没有声明。如果像初学者那样对待它,那么肯定会导致内存访问冲突。
本杰明·林德利

1
两者仍然具有足够的描述性,(b)显示* p为类型,char并且(a)显示p为类型pointer to a char
A Person

1
拥有十多年的行业经验,今天是第一次出现这种情况,并且只能阅读其他行业专家的文章。显然,那么,我从来没有像在制表符v空格,def或dec注释或其他任何“最好没有争论的话题”这样的话题上进行宗教对话了。 。从我的角度来看,在职业生涯的后期,我更倾向于使用“ char * p”。是的,前面有空格,后面有空格。我发现它主要是减少错误,因为它使指针的外观更加明显。
Kit10

Answers:


102

Bjarne Stroustrup说:

在“ int * p;”之间进行选择 和“ int * p;” 不是关于是非,而是关于风格和强调。C强调表达;声明常常被认为仅仅是必要的邪恶。另一方面,C ++非常注重类型。

一个“典型的C程序员”会写“ int * p;”。并以强调语法的方式解释“ * p是什么是int”,并且可能指向C(和C ++)声明语法来证明样式的正确性。实际上,*绑定到语法中的名称p。

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

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

我建议使用后一种样式,因为在您在一行中声明多个指针的情况下(您的第4个示例),您习惯使用带有变量的星号。


34
其他建议不要在同一声明中声明多个对象。:-)
Bo Persson

5
我强调语法背后的逻辑,因此我更喜欢:int *p,意思是:当p取消引用时,我得到一个int。然后多次声明相隔,是有道理的:int *p, *q, r(当pq取消引用我得到一个int,当r被引用我得到的int)。同样,函数指针语法也很有意义:(int (*f)()f取消引用并称为时,会得到int)。这是有道理的:int *p, (*f)()
2014年

2
这帮助我认识到论点的另一面是正确的。我主要是类型高的程序员,我强调类型。并且喜欢int*。对我而言,int *p, (*f)()这没有多大意义,但我可以看一下在某些情况下对某些人的感觉。
2015年

1
@Druesukker,我认为您的陈述比以上任何说法都更有意义。
Muntashir Akon

1
@Druesukker但是该逻辑并不完全适用void*(并且对于C ++引用也完全无效)。
jamesdlin

57

我个人更喜欢将其*与其余类型一起放置

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

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


char * p的论点很好;选择:)我不介意其中的任何一个,只要不难理解为您展示的示例,在这种情况下,他们就不应该这样做。
耶稣拉莫斯

1
以及何时要输出值?你做cout << *p;。那么,为什么不在声明时将星星放在前面 呢?我认为这不会太令人困惑。p*p
user1170330 2013年

13
@ user1170330,因为在一个地方它是类型定义的一部分,而在另一个地方它是解引用运算符。没关系 如果有的话,它们看起来有所不同是一件好事,因为不同的事物应该看起来有所不同。
ikegami

32

怎么写没有区别。但是,如果您想在一行中声明两个或多个指针,最好使用(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.

5
typedef当然不是更好的方法。有些人可能会喜欢它,但是如果有多个人在使用您的代码,这将是一个问题。如果我不习惯PCHAR,我可能会写类似的内容PCHAR *p;,这将是a char**而不是我想要的。通常,如果您需要a char**,则必须编写PCHAR*或定义一个新类型,然后它开始变得愚蠢。
BlackJack

3
如果需要某种复杂的指针类型(例如指向函数的指针),则最好创建typedef。在这种情况下,它们使代码更简单。另一方面,使用PCHAR比日常实践更具综合性。但这显然可以满足您的需求。然后它开始变得愚蠢,请将所有投诉
举报

如果您编写了PCHAR * p来定义一个指向char的指针,那么很明显,您将不知道自己在做什么并且没有读def类型。答案在他看来。typedef还有另一个好处。在C语言中,这是使事情变得不透明的简单方法。公开地将符号定义为VOID ptr,私下将类型def定义为其他内容……。我宁愿偶尔调整一次typedef,然后在我们更改其中一种类型的内容时对代码中的所有内容进行调整……但是C ++ 11通过汽车解决了其中的大部分问题
UpAndAdam

对于刚上大学五年后才尝试使用C ++重新玩弄玩具的人来说,这是最好的答案之一。
Panzercrisis

10

妥协是

char * p;

K&R用途

char *p;

除非您遵循编码标准,否则取决于您,在这种情况下,您应该遵循其他所有人的工作。


4
我很难理解char * x,y并不意味着y是char *。现在,我明白了为什么K&R遵循上述样式。
Rahul Kadukar

什么是K&R?为什么单一代码源使用什么有关系?我用char* p;。这是样式问题,而不是惯例或规则。对我来说,p是类型更有意义char*,因此显然*应该与类型匹配。
FalcoGer

@FalcoGer我为K&R添加了链接。单一代码源使用什么都没有关系。如果您不遵循他们的标准,您的团队可能会惹恼您,因为您正在使他们更加努力地理解您的代码。这些天,我希望clang-format无论如何团队都在使用。
jnnnnn

2

所有这些都是优先选择的问题,就我个人而言,在项目上我看到的char *我倾向于在单独的行上声明多个指针。没有真正的“正确”方法可以做到这一点,而这全都取决于首选项。有人说(a)更容易阅读,而有人说(b)更容易在同一行上声明更多相同类型的变量。

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

char * a;

或类似的东西。再次偏好。无论您满意还是我正在使用的项目都将使用(除非我自己写(在这种情况下我会使用(a)))

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.