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

Jef*_*ffV 114 c naming-conventions

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

  1. 具有lower_case_functions的GNU/linux/K&R
  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)
Run Code Online (Sandbox Code Playgroud)

axe*_*l_c 116

这里最重要的是一致性.也就是说,我遵循GTK +编码惯例,可归纳如下:

  1. 大写字母中的所有宏和常量:MAX_BUFFER_SIZE,TRACKING_ID_PREFIX.
  2. 在camelcase中的结构名称和typedef:GtkWidget, TrackingOrder.
  3. 对结构进行操作的函数:经典C风格:gtk_widget_show(), tracking_order_process().
  4. 指针:没有什么花哨的位置: GtkWidget *foo,TrackingOrder *bar.
  5. 全局变量:只是不使用全局变量.他们是邪恶的.
  6. 存在的函数,但不应直接调用,或具有模糊的用途,或者其他:开头的一个或多个下划线: _refrobnicate_data_tables(),_destroy_cache().

  • 关于第6点的补充说明:C标准有一些关于保留以`_`开头的名称的规则,以供实现和将来使用.以_ _`开头的名字有一些例外,但在我看来,记忆是不值得的.一个安全的规则是永远不要在代码中使用以`_`开头的名称.相关的C FAQ条目:http://c-faq.com/~scs/cgi-bin/faqcat.cgi?sec=decl#namespace (23认同)
  • 在第六点,我更喜欢使用`static`并跳过模块前缀,所以如果`gtk_widget_show()`是一个带有文件范围的函数,它将变成简单的`widget_show()`并添加了静态存储类. (13认同)
  • 本地多字变量怎么样?my_var还是myVar? (5认同)
  • #2更具体地说是*上驼峰情况*或*pascal情况*.骆驼箱或下骆驼箱在第一个字母上使用小写字母. (4认同)
  • 对于第六点,使用尾随下划线怎么样?或者诸如"internal_"的前缀? (2认同)
  • `全局变量:只是不要使用全局变量。它们是邪恶的。--除非您正在从事嵌入式项目,并且您具有1024字节的RAM和8MHz的CPU。 (2认同)

unw*_*ind 28

"结构指针"不是需要命名约定子句来覆盖它们的实体.他们只是struct WhatEver *.不要隐瞒一个指针涉及一个聪明且"明显"的typedef这一事实.它没有用处,打字时间更长,破坏了声明和访问之间的平衡.

  • 对于"不要隐藏指针"的东西+1 - 即使这个答案没有解决问题的其余部分(还). (28认同)
  • @unwind,我倾向于同意。然而,有时指针并不打算被外部取消引用,它更多的是消费者的句柄,而不是指向他们将使用的结构的实际指针。这就是我留下 TitleCasePtr 的原因。typedef struct { 字段 } MyStruct, *MyStructPtr; (4认同)

cle*_*tus 14

首先,C没有公共/私有/虚拟功能.这是C++,它有不同的约定.在C中通常你有:

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

C++更复杂.我在这里看到了真正的混音.用于班级名称或小写+下划线的驼峰案例(根据我的经验,骆驼案例更为常见).结构很少使用(通常因为库需要它们,否则你会使用类).

  • 您可以将静态函数视为私有; 问题没有提到虚拟.但是+1'很少看到C中的骆驼案例. (3认同)
  • 我认为杰夫的意思是"公共职能"的"外部联系"和"私人职能"的"内部联系". (2认同)
  • `ALL_CAPS`也经常用于枚举值. (2认同)

Sea*_*mey 10

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

  • 平凡变量:i,n,c等等...(只有一个字母.如果一个字母不清楚,那么将其变为局部变量)
  • 局部变量:lowerCamelCase
  • 全局变量:g_lowerCamelCase
  • Const变量:ALL_CAPS
  • 指针变量:p_在前缀中添加一个.对于全局变量gp_var,对于局部变量p_var,它将是const变量p_VAR.如果使用远指针则使用fp_而不是p_.
  • 结构 :( ModuleCamelCase模块=完整模块名称,或2-3字母缩写,但仍在CamelCase.)
  • 结构成员变量:lowerCamelCase
  • 枚举:ModuleCamelCase
  • 枚举值:ALL_CAPS
  • 公共职能:ModuleCamelCase
  • 私人职能:CamelCase
  • :CamelCase

我输入我的结构,但对标签和typedef使用相同的名称.标签并不常用.相反,最好使用typedef.我还在public模块头中声明了typedef以进行封装,以便我可以在定义中使用typedef'd名称.

完整 struct 示例:

typdef struct TheName TheName;
struct TheName{
    int var;
    TheName *p_link;
};
Run Code Online (Sandbox Code Playgroud)

  • 不是“PascalCase”和“camelCase”吗? (2认同)
  • 此格式类似于 java 和 c# 命名约定。我只是建议您使用驼峰命名法进行函数命名,并使用模块前缀,例如“MDL_functionName()”,而且我没有看到使用 p_ 前缀作为指针的好处,我会删除它以及。 (2认同)

Luc*_*ier 9

C#,java,C,C++和目标C的同时编码,我采用了一种非常简单明了的命名约定来简化我的生活.

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

然后,惯例:

  • 任何名字都必须是一个可读的句子,解释你的所有.就像"这是我的惯例".
  • 然后,4个方法从句子中获得约定:
    1. THIS的成员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;
        }
    }
}
Run Code Online (Sandbox Code Playgroud)


Eli*_*sky 8

我建议不要混合驼峰案例和下划线分离(就像你为结构成员提出的那样).这令人困惑.你会想,嘿,我有,get_length所以我应该有make_subset,然后你发现它实际上makeSubset.使用最不惊讶的原则,并保持一致.

我确实发现CamelCase对于类型名称很有用,比如结构,typedef和枚举.但这就是全部.对于所有其余的(函数名,结构成员名等),我使用underscore_separation.


Ste*_*off 6

这是一个(显然)不常见的,我发现它很有用:CamelCase中的模块名称,然后是CamelCase中的下划线,函数或文件范围名称.例如:

Bluetooth_Init()
CommsHub_Update()
Serial_TxBuffer[]
Run Code Online (Sandbox Code Playgroud)

  • 不那么不寻常,但非常有用。 (3认同)

Gáb*_*osi 6

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

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

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

例子:

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