根据this stack overflow answer,类型名称上的“_t”后缀在C中保留。当使用typedef
创建一个新的opaque类型时,我习惯于在这是一种类型的名称。通常我会选择类似hashmap_t
的东西,但现在我还需要别的东西。
C中的类型是否有任何标准命名方案?在其他语言中,使用类似Hashmap
的CapsCase是常见的,但我看到的很多C代码根本不使用大写。 CapsCase也可以很好地使用库前缀,例如XYHashmap
。
在C中命名类型是否存在通用规则或标准?
答案 0 :(得分:6)
是的,如果您包含任何POSIX标题,POSIX会保留名称以_t
结尾,因此建议您在理论上保持清楚。在过去的二十多年里,我参与了一个与这些名字相冲突两三次的项目。您可以使用公司前缀(例如,您的公司的TLA和下划线),或使用大小写混合的名称(以及_t
后缀)来最小化冲突风险;我见过的所有碰撞都是短小的全小写(dec_t
,loc_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
结尾的当前标识符加上任何以int
或uint
(7.26.8)开头的标识符。但是,POSIX可能会保留更多。
这是C中的一个普遍问题,因为你有非常平坦的命名空间,并且没有银弹。 如果您熟悉CapCase名称并且它们适合您,则应继续使用它们。否则,您将必须评估当前项目的目标并查看最佳解决方案它们。
答案 3 :(得分:2)
CapsCase通常用于C中的类型。
例如,如果您查看GNOME生态系统中的项目(GTK +,GDK,GLib,GObject,Clutter等),您会看到类似GtkButton
或ClutterStageWindow
的类型。他们仅使用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)
关于这个主题有很多想法和意见,但命名类型没有一个通用的标准。最重要的是保持一致。在没有编码标准的情况下,在维护代码时,抵制使用另一种命名约定的冲动。引入新的命名约定,即使它是完美的,也会增加不必要的复杂性。
在采访人们时,这实际上是一个很好的话题。我从未遇到过对此没有意见的优秀程序员。答案中没有任何意见或没有激情表明该人不是经验丰富的程序员。