在C中命名类型时要使用的样式

时间:2010-01-02 06:39:06

标签: c naming-conventions

根据this stack overflow answer,类型名称上的“_t”后缀在C中保留。当使用typedef创建一个新的opaque类型时,我习惯于在这是一种类型的名称。通常我会选择类似hashmap_t的东西,但现在我还需要别的东西。

C中的类型是否有任何标准命名方案?在其他语言中,使用类似Hashmap的CapsCase是常见的,但我看到的很多C代码根本不使用大写。 CapsCase也可以很好地使用库前缀,例如XYHashmap

在C中命名类型是否存在通用规则或标准?

6 个答案:

答案 0 :(得分:6)

是的,如果您包含任何POSIX标题,POSIX会保留名称以_t结尾,因此建议您在理论上保持清楚。在过去的二十多年里,我参与了一个与这些名字相冲突两三次的项目。您可以使用公司前缀(例如,您的公司的TLA和下划线),或使用大小写混合的名称(以及_t后缀)来最小化冲突风险;我见过的所有碰撞都是短小的全小写(dec_tloc_t,......)。

除了系统提供的(和系统保留的)_t后缀之外,没有特定的广泛使用的约定。其中一个混合案例系统(camelCase或InitialCaps)效果很好。系统前缀也很有效 - 更好的图书馆往往会小心这些。

如果你决定使用小写和_t后缀,请确保你使用足够长的名字,并努力检查POSIX标准,你工作的主要平台,以及你认为可能的任何努力避免不必要的冲突。当您向客户发布一些名称example_t然后发现某些新平台存在冲突时,会出现最严重的问题。然后你必须考虑让客户改变他们的代码,而他们总是不愿意这样做。最好事先避免这个问题。

答案 1 :(得分:5)

Indian Hill style guidelines有一些建议:

  

个别项目无疑会有   他们自己的命名惯例。那里   然而,这是一些一般规则。

     
      
  • 带有前导和尾部下划线的名称是为系统保留的   目的,不应该用于   任何用户创建的名称。大多数系统   将它们用于用户的名称   不应该知道。如果你必须   有自己的私人标识符,   用一两个字母开始   确定他们的包裹   属于

  •   
  • #define常量应该在所有CAPS中。

  •   
  • 枚举常量为大写或全部CAPS

  •   
  • 函数,typedef和变量名,以及struct,union和   枚举标记名称应该更低   情况下。

  •   
  • 许多宏“功能”都在所有CAPS中。一些宏(例如getchar和   putchar)因为他们是小写的   也可以作为函数存在。   小写宏名称仅为   如果宏表现得像一个,则可以接受   函数调用,即他们评估   他们的参数恰好一次就行了   不为命名参数赋值。   有时写一个是不可能的   行为像一个函数的宏   即使论点是   恰好评估了一次。

  •   
  • 避免仅在大小写方面有所不同的名称,例如foo和Foo。同样的,   避免foobar和foo_bar。该   混淆的可能性是   相当大的。

  •   
  • 同样,避免看起来彼此相似的名称。在许多终端和   打印机,'l','1'和'我'看起来很好   类似。名为'l'的变量是   特别糟糕,因为它看起来如此   很像常数'1'。

  •   
     

一般来说,全球名称(包括   枚举)应该有一个共同的前缀   识别他们的模块   属于。也可以是全球   被归为全球结构。   Typedeffed名称通常有“_t”   附在他们的名字上。

     

避免可能与之冲突的名称   各种标准库名称。一些   系统将包含更多库代码   比你想要的。此外,您的计划可能   有一天会延长。

答案 2 :(得分:3)

C仅保留 _t后缀的某些使用。据我所知,这只是以_t结尾的当前标识符加上任何以intuint(7.26.8)开头的标识符。但是,POSIX可能会保留更多。

这是C中的一个普遍问题,因为你有非常平坦的命名空间,并且没有银弹。 如果您熟悉CapCase名称并且它们适合您,则应继续使用它们。否则,您将必须评估当前项目的目标并查看最佳解决方案它们。

答案 3 :(得分:2)

CapsCase通常用于C中的类型。

例如,如果您查看GNOME生态系统中的项目(GTK +,GDK,GLib,GObject,Clutter等),您会看到类似GtkButtonClutterStageWindow的类型。他们使用CapsCase作为数据类型;函数名和变量都是小写的下​​划线分隔符 - 例如clutter_actor_get_geometry()

类型命名方案就像缩进惯例 - 它们会产生宗教战争,人们为自己喜欢的方法主张某种道德优势。当然最好遵循现有代码或相关项目中的风格(例如,对我来说,过去几年中的GNOME。)

但是,如果你从头开始并且没有模板,那就没有硬性规则。如果你有兴趣有效地编码并在合理的时间离开工作,这样你就可以回家喝啤酒或其他任何东西,你当然应该选择一种风格并坚持下去为你的项目,但是你选择哪种风格很重要

答案 4 :(得分:2)

一个合理运行的替代解决方案是对所有类型名称和宏名称使用大写。全局变量可能是CapCase(CamelBack),所有局部变量都是小写的。

这种技术有助于提高可读性,并利用语言语法减少变量名中的污染字符数;例如gvar,kvar,type_t等。例如,数据类型不能与任何其他类型在语法上混淆。

通过至少包含一个大写字母,可以轻松区分全局变量与本地变量。

我同意在所有令牌名称中都应避免使用带前缀或后缀的下划线。

让我们看看下面的例子。

很明显,InvertedCount因其案例而成为全球性的。同样清楚的是,由于它们的sytax,INT32U和RET_ERR是类型。很明显,INVERT_VAL()是一个宏,因为它位于右侧并且没有强制转换因此它不能成为数据类型。

但有一件事是肯定的。无论您使用哪种方法,都应该与您的组织编码标准一致。对我来说,最少的杂乱,越多越好。

当然,风格是另一个问题。

#define  INVERT_VAL(x)   (~x)
#define  CALIBRATED_VAL  100u

INT32U  InvertedCount;

typedef  enum {
    ERR_NONE = 0,
    ...
} RET_ERR;

RET_ERR  my_func (void) 
{
    INT32U  val;
    INT32U  check_sum;


    val           = CALIBRATED_VAL;   // --> Lower case local variable.
    check_sum     = INVERT_VAL(val);  // --> Clear use of macris.

    InvertedCount = checksum;         // --> Upper case global variable.  
                                      //     Looks different no g prefix required.

    ... 

    return (ERR_NONE); 
}

答案 5 :(得分:0)

关于这个主题有很多想法和意见,但命名类型没有一个通用的标准。最重要的是保持一致。在没有编码标准的情况下,在维护代码时,抵制使用另一种命名约定的冲动。引入新的命名约定,即使它是完美的,也会增加不必要的复杂性。

在采访人们时,这实际上是一个很好的话题。我从未遇到过对此没有意见的优秀程序员。答案中没有任何意见或没有激情表明该人不是经验丰富的程序员。