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

发布于 2024-08-11 07:29:49 字数 702 浏览 7 评论 0原文

C 语言中常用的命名约定是什么?我知道至少有两个:

  1. GNU / linux / K&R with lower_case_functions
  2. ?姓名 ?对于 UpperCaseFoo 函数,

我在这里只讨论 C。我们的大多数项目都是使用 C 的小型嵌入式系统。

这是我计划在下一个项目中使用的系统:


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)

What are the naming conventions commonly use in C? I know there are at least two:

  1. GNU / linux / K&R with lower_case_functions
  2. ? name ? with UpperCaseFoo functions

I am talking about C only here. Most of our projects are small embedded systems in which we use C.

Here is the one I am planning on using for my next project:


C Naming Convention

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)

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(13

旧梦荧光笔 2024-08-18 07:29:49

这里最重要的是一致性。也就是说,我遵循 GTK+ 编码约定,可概括如下:

  1. 所有宏和常量均大写:MAX_BUFFER_SIZETRACKING_ID_PREFIX
  2. 结构名称和类型定义采用驼峰式命名:GtkWidgetTrackingOrder
  3. 对结构进行操作的函数:经典 C 风格:gtk_widget_show()tracking_order_process()
  4. 指针:这里没什么特别的:
    GtkWidget *fooTrackingOrder *bar
  5. 全局变量:只是不要使用全局变量。他们是邪恶的。
  6. 功能都有,但是
    不应该直接调用,或者有
    模糊的用途,或其他什么:一种或多种
    在开头加下划线:
    _refrobnicate_data_tables()_destroy_cache()

The most important thing here is consistency. That said, I follow the GTK+ coding convention, which can be summarized as follows:

  1. All macros and constants in caps: MAX_BUFFER_SIZE, TRACKING_ID_PREFIX.
  2. Struct names and typedef's in camelcase: GtkWidget, TrackingOrder.
  3. Functions that operate on structs: classic C style: gtk_widget_show(), tracking_order_process().
  4. Pointers: nothing fancy here:
    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().
凡尘雨 2024-08-18 07:29:49

你知道,我喜欢保持简单,但清晰...所以这就是我在 C 中使用的内容:

  • 平凡变量i,n,c等。 .(只有一个字母。如果没有一个字母
    明确,然后将其设为局部变量)
  • 局部变量camelCase
  • 全局变量g_camelCase
  • 常量变量ALL_CAPS
  • 指针变量:在前缀中添加一个p_。对于全局变量,它是 gp_var,对于局部变量,它是 p_var,对于 const 变量,它是 p_VAR。如果使用远指针,则使用 fp_ 而不是 p_
  • 结构ModulePascalCase(模块=完整模块名称,或2-3个字母的缩写,但仍采用PascalCase。)
  • 结构成员变量camelCase
  • 枚举ModulePascalCase
  • 枚举值ALL_CAPS
  • < strong>公共函数:ModulePascalCase
  • 私有函数PascalCase
  • PascalCase code>

我输入了我的结构,但使用相同的名称
标签和 typedef。该标签并不适合常用。
相反,最好使用 typedef。我还在公共模块头中转发声明 typedef 以进行封装,以便我可以在定义中使用 typedef 名称。

完整 结构 示例

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

You know, I like to keep it simple, but clear... So here's what I use, in C:

  • Trivial Variables: i,n,c,etc... (Only one letter. If one letter isn't
    clear, then make it a Local Variable)
  • Local Variables: camelCase
  • Global Variables: g_camelCase
  • Const Variables: ALL_CAPS
  • Pointer Variables: add a p_ to the prefix. For global variables it would be gp_var, for local variables p_var, for const variables p_VAR. If far pointers are used then use an fp_ instead of p_.
  • Structs: ModulePascalCase (Module = full module name, or a 2-3 letter abbreviation, but still in PascalCase.)
  • Struct Member Variables: camelCase
  • Enums: ModulePascalCase
  • Enum Values: ALL_CAPS
  • Public Functions: ModulePascalCase
  • Private Functions: PascalCase
  • Macros: PascalCase

I typedef my structs, but use the same name for
both the tag and the typedef. The tag is not meant to be commonly used.
Instead it's preferrable to use the 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.

Full struct Example:

typedef struct UtilsExampleStruct UtilsExampleStruct;
struct UtilsExampleStruct{
    int var;
    UtilsExampleStruct *p_link;
};
谎言 2024-08-18 07:29:49

“结构指针”不是需要命名约定子句来覆盖它们的实体。它们只是struct WhatEver *。不要隐藏这样一个事实:巧妙且“明显”的 typedef 涉及到一个指针。它没有任何作用,打字时间更长,并且破坏了声明和访问之间的平衡。

"Struct pointers" aren't entities that need a naming convention clause to cover them. They're just struct WhatEver *. DON'T hide the fact that there is a pointer involved with a clever and "obvious" typedef. It serves no purpose, is longer to type, and destroys the balance between declaration and access.

两仪 2024-08-18 07:29:49

首先,C 没有公共/私有/虚拟函数。这就是 C++,它有不同的约定。在 C 中,通常有:

  • 全部大写的常量
  • 下划线用于分隔结构或函数名称中的单词,在 C 中几乎看不到驼峰式大小写;
  • 结构、typedef、联合、成员(联合和结构)和枚举值通常采用小写(根据我的经验),而不是 C++/Java/C#/etc 将第一个字母设为大写的约定,但我想这是可能的C也是。

C++ 更复杂。我在这里看到了真正的混合。类名使用驼峰式大小写或小写+下划线(根据我的经验,驼峰式大小写更常见)。结构很少使用(通常是因为库需要它们,否则您将使用类)。

Well firstly C doesn't have public/private/virtual functions. That's C++ and it has different conventions. In C typically you have:

  • Constants in ALL_CAPS
  • Underscores to delimit words in structs or function names, hardly ever do you see camel case in 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++ is more complex. 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).

卸妝后依然美 2024-08-18 07:29:49

同时使用C#、java、C、C++ 和 Objective C 进行编码,我采用了非常简单明了的命名约定来简化我的生活。

首先,它依赖于现代 IDE 的强大功能(例如 eclipse、Xcode...),可以通过悬停或 ctrl 单击来快速获取信息...
接受这一点后,我禁止使用 IDE 简单给出的任何前缀、后缀和其他标记。

然后,约定:

  • 任何名称都必须是一个可读的句子,解释您所拥有的内容。就像“这是我的惯例”。
  • 然后,有 4 种方法可以从句子中获得约定:
    1. THIS_IS_MY_CONVENTION 用于宏、枚举成员
    2. ThisIsMyConvention 用于文件名、对象名称(类、结构、枚举、联合...)、函数名称、方法名称、typedef
    3. this_is_my_convention 全局变量和局部变量,
      参数、结构和联合元素
    4. thisismyconvention [可选]非常局部和临时的变量(例如 for() 循环索引)

就是这样。

它给出了

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

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.

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.

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:
    1. THIS_IS_MY_CONVENTION for macros, enum members
    2. ThisIsMyConvention for file name, object name (class, struct, enum, union...), function name, method name, typedef
    3. this_is_my_convention global and local variables,
      parameters, struct and union elements
    4. thisismyconvention [optional] very local and temporary variables (such like a for() loop index)

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;
        }
    }
}
清风疏影 2024-08-18 07:29:49

这是一个(显然)不常见的,我发现它很有用:模块名称采用驼峰式命名法,然后是下划线,然后是驼峰式命名法的函数或文件范围名称。例如:

Bluetooth_Init()
CommsHub_Update()
Serial_TxBuffer[]

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. So for example:

Bluetooth_Init()
CommsHub_Update()
Serial_TxBuffer[]
戏剧牡丹亭 2024-08-18 07:29:49

我建议不要混合使用驼峰式大小写和下划线分隔(就像您建议的结构成员一样)。这很令人困惑。您可能会想,嘿,我有 get_length,所以我可能应该有 make_subset,然后您发现它实际上是 makeSubset。使用最少惊讶的原则,并保持一致。

我确实发现 CamelCase 对于键入名称(如结构、typedef 和枚举)很有用。不过,这就是全部了。对于其余所有内容(函数名称、结构成员名称等),我使用下划线分隔。

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. Use the principle of least astonishment, and be consistent.

I do find CamelCase useful to type names, like structs, typedefs and enums. That's about all, though. For all the rest (function names, struct member names, etc.) I use underscore_separation.

最舍不得你 2024-08-18 07:29:49

您还应该考虑单词顺序,以使自动名称完成更容易。

一个好的做法:库名称 + 模块名称 + 操作 + 主题

如果某个部分不相关,则跳过它,但至少应始终显示模块名称和操作。

示例:

  • 函数名称:os_task_set_priolist_get_sizeavg_get
  • 定义(这里通常没有操作部分):OS_TASK_PRIO_MAX

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
  • define (here usually no action part): OS_TASK_PRIO_MAX
刘备忘录 2024-08-18 07:29:49

当我在 CI 中编程时,将使用以下约定:

定义前缀示例
变量 - 本地 (trivial)/i, n, ab...
iinnaabb...
iiinnnaaabbb...
变量 -局部(描述性)/变量连接...
变量 - 全局g_g_variable, g_connection...
变量 - 常量c_c_variable, c_connection...
指针p_< /code>p_variablep_connection...
数组a_a_variablea_connection。 ..
structs_s_variable, s_connection...
unionu_u_variable, < code>u_connection...
枚举e_e_variablese_connection...
struct (成员)
联合(成员)
枚举(成员)
m_
m_
m_
m_variablem_connection...
m_variablem_connection.. .
m_variablem_connection...
struct (位域)b_b_variable,b_connection...
函数f_f_variablef_connection...
o_代码>o_variableo_connection...

注意:

除了变量之外的每个定义都有一个字母前缀,这样它们就可以组合起来,以免被错过。

注意:

因为我的字母用完了,并且我坚持只使用小写字母前缀,所以用于宏的前缀“o_”与定义的第一个字母不匹配(macro),但它与最后一个字母 (macro) 匹配。


如果您有任何建议,我持开放态度。

When I will program in C I will use this convention:

definitionsprefixexamples
variables - local (trivial)/i, n, a, b...
ii, nn, aa, bb...
iii, nnn, aaa, bbb...
variable - local (descriptive)/variable, conection...
variable - globalg_g_variable, g_connection...
variable - constantc_c_variable, c_connection...
pointerp_p_variable , p_connection...
arraya_a_variable, a_connection...
structs_s_variable, s_connection...
unionu_u_variable, u_connection...
enume_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...
struct (bit field)b_b_variable, b_connection...
functionf_f_variable, f_connection...
macroo_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 (macro) but it matches the last letter (macro).

If you have any suggestions I am open minded.

好多鱼好多余 2024-08-18 07:29:49

我对一件事感到困惑:您计划为新项目创建新的命名约定。一般来说,您应该有一个公司或团队范围内的命名约定。如果您已有的项目具有任何形式的命名约定,则不应更改新项目的约定。如果上述约定只是对您现有实践的编纂,那么您就很出色了。它与现有的事实上的标准越不同,就越难获得新标准的关注。

关于我要添加的唯一建议是,我喜欢 uint32_t 和 size_t 样式的类型末尾的 _t 。对我来说,它非常 C 式,尽管有些人可能会抱怨它只是“反向”匈牙利语。

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. It's very C-ish to me although some might complain it's just "reverse" Hungarian.

鲜血染红嫁衣 2024-08-18 07:29:49

可能有很多,主要是 IDE 决定了一些趋势,C++ 约定也在推动。对于 C 语言,通常有:

  • UNDERSCORED_UPPER_CASE(宏定义、常量、枚举成员)
  • underscored_lower_case(变量、函数)
  • CamelCase(自定义类型:结构体、枚举、联合)
  • uncappedCamelCase(oppa Java 风格)
  • UnderScored_CamelCase(某种命名空间下的变量、函数)

匈牙利表示法全局变量很好,但不适用于类型。
即使对于简单的名称,也请至少使用两个字符。

There could be many, mainly IDEs dictate some trends and C++ conventions are also pushing. For C commonly:

  • UNDERSCORED_UPPER_CASE (macro definitions, constants, enum members)
  • underscored_lower_case (variables, functions)
  • CamelCase (custom types: structs, enums, unions)
  • uncappedCamelCase (oppa Java style)
  • UnderScored_CamelCase (variables, functions under kind of namespaces)

Hungarian notation for globals are fine but not for types.
And even for trivial names, please use at least two characters.

世界和平 2024-08-18 07:29:49

我建议您阅读本文档

摘要
本文档是 Indian Hill C 风格和编码标准论文的更新版本,由最后三位作者进行了修改。它描述了 C 程序的推荐编码标准。范围是编码风格,而不是功能组织。

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. It describes a recommended coding standard for C programs. The scope is coding style, not functional organization.

悲欢浪云 2024-08-18 07:29:49

几年过去了,这仍然是一个相关的主题。多年来我继承了大量的代码,我会说现在的风格可能与 2001 年的风格不同(而且更好)。

虽然我不太喜欢这样的编码标准,但我有一些我喜欢使用的约定,它们都有几个原因,并且与上面的一些想法相冲突:

  1. 请使用长变量名。如今,我们的显示器都和电视一样宽。早在 2001 年,我们的办公桌上有一台 19 英寸 CRT 就很幸运了,但现在我们有两台 2k/27 英寸。 2001 年制定标准的人们可能已经在带有 14 英寸金鱼缸的 BBC Micros 和 IBM XT 上进行了实践。

  2. 不要让类型看起来相同。例如,将枚举定义为 ThisIsAnEnum,将结构定义为 ThisIsAStruct 会使它们变得相同。我很喜欢 T_E_THIS_IS_AN_ENUM 和 T_S_THIS_IS_A_STRUCT 因为它们显然不是变量,而且它们也显然不是宏,并且您不必在其中任何一个的名称中添加“enum”。 typedef 或变量名。同样,我将 C_ 放在宏的开头,因为它们是常量,这有点误导,但它显然与其他任何东西不同。
    常量变量是一个有趣的变量,但是当编译器像变量一样处理它们时,我也这样做。编译器会告诉你是否搞砸了它们,这样就不用担心了。

  3. 请说出变量有多大。这是有争议的,但任何继承旧代码的人很可能会从 8 位或 16 位系统移植到新的 32 位处理器。毕竟,这是一个嵌入式线程。然而,还有另一个好处,那就是它会告诉您一切是如何联系在一起的。例如,如果您将某些内容声明为 8 位并优化大小,那么您将在每个地址空间中压缩其中的四个 - 编译器将为您完成此操作并添加以不可见方式提取它所需的代码。然而,如果您针对速度进行优化,您将占用一个 32 位数据空间并在一个时钟周期内执行该代码。我们进入嵌入式的全部原因是为了这种级别的控制,因此这对嵌入式系统很重要(毕竟,枚举是整数)通过了解系统的变量有多大,您可以真正了解系统的很多信息。此外,我们经常看到 ARM 以其 32 位内核主导市场,但也有大量采用非 32 位低成本 PIC 或 Atmel 的设计。此外,ARM 革命可能即将成为 Risc 革命,而且 ARM 已经是 64 位了……这一切都将重演。

25 年前,代码约定在嵌入式领域并不是什么真正的东西,因为它往往是电子工程师将代码拼凑在一起的。我看到那个时代的代码,发现很多随机且不合适的“易失性”和全局变量,即使是 2024 年的免费工具也不需要这些。但如果您正在做商业工作 - 不要使用免费工具!哈哈。即使是一名研究生工程师,购买合适的工具的成本还不到一个月的工资。

Several years on and this is still a relevant thread. I've inherited loads of code over the years and I will say that the style now is probably different (and better) than what it would have been in 2001.

Whilst I'm not really into coding standards as such, I have a few conventions I like to work with and they're all for several reasons and they conflict with some ideas above:

  1. DO use long variable names. We all have monitors as wide as our televisions these days. Back in 2001 we would have been lucky to have a 19 inch CRT on our desks but now we have two 2k/27 inchers. The people setting the standards in 2001 would have cut their teeth on BBC Micros and IBM XTs with 14" goldfish bowls.

  2. DON'T make types look the same. For instance defining an enum as ThisIsAnEnum and a struct as ThisIsAStruct makes them look identical. I quite like T_E_THIS_IS_AN_ENUM and T_S_THIS_IS_A_STRUCT because they're clearly not variables and they're also clearly not macros. They're also clearly not each other and you don't have to put "enum" in the name of either the typedef or the variable name. Similarly I put C_ at the start of a Macro because they're constant. It's a bit misleading but it's clearly different to anything else.
    Constant variables are an interesting one but as the compiler deals with them like variables, I do too. The compiler is going to tell you if you muck them up so there's less to worry about.

  3. DO say how big the variable is. This is controversial but anyone inheriting old code may well be porting to a new 32 bit processor from an 8 or 16 bit system. After all, this was an embedded thread. However, there's another benefit and that is it will tell you how everything hangs together. For instance, if you declare something as 8 bit and optimise for size, you're gonna squeeze four of those in every address space - the compiler will do it for you and add the code needed to extract it invisibly. However if you optimise for speed you're going to take one 32 bit data space and execute that code in one clock cycle. The whole reason we go embedded is for this level of control so this matters on embedded systems (after all, enums are ints for example) You can really learn a lot about a system by knowing how big its variables are. Further to that, we often see ARM dominating the market with their 32 bit cores however there are loads of designs with low cost PICs or Atmels in that are not 32 bit. Add to that the ARM revolution might be about to become the Risc revolution and ARMs are already 64 bit... it's all about to repeat itself.

Code conventions weren't really a thing 25 years ago in embedded as it tended to be electronics engineers chucking the code together. I see code from that era and find lots of random and inappropriate "volatiles" and globals that are just not necessary with even free tools in 2024. But if you're doing commercial work - DO NOT USE FREE TOOLS! haha. The right tools cost less than a months' salary of even a graduate engineer.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文