简体   繁体   English

C 中最常见的命名约定是什么?

[英]What are the most common naming conventions in C?

What are the naming conventions commonly use in C? C中常用的命名约定是什么? I know there are at least two:我知道至少有两个:

  1. GNU / linux / K&R with lower_case_functions GNU / linux / K&R with lower_case_functions
  2. ? name?姓名? with UpperCaseFoo functions使用 UpperCaseFoo 函数

I am talking about C only here.我在这里只谈论C。 Most of our projects are small embedded systems in which we use C.我们的大多数项目都是使用 C 语言的小型嵌入式系统。

Here is the one I am planning on using for my next project:这是我计划在下一个项目中使用的:


C Naming Convention C命名约定

Struct              TitleCase
Struct Members      lower_case or lowerCase

Enum                ETitleCase
Enum Members        ALL_CAPS or lowerCase

Public functions    pfx_TitleCase (pfx = two or three letter module prefix)
Private functions   TitleCase
Trivial variables   i,x,n,f etc...
Local variables     lower_case or lowerCase
Global variables    g_lowerCase or g_lower_case (searchable by g_ prefix)

The most important thing here is consistency.这里最重要的是一致性。 That said, I follow the GTK+ coding convention, which can be summarized as follows:也就是说,我遵循 GTK+ 编码约定,可以总结如下:

  1. All macros and constants in caps: MAX_BUFFER_SIZE , TRACKING_ID_PREFIX .大写中的所有宏和常量: MAX_BUFFER_SIZETRACKING_ID_PREFIX
  2. Struct names and typedef's in camelcase: GtkWidget , TrackingOrder .驼峰格式的结构名称和 typedef: GtkWidgetTrackingOrder
  3. Functions that operate on structs: classic C style: gtk_widget_show() , tracking_order_process() .对结构进行操作的函数:经典 C 风格: gtk_widget_show()tracking_order_process()
  4. Pointers: nothing fancy here: GtkWidget *foo , TrackingOrder *bar .指针:这里没什么特别的: GtkWidget *foo , TrackingOrder *bar
  5. Global variables: just don't use global variables.全局变量:只是不要使用全局变量。 They are evil.他们是邪恶的。
  6. Functions that are there, but shouldn't be called directly, or have obscure uses, or whatever: one or more underscores at the beginning: _refrobnicate_data_tables() , _destroy_cache() .存在的函数,但不应直接调用,或用途不明确,或其他:开头的一个或多个下划线: _refrobnicate_data_tables()_destroy_cache()

"Struct pointers" aren't entities that need a naming convention clause to cover them. “结构指针”不是需要命名约定子句来覆盖它们的实体。 They're just struct WhatEver * .它们只是struct WhatEver * DON'T hide the fact that there is a pointer involved with a clever and "obvious" typedef.不要隐瞒这样一个事实,即有一个指针与一个聪明且“明显”的 typedef 有关。 It serves no purpose, is longer to type, and destroys the balance between declaration and access.它没有任何作用,键入时间更长,并破坏了声明和访问之间的平衡。

You know, I like to keep it simple, but clear... So here's what I use, in C:你知道,我喜欢保持简单,但很清楚......所以这是我在 C 中使用的:

  • Trivial Variables : i,n,c ,etc... (Only one letter. If one letter isn't clear, then make it a Local Variable)琐碎变量i,n,c等...(只有一个字母。如果一个字母不清楚,则将其设为局部变量)
  • Local Variables : camelCase局部变量camelCase
  • Global Variables : g_camelCase全局变量g_camelCase
  • Const Variables : ALL_CAPS常量变量ALL_CAPS
  • Pointer Variables : add a p_ to the prefix.指针变量:在前缀中添加p_ For global variables it would be gp_var , for local variables p_var , for const variables p_VAR .对于全局变量,它将是gp_var ,对于局部变量p_var ,对于常量变量p_VAR If far pointers are used then use an fp_ instead of p_ .如果使用远指针,则使用fp_而不是p_
  • Structs : ModulePascalCase (Module = full module name, or a 2-3 letter abbreviation, but still in PascalCase .)结构ModulePascalCase (模块 = 完整的模块名称,或 2-3 个字母的缩写,但仍为PascalCase 。)
  • Struct Member Variables : camelCase结构成员变量camelCase
  • Enums : ModulePascalCase枚举ModulePascalCase
  • Enum Values : ALL_CAPS枚举值ALL_CAPS
  • Public Functions : ModulePascalCase公共函数ModulePascalCase
  • Private Functions : PascalCase私有函数PascalCase
  • Macros : PascalCasePascalCase

I typedef my structs, but use the same name for both the tag and the typedef.我 typedef 我的结构,但对标签和 typedef 使用相同的名称。 The tag is not meant to be commonly used.该标签并不意味着经常使用。 Instead it's preferrable to use the typedef.相反,最好使用 typedef。 I also forward declare the typedef in the public module header for encapsulation and so that I can use the typedef'd name in the definition.我还在公共模块头中转发声明 typedef 以进行封装,以便我可以在定义中使用 typedef 的名称。

Full struct Example :完整struct示例

typdef struct UtilsExampleStruct UtilsExampleStruct;
struct UtilsExampleStruct{
    int var;
    UtilsExampleStruct *p_link;
};

Well firstly C doesn't have public/private/virtual functions.首先,C 没有公共/私有/虚拟功能。 That's C++ and it has different conventions.那是 C++,它有不同的约定。 In C typically you have:在 C 通常你有:

  • Constants in ALL_CAPS ALL_CAPS 中的常量
  • Underscores to delimit words in structs or function names, hardly ever do you see camel case in C;在结构体或函数名中用下划线分隔单词,你在 C 中几乎看不到驼峰式大小写;
  • structs, typedefs, unions, members (of unions and structs) and enum values typically are in lower case (in my experience) rather than the C++/Java/C#/etc convention of making the first letter a capital but I guess it's possible in C too.结构、类型定义、联合、成员(联合和结构的)和枚举值通常是小写的(根据我的经验)而不是 C++/Java/C#/etc 将第一个字母设为大写的约定,但我想这可能在还有 C。

C++ is more complex. C++ 更复杂。 I've seen a real mix here.我在这里看到了真正的混合。 Camel case for class names or lowercase+underscores (camel case is more common in my experience).类名的驼峰式大小写或小写+下划线(在我的经验中,驼峰式大小写更常见)。 Structs are used rarely (and typically because a library requires them, otherwise you'd use classes).结构很少使用(通常是因为库需要它们,否则您将使用类)。

Coding in C#, java, C, C++ and objective C at the same time, I've adopted a very simple and clear naming convention to simplify my life.同时使用C#、java、C、C++ 和 Objective C进行编码,我采用了非常简单明了的命名约定来简化我的生活。

First of all, it relies on the power of modern IDEs (such as eclipse, Xcode...), with the possibility to get fast information by hovering or ctrl click... Accepting that, I suppressed the use of any prefix, suffix and other markers that are simply given by the IDE.首先,它依赖于现代 IDE(例如 eclipse、Xcode...)的强大功能,可以通过悬停或 ctrl 单击来快速获取信息...接受这一点,我禁止使用任何前缀、后缀以及其他由 IDE 简单提供的标记。

Then, the convention:然后,约定:

  • Any names MUST be a readable sentence explaining what you have.任何名字都必须是一个可读的句子,解释你有什么。 Like "this is my convention".就像“这是我的约定”。
  • Then, 4 methods to get a convention out of a sentence:然后,从句子中获取约定的 4 种方法:
    1. THIS_IS_MY_CONVENTION for macros, enum members THIS_IS_MY_CONVENTION用于宏、枚举成员
    2. ThisIsMyConvention for file name, object name (class, struct, enum, union...), function name, method name, typedef ThisIsMyConvention用于文件名、对象名(类、结构、枚举、联合...)、函数名、方法名、typedef
    3. this_is_my_convention global and local variables, this_is_my_convention全局和局部变量,
      parameters, struct and union elements参数、结构和联合元素
    4. thisismyconvention [optional] very local and temporary variables (such like a for() loop index) thisismyconvention [可选] 非常局部和临时的变量(例如 for() 循环索引)

And that's it.就是这样。

It gives它给

class MyClass {
    enum TheEnumeration {
        FIRST_ELEMENT,
        SECOND_ELEMENT,
    }

    int class_variable;

    int MyMethod(int first_param, int second_parameter) {
        int local_variable;
        TheEnumeration local_enum;
        for(int myindex=0, myindex<class_variable, myindex++) {
             localEnum = FIRST_ELEMENT;
        }
    }
}

I would recommend against mixing camel case and underscore separation (like you proposed for struct members).我建议不要混合驼峰式大小写和下划线分隔(就像你为结构成员提出的那样)。 This is confusing.这令人困惑。 You'd think, hey I have get_length so I should probably have make_subset and then you find out it's actually makeSubset .你会想,嘿我有get_length所以我应该有make_subset然后你发现它实际上是makeSubset Use the principle of least astonishment, and be consistent.使用最少惊讶的原则,并保持一致。

I do find CamelCase useful to type names, like structs, typedefs and enums.我确实发现 CamelCase 对键入名称很有用,例如结构、typedef 和枚举。 That's about all, though.不过,仅此而已。 For all the rest (function names, struct member names, etc.) I use underscore_separation.对于所有其余的(函数名称、结构成员名称等),我使用 underscore_separation。

Here's an (apparently) uncommon one, which I've found useful: module name in CamelCase, then an underscore, then function or file-scope name in CamelCase.这是一个(显然)不常见的,我发现它很有用:CamelCase 中的模块名称,然后是下划线,然后是 CamelCase 中的函数或文件范围名称。 So for example:例如:

Bluetooth_Init()
CommsHub_Update()
Serial_TxBuffer[]

You should also think about the order of the words to make the auto name completion easier.您还应该考虑单词顺序,以使自动名称完成更容易。

A good practice: library name + module name + action + subject一个好习惯:库名+模块名+动作+主题

If a part is not relevant just skip it, but at least a module name and an action always should be presented.如果某个部分不相关,请跳过它,但至少应始终显示模块名称和操作。

Examples:例子:

  • function name: os_task_set_prio , list_get_size , avg_get函数名称: os_task_set_priolist_get_sizeavg_get
  • define (here usually no action part): OS_TASK_PRIO_MAX定义(这里通常没有动作部分): OS_TASK_PRIO_MAX

I'm confused by one thing: You're planning to create a new naming convention for a new project.我对一件事感到困惑:您计划为新项目创建新的命名约定。 Generally you should have a naming convention that is company- or team-wide.通常,您应该有一个公司或团队范围的命名约定。 If you already have projects that have any form of naming convention, you should not change the convention for a new project.如果您已经有具有任何形式命名约定的项目,则不应更改新项目的约定。 If the convention above is just codification of your existing practices, then you are golden.如果上述约定只是您现有实践的编纂,那么您就是黄金。 The more it differs from existing de facto standards the harder it will be to gain mindshare in the new standard.它与现有的事实上的标准越不同,就越难在新标准中获得关注。

About the only suggestion I would add is I've taken a liking to _t at the end of types in the style of uint32_t and size_t.关于我要添加的唯一建议是,我喜欢在 uint32_t 和 size_t 样式的类型末尾使用 _t。 It's very C-ish to me although some might complain it's just "reverse" Hungarian.虽然有些人可能会抱怨它只是“反向”匈牙利语,但对我来说它非常C-ish。

There could be many, mainly IDEs dictate some trends and C++ conventions are also pushing.可能有很多,主要是 IDE 决定了一些趋势,C++ 约定也在推动。 For C commonly:对于 C 通常:

  • UNDERSCORED_UPPER_CASE (macro definitions, constants, enum members) UNDERSCORED_UPPER_CASE(宏定义、常量、枚举成员)
  • underscored_lower_case (variables, functions) underscored_lower_case(变量、函数)
  • CamelCase (custom types: structs, enums, unions) CamelCase(自定义类型:结构、枚举、联合)
  • uncappedCamelCase (oppa Java style) uncapedCamelCase(oppa Java 风格)
  • UnderScored_CamelCase (variables, functions under kind of namespaces) UnderScored_CamelCase(变量、命名空间下的函数)

Hungarian notation for globals are fine but not for types.全局变量的匈牙利符号很好,但不适用于类型。 And even for trivial names, please use at least two characters.即使是琐碎的名字,也请至少使用两个字符。

When I will program in CI will use this convention:当我在 CI 中编程时将使用这个约定:

definitions定义 prefix前缀 examples例子
variables - local (trivial)变量 - 局部(微不足道) / / i , n , a , b ... i , n , a , b ...
ii , nn , aa , bb ... ii , nn , aa , bb ...
iii , nnn , aaa , bbb ... iii , nnn , aaa , bbb ...
variable - local (descriptive)变量 - 本地(描述性) / / variable , conection ... variableconection ...
variable - global变量 - 全局 g_ g_variable , g_connection ... g_variable , g_connection ...
variable - constant变量 - 常量 c_ c_variable , c_connection ... c_variable , c_connection ...
pointer指针 p_ p_variable , p_connection ... p_variable , p_connection ...
array数组 a_ a_variable , a_connection ... a_variable , a_connection ...
struct结构 s_ s_variable , s_connection ... s_variable , s_connection ...
union工会 u_ u_variable , u_connection ... u_variable , u_connection ...
enum枚举 e_ e_variables , e_connection ... e_variables , e_connection ...
struct (member)结构(成员)
union (member)工会(会员)
enum (member)枚举(成员)
m_
m_
m_
m_variable , m_connection ... m_variable , m_connection ...
m_variable , m_connection ... m_variable , m_connection ...
m_variable , m_connection ... m_variable , m_connection ...
struct (bit field)结构体(位域) b_ b_variable , b_connection ... b_variable , b_connection ...
function功能 f_ f_variable , f_connection ... f_variable , f_connection ...
macro o_ o_variable , o_connection ... o_variable , o_connection ...

Note:笔记:

Each definition except variables has a single letter prefix, so that they can be combined and then not being miss understood.除了变量之外的每个定义都有一个单独的字母前缀,以便它们可以组合在一起而不会被错过。

Note:笔记:

Because I ran out of letters and I insisted to have only lower case letter prefixes, prefix " o_ " used for macro does not match the first letter of the definition ( m acro) but it matches the last letter (macr o ).因为我用完了字母并且我坚持只有小写字母前缀,所以用于宏的前缀“ o_ ”与定义的第一个字母( m acro )不匹配,但它与最后一个字母(macr o )匹配。

If you have any suggestions I am open minded.如果您有任何建议,我持开放态度。

I recommend you to read this document.我建议你阅读这份文件。

Abstract抽象的
This document is an updated version of the Indian Hill C Style and Coding Standards paper, with modifications by the last three authors.本文档是 Indian Hill C Style and Coding Standards 论文的更新版本,由最后三位作者进行了修改。 It describes a recommended coding standard for C programs.它描述了 C 程序的推荐编码标准。 The scope is coding style, not functional organization.范围是编码风格,而不是功能组织。

https://www.doc.ic.ac.uk/lab/cplus/cstyle.html#N1026F https://www.doc.ic.ac.uk/lab/cplus/cstyle.html#N1026F

I think those can help for beginner: Naming convention of variables in c我认为这些对初学者有帮助:C中变量的命名约定

  1. You have to use Alphabetic Character (az, AZ), Digit (0-9) and Under Score (_).您必须使用字母字符 (az, AZ)、数字 (0-9) 和下划线 (_)。 It's not allow to use any special Character like: %, $, #, @ etc. So, you can use user_name as variable but cannot use user&name .不允许使用任何特殊字符,如:%、$、#、@ 等。因此,您可以使用user_name作为变量,但不能使用user&name
  2. Can not use white space between words.单词之间不能使用空格。 So, you can use user_name or username or username as variable but cannot use user name .因此,您可以使用user_name 或 username 或 username作为变量,但不能使用user name
  3. Can not start naming with digit.不能以数字开头命名。 So, you can use user1 or user2 as variable but cannot use 1user .因此,您可以使用user1 或 user2作为变量,但不能使用1user
  4. It is case sensitive language.它是区分大小写的语言。 Uppercase and lowercase are significant.大写和小写都很重要。 If you use a variable like username then you cannot use USERNAME or Username for father use.如果您使用像用户名这样的变量,那么您不能将USERNAME 或 Username用于父亲使用。
  5. You can not use any keyword (char, int, if, for, while etc) for variable declaration.您不能使用任何关键字(char、int、if、for、while 等)进行变量声明。
  6. ANSI standard recognizes a length of 31 characters for a variable name ANSI 标准识别长度为 31 个字符的变量名

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM