为什么variables名称不能以数字开头?

我刚刚和一个新的c ++开发人员一起问了一个问题:“为什么variables名称不能以数字开头?

我不能拿出答案,除了一些数字可以有文字(123456L,123456U),如果编译器认为所有的字母字符都是variables名称,那么这是不可能的。

这是正确的答案吗? 还有更多的理由吗?

string 2BeOrNot2Be = "that is the question"; // Why won't this compile? 

因为那么一串数字将是一个有效的标识符以及一个有效的数字。

 int 17 = 497; int 42 = 6 * 9; String 1111 = "Totally text"; 

那么想想这个:

 int 2d = 42; double a = 2d; 

什么是? 2.0? 还是42?

提示,如果你没有得到它,d之后的数字意味着数字是一个双重字面

现在这是一个惯例,但是它是作为一个技术要求而开始的。

在过去,诸如FORTRAN或BASIC语言的parsing器不需要使用空格。 所以,基本上,以下是相同的:

 10 V1=100 20 PRINT V1 

 10V1=100 20PRINTV1 

现在假设允许使用数字前缀。 你怎么解释这个?

 101V=100 

 10 1V = 100 

或如

 101 V = 100 

或如

 1 01V = 100 

所以,这是非法的。

因为在编译时避免了词法分析中的回溯。 一个variables如:

 Apple; 

当它遇到字母“A”时,编译器会马上知道它是一个标识符。

然而,像这样的variables:

 123apple; 

编译器将不能决定它是否是一个数字或标识符,直到它碰到“a”,并且因此需要回溯。

编译器/parsing器/词法分析器对我来说是很久以前的,但是我想我记得在编译单元中的数字字符是表示文字还是标识符的问题上存在困难。

空间不重要的语言(如果我没有记错,就像ALGOL和原始的FORTRAN)不能接受数字开始标识符的原因。

这回退 – 在用特殊符号表示存储或数字库之前。

这可能是由于以下几个原因造成的:当parsing令牌时,只需要查看第一个字符,以确定它是标识符还是文字,然后将其发送到正确的函数进行处理。 所以这是一个性能优化。

另一个select是检查它是不是一个文字,并把标识符的域名是宇宙减文字。 但要做到这一点,你必须检查每个标记的每个字符,以了解如何对其进行分类。

还有文体暗示标识符应该是助记符,所以文字比数字更容易记住。 当大量的原始语言被写入设置未来几十年的风格时,他们并没有考虑用“2”来代替“to”。

我同意允许标识符以一个数字开始是很方便的。 有一两个人提到,你可以通过在你的标识符前加一个下划线来解决这个限制,但这真的很难看。

我认为问题的一部分来自数字文字,如0xdeadbeef,这使得很难想出容易记住规则的标识符,可以以数字开头。 一种方法可能是允许任何与[A-Za-z _] +不匹配的关键字或数字文字匹配。 问题是会导致奇怪的事情,如允许0xdeadpork,但不是0xdeadbeef。 最终,我认为我们应该对所有肉类公平:P。

当我第一次学习C时,我记得感觉variables名的规则是任意的和限制性的。 最糟糕的是,他们很难记住,所以我放弃了试图学习它们。 我只是做了正确的事,而且工作得很好。 现在我已经学到了很多东西,看起来并不是那么糟糕,而且我终于明白了。

使用数字开始variables名称在编译或插入过程中进行错误检查要复杂得多。

允许使用以数字开头的variables名可能会给语言devise者带来很大的问题。 在源代码parsing期间,无论何时编译器/解释器遇到一个以数字开头的令牌(其中包含variables名称),都必须search庞大复杂的规则集以确定令牌是否真的是variables或错误。 添加到语言parsing器中的附加复杂性可能无法certificate此function。

据我所知(大约40年),我不认为我曾经使用过一种允许使用数字开始variables名的语言。 我确信至less这样做了一次。 也许,这里有人真的看到了这个地方。

正如几个人已经注意到的,关于variables名称的有效格式有很多历史包袱。 语言devise者总是受到他们创build新语言时所了解的东西的影响。

也就是说,几乎所有的时候,语言不允许variables名以数字开头,因为这些是语言devise的规则。 通常这是因为这样一个简单的规则使语言的parsing和阅读变得非常容易。 不是所有的语言devise师都知道这是真正的原因。 现代lexing工具的帮助,因为如果你试图将其定义为允许,他们会给你parsing冲突。

OTOH,如果你的语言有一个唯一可识别的字符来预告variables名,那么可以为它们设置一个数字。 类似的规则变化也可以用来允许variables名称中的空格。 但是,由此产生的语言很可能不会像任何stream行的常规语言一样。

对于一个非常简单的HTML模板语言的例子,它确实允许variables以数字开头并且有embedded空格,查看Qompose 。

因为如果你允许关键字和标识符以数字字符开始,词法分析器(编译器的一部分)不能很容易区分数字文字和关键字的开头,而不会变得更复杂(和更慢)。

variables名称不能以数字开头,因为它可能会导致一些问题,如下所示:

 int a = 2; int 2 = 5; int c = 2 * a; 

c的价值是什么? 是4,还是10!

另一个例子:

 float 5 = 25; float b = 5.5; 

是前5个数字,还是一个对象(。运算符)第二个5有个类似的问题。

也许,还有其他一些原因。 所以,我们不应该在variables名的beginnig中使用任何数字。

限制是任意的。 各种Lisp允许符号名称以数字开头。

C ++不能这样做,因为语言devise者已经把它作为一个规则。 如果你要创build自己的语言,你当然可以允许,但是你可能遇到同样的问题,并决定不允许。 会导致问题的variables名称的示例:

0x,2d,5555

放松句法习惯的关键问题之一是将认知失调引入编码过程。 如何考虑你的代码可能会受到这种引入不够清晰的深刻影响。

是不是Dykstra说“任何工具的最重要的方面是对用户的影响”?

COBOL允许variables以数字开头。

可能是因为它使得人类更容易辨别它是一个数字还是一个标识符,也因为传统。 具有可以以数字开头的标识符不会使词汇扫描复杂化太多。

并非所有的语言都有以数字开头的禁止标识符。 在第四,它们可以是数字,而小整数通常被定义为第四个字(本质上是标识符),因为读“2”作为例程将2推到栈上比识别“2”更快其值为2.(在处理来自程序员或磁盘块的input时,Forth系统将根据空格分割input,它将尝试在字典中查找标记以查看它是否是定义的字,并且如果不是会试图把它翻译成一个数字,如果不是会标记错误。)

假设您确实允许符号名称以数字开头。 现在假设你想命名一个variables12345foobar。 你如何区分12345呢? 用正则expression式实际上并不难。 问题其实就是performance的问题之一。 我无法真正解释为什么这是非常详细的,但实质上归结为区分12345foobar从12345需要回溯。 这使正则expression式不确定。

这里有更好的解释。

编译器很容易在内存位置而不是数字上使用ASCII来识别variables。

我觉得简单的答案是可以的,限制是基于语言的。 在C + +和其他许多人不能因为语言不支持它。 这不是build立在规则允许的。

这个问题类似于问国王为什么不能在国际象棋中一次移动四个空格? 这是因为在国际象棋这是一个非法的举动。 可以在另一场比赛肯定。 这取决于正在播放的规则。

原来,这只是因为它更容易记住(可以赋予它更多的含义)variables名称作为string而不是数字,尽pipe数字可以包含在string中以增强string的含义或允许使用相同的variables名称,但是它被指定为具有单独的,但接近的含义或上下文。 例如loop1,loop2等总是让你知道你在一个循环和/或循环2是loop1内的一个循环。 你更喜欢哪个(有更多的含义)作为一个variables:地址或1121298? 哪个更容易记住? 但是,如果语言使用某些东西来表示它不只是文本或数字(例如$ in $地址),它实际上不应该有所作为,因为它会告诉编译器,接下来将被视为一个variables(在这种情况下)。 无论如何,这归结于语言devise者想要用作语言规则的东西。

编译器在编译期间也可以将该variables视为一个值,因此该值可以recursion地调用该值