C ++中是否存在通用的大写约定?[关闭]


13

我在Python和Java上做了很多工作,并且这两种语言都有关于标识符中如何使用大写字母的相当通用(尽管不是通用的)约定:都PascalCase用于类名和ALL_CAPS“全局”常量,但用于其他标识符很多Java代码使用,mixedCase而很多Python代码使用underscore_delimiters。我知道没有语言或库会强制使用任何特定的大写字母,但是我发现当我坚持使用的语言的标准约定时,我的代码似乎更具可读性。

现在,我正在用C ++启动一个项目,并且我想应用相同的想法。我应该了解任何最常见的大写约定吗?


camelCase的问题在于,它不能与预处理器很好地配合使用。这不是一个大问题,特别是因为通常可以避免使用预处理器。
Pubby的

就在几天前,我不得不面对这个决定。最后,这毫无疑问,因为标准库和boost都使用underscore_lowercase_delimiters。由于我将boost用作STL增强器,因此我的代码将全部被散布。我使用的其他PascalCase(SFML)库可以更容易地包含在内,因此任何给定的方法都是非常标准的。
最多

@ Pubby8:出于好奇:camelCase如何与预处理程序发生冲突?
约阿希姆·绍尔

@JoachimSauer camelCase中的单个单词可能具有不同的大小写,但是宏不能更改大小写。如果您想要将单词的一部分作为参数的宏,这将成为一个问题-您可能必须同时提供两种情况作为参数:macro(x,X)。这是一个很小的问题,但是如果您打算使用预处理器,则应该知道这一点。
Pubby 2011年

Answers:


27

我应该了解任何最常见的大写约定吗?

C ++基于C,C语言已经足够老,可以在发明C ++时开发出许多命名约定。然后,C ++增加了一些,而C也没有闲着想新的东西。除此之外,还有许多C语言派生的语言,这些语言进一步发展了他们的发明人的C命名约定,以至于他们在C和C ++上受精……换句话说:C ++不是一个,而是许多这样的约定。

但是,如果您正在寻找一种命名约定,则最好查看标准库的命名约定,因为这是所有C ++开发人员都必须知道并习惯的一种命名约定

但是,您使用的最重要的规则是:保持一致!

有趣的是,虽然我最初使用PascalCase和camelCase进行混合,并参与了具有更多命名约定的众多项目,但多年来,我发现我越来越对standard_library_convention感到困惑。不要问我为什么。


感谢您提供的信息...所以标准库是下划线,然后呢?(至少比什么都重要吗?)我沿着这些思路思考,但是由于iostream之类的东西很难讲出来,其中一半的方法名称似乎和ANSI一样是拼凑在一起的单词片段C :-P
David Z

5
@David:iostreams库可能已有25年的历史了,并且(C语言库或课程除外)可能是C ++ std库中最古老的部分。希望,没有人会以如今的方式来设计它,并且希望即使是那些不在意之内的人也不会像在流库中那样使用标识符。(来吧,有一个名为功能egptrsputn以及uflow以及underflow,那只是搞笑!)无论如何,是的,标准库现在使用all_lowercase_with_underscores。
2011年

@sbi我发现iostream库不再是C ++的标准库。正如您提到的,它的标识符不能用作编程约定;-)
umlcat 2011年

2
@umlcat:iostreams库(以C ++ 03接受的模板化形式)绝对被认为是C ++标准库的一部分。
2011年

我也走了同样的路,我觉得我叫camelCase的原因稍微容易打字,我想在那里懒惰。后来我知道,与编写代码相比,我花了更多的时间阅读和重构代码,并且snake_case更易于阅读。因此,所有这些都是关于最小化能源消耗的。现在,我在为类使用小写字母名称。这是非常规的,但是我认为切换它并重用重要的实例和小写的类型实际上可以提高代码的可读性。我在想也许这是要走的路。大写重要的内容,例如人文语言。
PSkocik '16

19

首先让我们同意,ALL UPPERCASE是一件令人讨厌的事,应将其最小化。

因此,在C和C ++中,它被用作宏的约定,并且仅用作宏的约定,因为宏同样难看,更不用说邪恶了。

早期的C没有const,因此常量必须表示为宏。另外,在早期,程序要短得多,因此可以使用今天不理想的做法(例如IIRC Brian Kernighan用很多非大写的宏编写了代码)。而且,在那个年代,确实存在没有小写字母的键盘。我在挪威的Tandberg EC-10计算机上使用了这样的设备,大约在1980或1979年。

因此,Java从早期的C语言开始就采用常量的大写约定。与此同时,甚至在此之前(我不确定这里的时间顺序),C语言也获得了常量。但是,尽管某些/许多C程序员由于必须将常量作为大写宏而不得不停留在较早的约定中,但C ++程序员更为明智。

当今最大的问题是,首先让人们学习Java,或者首先学习C(使用中世纪的约定),然后再学习C ++,并采用那种粗俗的约定。

所以,

    int const answer = 42;    // Nice, good, OK.
    const int ANSWER = 0x2A;  // Ouch!
    #define COMPANYNAME_ANSWER 052  // Oh kill me, please.

好吧,您可能以为我开玩笑地提到了仅使用大写字母的键盘。不好了。因为那仅仅是驱动命名约定的最古老,最古老的技术限制,或者至少影响了它们看起来的错误/正确程度。接下来,出现了7位串行传输的问题,这导致所使用的字符代码(newspeak字符编码)出现相应的问题,这意味着您必须将自己限制为英语字母A到Z。

实际上,我建议仍然这样做。那就是我们的位置!我们还没有进一步。

目前,从2011年开始,标准C ++支持名称中的通用Unicode(并且自1998年以来就支持),而实际的C ++实现则不支持。特别是g ++编译器受到了国家字符的挑战。这源于黑暗时代的技术局限性。

所以,

    double blueberryJamViscosity  = 0.0;    // OK
    double blåbærsyltetøyViskositet = 0.0;  // Ouch!

最后,关于下划线与穿插的大写字母,

  • 为类型名称保留易于识别的形式。
  • 保留所有大写的宏。
  • 始终如一。

我认为实际上就是这样,除了“通常避免使用单字母名称((循环,模板参数,等等)之外”)和“避免使用l,容易与1混淆”和“避免大写O,容易混淆”之类的规则与0“。另外,当然,请避免使用保留名称,例如以下划线开头,后跟大写字母,包含两个连续的下划线或以下划线开头并位于全局名称空间中。

干杯和健康


Alf,ISTR Stroustrup const从C ++ 复制D&E C时提到,因此,这一定是很久以前发生的,而且比Java早了很久,可能是C89。
2011年

2
哦,衷心地表示+1“保持一致!” 阅读时,我想知道为什么我忘了在我的答案中提到这一最重要的规则,那是我从未忘记告诉我的学生的规则。我想如果您现在把它添加到我的回答中来,您会原谅我吗?
2011年

2

我通常倾向于遵守在该语言的现有代码库中看到最多的约定。对于C ++,我通常会看到camelCase。对于Ruby或PHP,我通常会看到stuff_like_this。

但实际上,最重要的是,您选择的样式约定并非完全疯狂(dOnT_dO_tHiS)并与之保持一致。使其样式在特定项目的整个代码中不会改变。如果您正在处理现有项目,则需要使用已经存在的样式。


1

好吧,即使在现在,Systems Hungarian确实很常见,但是我宁愿自己割喉也不推荐。Apps Hungarian更好,因为它的注释标记可以真正表示语义,尽管我觉得当一个简短的单词可以使用缩写时,它对缩写有点太热衷了​​。(要使用该维基百科页面上的示例,为什么rwrow仅多一个字符的情况下用于行?这不像全球元音短缺。)

但实际上,最重要的是遵循与您一起工作的人的惯例。真。大多数约定都可以很好地工作,特别是如果一致使用。不一致最严重(比我讨厌的匈牙利系统更为严重)。如果您是一个人,请使用所需的任何东西。


1

从我所看到的,它随项目而变化。

嵌入式下划线可能更传统/在Unix上的C中更常用。标准库也遵循该标准库,因此,除非有足够的现有代码使用另一种约定来绝对强制使用另一种约定,否则几乎应该将其视为默认库。

Windows(例如)使用驼峰式保护套来实现其大多数功能,因此,很多为Windows开发的人也都这样做。在确实更习惯其他语言的人中,这也很常见,他们试图将C ++视为其他事物的一种奇怪的变体。


1

我已经使用标准库和boost作为命名约定的参考。但是,该解决方案存在问题。

标准库使用命名约定,旨在减少与代码的冲突。解决方案的一部分是使用所有小写字母。因此,使用下划线而不是camelCase。

我发现camelCase可读。PascalCase通常用于类名,因为它表示专有名词的等效项。但是,对于那些更能代表动词的函子,我将打破该规则。

我尝试不使用宏。但是,当我这样做时,可以使宏看起来像函数。我还使用const值或枚举代替清单常量,进一步避免了所有大写形式。我通常在这些符号前面加上“ k”以表示它们是常数。

// instead of a manifest constant
#define HOURS 24

// use const
const int kHours = 24; 

// or enum
enum {
    kHours   = 24,
    kMinutes = 60
};

0

该参考文献描述的命名约定与我过去在至少三家公司工作过的成功使用过的命名约定非常相似。

与早先的答案相反,如果除了避免与标准库的名称冲突之外,我不会避免在自己的代码中遵循C ++标准库的命名约定。

先前有关相关主题的SO答案也可能很有趣:https//stackoverflow.com/questions/228783/what-are-the-rules-about-using-an-underscore-in-ac-identifier


嗯,您可以使用相同的命名约定,而不必使用相同的名称...,如果您确实想要相同的名称,则仍然受到名称空间(例如std::stringvs.)的保护gnawme::string
einpoklum 2015年
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.