C/C++中指针类型声明: `*`的位置

引入

咱们用两个简单(?)的问题做为引入,固然咱们整篇文章都会围绕这两个问题:html

  1. 下面四种类型声明等价吗?linux

    • int* i;
    • int *i;
    • int * i;
    • int*i;
  2. 下面四种类型声明中,j拥有哪个数据类型?是int或者int的指针?数据库

    • int* i, j;
    • int *i, j;
    • int * i, j;
    • int*i, j;

固然看到这里,若是你已经有很是自信的答案,你固然能够无视这一篇文章后面的部分。express

第一个问题

第一个问题的答案是: 四种指针的类型声明的等价的。编程

很好,既然咱们知道它们等价,或许已经足够了。可是咱们数据库教授老是在课上提醒你们,知道区别并不足够,还须要问本身其中的哪个更好,什么状况下用哪种方式。less

哪种写法更好呢?

C++之父在他的一篇文章:Bjarne Stroustrup's C++ Style and Technique FAQ中提到:ide

  • The choice between int* p; and int *p; is not about right and wrong, but about style and emphasis. C emphasized expressions; declarations were often considered little more than a necessary evil. C++, on the other hand, has a heavy emphasis on types.
  • A typical C programmer writes int *p; and explains it *p is what is the int emphasizing syntax, and may point to the C (and C++) declaration grammar to argue for the correctness of the style. Indeed, the * binds to the name p in the grammar.
  • A typical C++ programmer writes int* p; and explains it p is a pointer to an int emphasizing type. Indeed the type of p is int*. I clearly prefer that emphasis and see it as important for using the more advanced parts of C++ well.

Linux kernel coding style中的习惯规则是:this

When declaring pointer data or a function that returns a pointer type, the
preferred use of * is adjacent to the data name or function name and not
adjacent to the type name. Examples:
char *linux_banner;
unsigned long long memparse(char *ptr, char **retptr);
char *match_strdup(substring_t *s);

某种程度上它也拟合了C++之父Bjarne Stroustrup的想法。spa

第二个问题

第二个问题的答案是: j的类型是int指针

固然这问题是编译器的行为,或者语言自身的规定,很难去阐述行为或规定背后的为何。

咱们继续看Bjarne Stroustrup's C++ Style and Technique FAQ,这部分紧接问题一中对应的引用:

The critical confusion comes (only) when people try to declare several pointers with a single declaration:
`int* p, p1;    // probable error: p1 is not an int*`

Placing the * closer to the name does not make this kind of error significantly less likely.

`int *p, p1;    // probable error?`

Declaring one name per declaration minimizes the problem - in particular when we initialize the variables. People are far less likely to write:

`int* p = &i;`
`int p1 = p;    // error: int initialized by int*`

And if they do, the compiler will complain.

从他的这一部分文字中,很容易能够看出咱们这文章中的第一个问题第二个问题彻底是紧密结合。第二个问题中的四种写法的确是等价的,可是无一能让人轻松理解。从他的这一个观点中:Declaring one name per declaration minimizes the problem,咱们能够对这篇文章下一个主观的结论。

结论

针对第二个问题,对我来讲最好的方式是:

int* i;
int j;

这种写法更清晰,也是多个Stackoverflow提问中所提倡的。

最后一点声明是,不管怎么写对编译器来讲其实都无所谓,它只是客观地去检查可否经过编译而后生成对应的代码。这些等价写法对应的汇编语言甚至同样,对应的程序的效能天然也是同样。这些写法迷惑的只是人类(编程的人和浏览代码的人),咱们须要有一个清晰的方式,保证本身不出错同时也让代码浏览者能快速理解。


引用和推荐阅读:

http://www.stroustrup.com/bs_...

https://www.kernel.org/doc/Do...

https://softwareengineering.s...

https://stackoverflow.com/que...

https://stackoverflow.com/que...

https://stackoverflow.com/que...

https://stackoverflow.com/que...

https://stackoverflow.com/que...

(Stackoverflow通通是在问同一件问题)

该文章遵循创做共用版权协议 CC BY-NC 4.0,要求署名、非商业 、保持一致。在知足创做共用版权协议 CC BY-NC 4.0 的基础上能够转载,但请以超连接形式注明出处。文章仅表明做者的知识和见解,若有不一样观点,能够回复并讨论。

相关文章
相关标签/搜索