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

时间:2009-11-12 13:16:50

标签: c naming-conventions

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

  1. GNU / linux / K& R with lower_case_functions
  2. ?名称 ?使用UpperCaseFoo函数
  3. 我只在这里谈论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)
    

12 个答案:

答案 0 :(得分:106)

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

  1. 大写字母中的所有宏和常量:MAX_BUFFER_SIZETRACKING_ID_PREFIX
  2. 在camelcase中使用结构名称和typedef:GtkWidgetTrackingOrder
  3. 对结构进行操作的函数:经典C样式:gtk_widget_show()tracking_order_process()
  4. 指针:这里没什么特别的: GtkWidget *fooTrackingOrder *bar
  5. 全局变量:只是不要使用全局变量。他们是邪恶的。
  6. 那里的功能,但是 不应该直接调用,或者有 模糊的用途,或者其他:一个或多个 一开始就强调: _refrobnicate_data_tables()_destroy_cache()

答案 1 :(得分:27)

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

答案 2 :(得分:13)

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

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

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

答案 3 :(得分:8)

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

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

答案 4 :(得分:8)

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

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

然后,惯例:

  • 任何名字都必须是一个可读的句子,解释你拥有的内容。就像“这是我的惯例”。
  • 然后,从句子中获得约定的4种方法:
    1. THIS_IS_MY_CONVENTION for macros,enum members
    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;
        }
    }
}

答案 5 :(得分:6)

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

Bluetooth_Init()
CommsHub_Update()
Serial_TxBuffer[]

答案 6 :(得分:6)

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

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

我输入我的结构,但使用相同的名称 标签和typedef。标签并不常用。 相反,它更喜欢使用typedef。我还在public模块头中声明了typedef以进行封装,以便我可以在定义中使用typedef&#39; d名称。

完整 struct 示例

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

答案 7 :(得分:3)

我对一件事感到困惑:你计划为新项目创建一个新的命名约定。通常,您应该具有公司或团队范围的命名约定。如果您已经拥有任何形式的命名约定的项目,则不应更改新项目的约定。如果上述惯例只是对现有做法的编纂,那么你就是金。它与现有的事实上的标准越不同,在新标准中获得思想共享的难度就越大。

关于我要添加的唯一建议是,我喜欢在uint32_t和size_t风格的类型末尾_t。这对我来说非常C-ish虽然有些人可能会抱怨它只是“反向”匈牙利人。

答案 8 :(得分:2)

当我用 C 编程时,我会使用这个约定:

<头>
定义 前缀 例子
变量 - 局部(琐碎) / inab...
iinnaa , bb...
iii, nnn, aaa, bbb...
变量 - 本地(描述性) / variable, conection...
变量 - 全局 g_ g_variable, g_connection...
变量 - 常量 c_ c_variable, c_connection...
指针 p_ p_variable , p_connection...
数组 a_ a_variable, a_connection...
结构 s_ s_variable, s_connection...
工会 u_ u_variable, u_connection...
枚举 e_ e_variables, e_connection...
struct (member)
union (member)
enum (member)
m_
m_
m_
m_variablem_connection...
m_variablem_connection...
m_variablem_connection ...
struct (位域) b_ b_variable, b_connection...
功能 f_ f_variable, f_connection...
o_ o_variable, o_connection...
<块引用>

注意:

除了变量之外的每个定义都有一个单字母前缀,这样它们就可以组合起来而不会被遗漏。

<块引用>

注意:

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

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

答案 9 :(得分:0)

您还应该考虑顺序以简化自动名称

一个好习惯:库名+模块名+动作+主题

如果某个部件不相关,则只需跳过它,但至少应该显示一个模块名称和一个动作。

示例:

  • 功能名称:os_task_set_priolist_get_sizeavg_get
  • 定义(此处通常没有操作部分):OS_TASK_PRIO_MAX

答案 10 :(得分:0)

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

  • UNDERSCORED_UPPER_CASE(宏定义,常量,枚举成员)
  • underscored_lower_case(变量,函数)
  • CamelCase(自定义类型:结构,枚举,联合)
  • uncappedCamelCase(oppa Java style)
  • UnderScored_CamelCase(变量,名称空间类型下的函数)

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

答案 11 :(得分:0)

我认为这些可以为初学者提供帮助: c

中变量的命名约定
  1. 您必须使用字母字符(a-z,A-Z),数字(0-9)和未满分数(_)。不允许使用任何特殊字符,例如%,$,#,@等。因此,您可以使用 user_name 作为变量,但不能使用 user&name
  2. 不能在单词之间使用空格。因此,您可以使用 user_name或用户名或用户名作为变量,但不能使用用户名
  3. 无法以数字开始命名。因此,您可以使用 user1或user2 作为变量,但不能使用 1user
  4. 这是区分大小写的语言。大写和小写都很重要。如果您使用 username 之类的变量,则不能将 USERNAME或Username 用作父亲使用。
  5. 您不能使用任何关键字(char,int,if,for,while等)进行变量声明。
  6. ANSI标准可识别长度为31个字符的变量名