从头学C(12)变量名

0

上一章我们已经学习了关于C语言的一些核心知识,当然还有很多细节的东西我们必须要掌握,不然写出的程序即便出了问题,调试时也会感到无从下手。

我们每个人从一出生,头一件大事当然就是取名字了,名字取得好不好也是一门学问。写程序这事儿,更离不开取名了,函数名、变量名、符号常量名……所以我们先从这名字下手,看看C语言里是不是有什么规定。

第二章 类型、运算符与表达式 >> 2.1 变量名

C语言对于变量、常量、函数的命名的确是有限制的,主要如下规定:

  1. 名字只能由字母、下划线“_”和数字组成;
  2. 名字不能以数字开头,只能是字母或者下划线开头,不过由于标准库中通常以下划线开头来命名,所以变量名不要以下划线开头;
  3. 字母大小写是有区别的,所以count、Count、COUNT绝不是一回事;
  4. 在传统的C语言用法中,变量名使用小写字母,符号常量名全部使用大写字母。

书中第二段对于内部名和外部名的描述让人看起来觉得很混乱,因为ANSI C中并没有内部名(Internal Name)和外部名(External Name)的解释,即便有多年编程经验的朋友可能也不会太在意这种问题,不过对于我们初学者来说,不弄清楚估计饭都吃不下吧。

中文版的原文是:

对于内部名而言,至少前31个字符是有效的。函数名与外部变量名包含的字符数目可能小于31个,这是因为汇编程序和加载程序可能会使用这些外部名,而语言本身是无法控制加载和汇编程序的。对于外部名,ANSI标准仅保证前6个字符的唯一性,并且不区分大小写。类似于if、else、int、float等关键字是保留给语言本身使用的,不能把他们用作变量名。所有关键字中的字符都必须小写。

英文版的原文是:

At least the first 31 characters of an internal name are significant. For function names and external variables, the number may be less than 31, because external names may be used by assemblers and loaders over which the language has no control. For external names, the standard guarantees uniqueness only for 6 characters and a single case. Keywords like if, else, int, float, etc., are reserved: you can’t use them as variable names. They must be in lower case.

Google一下才找到,原来在ISO 9899:1989的第六节中是这么说的:

The implementation shall treat at least the first 31 characters of an internal name(a macro name or an identifier that does not have external linkage) as significant. Corresponding lowercase and uppercase letters are different. The implementation may further restrict the signification of an external name(an identifier that has external linkage) to six characters and may ignore distinctions of alphabetical case for such names. Theses limitations on identifiers are all implementation-defined

可见,内部名是指不含外部链接的标示符或宏名字,而外部名是指带有外部链接的标示符。举个简单的例子,比如在file_1.c中:

int global_variable;

int main(void)
{
        int local_variable;
        extern int extern_variable;

        return 0;
}

其中extern_varialbe是在file_2.c中定义的。那么global_variable和local_variable是内部名,而extern_variable是外部名,因为只有extern_variable是在编译的时候要去链接file_2.c才能生成有效的目标代码。

而关于外部名ANSI仅保证前6个字符唯一性的问题,我们也通过例子来看下,比如我们在file_1.c中同时声明了:

extern int MyFavoriteItem;
extern int MyFavoriteThing;
extern int myfavorite;

但有些系统(似乎称为“编译器”更合理些)可能只会把它们当成6个字符的变量名写入到目标文件(object-file)中,因为它不知道如何处理比6个字符更长的变量名。所以在编译器看来,这三个变量实际上是可能被声明为:

extern int myfavo;
extern int myfavo;
extern int myfavo;

这是重复声明,一般C编译器是能捕获到这种错误,并返回一个错误信息的,也就是说编译是通不过的。

但是注意:上面这一段只是说明编译器必须能处理至少31个字符的内部名和至少6个字符的外部名,然而时至今日,当前的编译器对于外部名和内部名的长度限制已经没有差别了(C99中对外部名的长度也支持到31位了)

所以C语言中对标示符命名的规定除了上面5条之外,还应加上2条:

  1. 函数名、变量名的长度不能超过31个字符;
  2. 不能使用关键字作为变量名。

C99中规定的关键字有如下这些:

auto      break     case      char      const
continue  default   do        double
else      enum      extern    float     for
goto      if        inline    int       long
register  restrict  return    short     signed
sizeof    static    struct    switch    typedef
union     unsigned  void      volatile  while
_Bool     _Complex  _Imaginary

一个好的变量名应该是让人一眼就能看出其用途。通常局部变量一般使用较短的变量名(如i、j、k等常用于循环控制变量),而外部变量通常使用较长的名字,一般还会通过下划线“_”来分割单词(如之前的my_getline函数)。

Leave A Reply