Некоторое время назад я работал с новым разработчиком C ++, когда он задал вопрос: «Почему имена переменных не могут начинаться с цифр?»
Я не мог придумать ответ, за исключением того, что некоторые числа могут содержать текст (123456L, 123456U), и это было бы невозможно, если бы компиляторы думали, что все с некоторым количеством буквенных символов является именем переменной.
Это был правильный ответ? Есть еще причины?
string 2BeOrNot2Be = "that is the question"; // Why won't this compile?
0
которое помещает 0 в стек. другой -0=
проверяет, находится ли в стеке 0.Ответы:
Потому что тогда строка цифр будет как действительным идентификатором, так и действительным числом.
источник
A
-F
и заканчивалисьh
. Подстегнул меня в первый раз, когда я попытался определить лейбл, указывающий на музыкальные данные для изобретения Баха из двух частей № 13 (логическое имя?Bach
).Хорошо подумайте об этом:
Что такое? 2,0? или 42?
Подсказка: если вы не поняли, d после числа означает, что число перед ним является двойным литералом
источник
d
не является допустимым плавающим литеральным суффиксом в C ++. Плавающие литералы по умолчанию являются двойными , вы можете использоватьf
или,l
если вам нужен плавающий или длинный двойной литерал.Сейчас это соглашение, но началось оно как техническое требование.
Раньше парсеры таких языков, как FORTRAN или BASIC не требовали использования пробелов. Итак, в основном следующие идентичны:
и
Теперь предположим, что числовые префиксы разрешены. Как бы вы это истолковали?
так как
или как
или как
Итак, это было объявлено незаконным.
источник
DO 10 I=1,50
может быть неоднозначно проанализирован какDO1 0I=1,50
[кстати, если использовать точку вместо запятой, оператор становится присваиванием переменная с плавающей запятой с именемDO10I
.Потому что при лексическом анализе во время компиляции исключается возврат с возвратом. Переменная как:
компилятор сразу узнает, что это идентификатор, когда он встретит букву «А».
Однако переменная вроде:
компилятор не сможет решить, является ли это числом или идентификатором, пока он не достигнет 'a', и в результате ему потребуется возврат с возвратом.
источник
Компиляторы / парсеры / лексические анализаторы были для меня давным-давно, но я думаю, что помню, как было трудно однозначно определить, представляет ли числовой символ в модуле компиляции литерал или идентификатор.
Языки, где пробел незначителен (например, ALGOL и оригинальный FORTRAN, если я правильно помню), не могут принимать числа для начала идентификаторов по этой причине.
Это восходит к прошлому - до специальных обозначений для обозначения памяти или числовой базы.
источник
Я согласен, что было бы удобно разрешить идентификаторам начинаться с цифры. Один или два человека упомянули, что вы можете обойти это ограничение, добавив знак подчеркивания к своему идентификатору, но это действительно некрасиво.
Я думаю, что отчасти проблема связана с числовыми литералами, такими как 0xdeadbeef, которые затрудняют создание легко запоминающихся правил для идентификаторов, которые могут начинаться с цифры. Один из способов сделать это - разрешить все, что соответствует [A-Za-z _] +, но НЕ является ключевым словом или числовым литералом. Проблема в том, что это приведет к тому, что будут разрешены такие странные вещи, как 0xdeadpork, но не 0xdeadbeef. В конечном счете, я считаю, что мы должны быть справедливыми по отношению ко всему мясу: P.
Помню, когда я впервые изучал C, я чувствовал, что правила для имен переменных были произвольными и ограничительными. Хуже всего то, что их было трудно запомнить, поэтому я отказался от попыток их выучить. Я просто делал то, что считал правильным, и это сработало очень хорошо. Теперь, когда я узнал намного больше, это не кажется таким уж плохим, и я наконец нашел время, чтобы выучить это правильно.
источник
Вероятно, это решение было принято по нескольким причинам: когда вы анализируете токен, вам нужно только взглянуть на первый символ, чтобы определить, является ли он идентификатором или литералом, а затем отправить его правильной функции для обработки. Так что это оптимизация производительности.
Другой вариант - проверить, не является ли это литералом, и оставить доменом идентификаторов вселенную без литералов. Но чтобы сделать это, вам нужно изучить каждый символ каждого токена, чтобы узнать, как его классифицировать.
Существует также стилистическое значение, идентификаторы которого должны быть мнемоническими, поэтому слова гораздо легче запомнить, чем числа. Когда писалось множество оригинальных языков, задающих стили на следующие несколько десятилетий, они не думали о замене «2» на «to».
источник
Имена переменных не могут начинаться с цифры, потому что это может вызвать некоторые проблемы, как показано ниже:
каково значение c? равно 4 или 10!
другой пример:
- это первая цифра 5 или объект (оператор.) Аналогичная проблема возникает и со вторым числом 5.
Может быть, есть другие причины. Итак, мы не должны использовать какие-либо цифры в начале имени переменной.
источник
Использование цифры в начале имени переменной значительно усложняет проверку ошибок во время компиляции или интерпретации.
Разрешение использования имен переменных, начинающихся с числа, вероятно, вызовет огромные проблемы для разработчиков языка. Во время синтаксического анализа исходного кода, всякий раз, когда компилятор / интерпретатор обнаруживал токен, начинающийся с цифры, где ожидалось имя переменной, ему приходилось искать по огромному, сложному набору правил, чтобы определить, действительно ли токен является переменной или ошибкой. , Дополнительная сложность, добавленная к синтаксическому анализатору языка, может не оправдать эту функцию.
Насколько я себя помню (около 40 лет), я не думаю, что когда-либо использовал язык, который позволял бы использовать цифру в начале имен переменных. Я уверен, что это было сделано хоть раз. Может, кто-то здесь действительно где-то видел это.
источник
Как заметили несколько человек, существует много исторического багажа относительно допустимых форматов для имен переменных. А языковые дизайнеры всегда зависят от того, что они знают, когда создают новые языки.
Тем не менее, почти всегда язык не позволяет именам переменных начинаться с цифр, потому что это правила дизайна языка. Часто это потому, что такое простое правило значительно упрощает синтаксический анализ и лексирование языка. Однако не все разработчики языков знают, что это настоящая причина. Современные лексические инструменты помогают, потому что, если вы попытаетесь определить его как допустимый, они вызовут конфликты при разборе.
OTOH, если в вашем языке есть однозначно идентифицируемый символ для обозначения имен переменных, можно настроить их так, чтобы они начинались с числа. Подобные варианты правил также могут использоваться для разрешения пробелов в именах переменных. Но полученный язык, скорее всего, не будет сильно напоминать какой-либо популярный традиционный язык, если вообще будет.
В качестве примера довольно простого языка шаблонов HTML, который позволяет переменным начинаться с чисел и иметь встроенные пробелы, посмотрите Qompose .
источник
Потому что, если вы разрешили ключевому слову и идентификатору начинаться с числовых символов, лексер (часть компилятора) не мог легко отличить начало числового литерала от ключевого слова, не становясь намного сложнее (и медленнее).
источник
Ограничение произвольное. Различные Лиспы позволяют именам символов начинаться с цифр.
источник
COBOL позволяет переменным начинаться с цифры.
источник
C ++ не может иметь этого, потому что разработчики языка сделали это правилом. Если бы вы создали свой собственный язык, вы, конечно, могли бы разрешить это, но вы, вероятно, столкнетесь с теми же проблемами, что и они, и решите не позволять этого. Примеры имен переменных, которые могут вызвать проблемы:
0x, 2д, 5555
источник
Одна из ключевых проблем ослабления синтаксических соглашений заключается в том, что это вносит когнитивный диссонанс в процесс кодирования. На то, как вы думаете о своем коде, может сильно повлиять отсутствие ясности, которое он привнесет.
Разве не Дайкстра сказал, что «самый важный аспект любого инструмента - это его влияние на пользователя»?
источник
Вероятно, потому, что так человеку легче определить, число это или идентификатор, и в силу традиции. Наличие идентификаторов, которые могут начинаться с цифры, не сильно усложнит лексическое сканирование.
Не во всех языках есть запрещенные идентификаторы, начинающиеся с цифры. В Forth они могли быть числами, а маленькие целые числа обычно определялись как слова Forth (по сути, идентификаторы), поскольку было быстрее читать «2» как процедуру для помещения 2 в стек, чем распознавать «2» как число. значение которого равнялось 2. (При обработке ввода от программатора или блока диска система Forth разделяла ввод по пробелам. Она пыталась найти токен в словаре, чтобы узнать, было ли это определенным словом, и в противном случае попытался бы преобразовать его в число, а в противном случае - пометил бы ошибку.)
источник
Предположим, вы разрешили имена символов начинаться с цифр. Теперь предположим, что вы хотите назвать переменную 12345foobar. Как бы вы отличили это от 12345? На самом деле это не так уж сложно сделать с регулярным выражением. Проблема на самом деле заключается в производительности. Я не могу объяснить, почему это так подробно, но, по сути, все сводится к тому факту, что для отличия 12345foobar от 12345 требуется возврат. Это делает регулярное выражение недетерминированным.
Есть гораздо лучшее объяснение этому здесь .
источник
ifq
или,doublez
но неif
илиdouble
? Основная проблема с разрешением идентификаторам начинаться с цифр заключается в том, что существуют существующие формы шестнадцатеричных литералов и чисел с плавающей запятой, которые полностью состоят из буквенно-цифровых символов (языки будут использовать что-то вроде $ 1234 или h'1234 вместо 0x1234 и требовать такие числа, как 1E23, чтобы включить точку, можно избежать этой проблемы). Обратите внимание, что попытки синтаксического разбора C уже могут быть сбиты такими вещами, как0x12E+5
.компилятору легко идентифицировать переменную, используя ASCII в ячейке памяти, а не по номеру.
источник
Компилятор имеет следующие 7 этапов:
На этапе лексического анализа во время компиляции фрагмента кода исключается возврат с возвратом. Переменная, такая как Apple, компилятор узнает ее идентификатор сразу, когда он встретит букву «A» на этапе лексического анализа. Однако для такой переменной, как 123apple, компилятор не сможет решить, является ли это числом или идентификатором, пока он не достигнет «a», и ему потребуется возврат с возвратом, чтобы перейти на фазу лексического анализа, чтобы определить, что это переменная. Но компилятором это не поддерживается.
Когда вы разбираете токен, вам нужно только посмотреть на первый символ, чтобы определить, является ли он идентификатором или литералом, а затем отправить его в нужную функцию для обработки. Так что это оптимизация производительности.
источник
Я думаю, простой ответ - может, ограничение основано на языке. В C ++ и многих других это невозможно, потому что язык не поддерживает это. Это не разрешено правилами.
Этот вопрос похож на вопрос, почему король не может перемещать четыре клетки за раз в шахматах? Это потому, что в шахматах это недопустимый ход. Может это в другой игре точно. Это просто зависит от правил игры.
источник
Первоначально это было просто потому, что легче запомнить (можно придать ему больше смысла) имена переменных в виде строк, а не чисел, хотя числа могут быть включены в строку, чтобы улучшить смысл строки или разрешить использование того же имени переменной, но обозначить его как имеющий отдельное, но близкое значение или контекст. Например, loop1, loop2 и т. Д. Всегда будут сообщать вам, что вы находитесь в цикле и / или цикл 2 был циклом внутри цикла loop1. Что бы вы предпочли (имеет большее значение) в качестве переменной: адрес или 1121298? Что легче запомнить? Однако, если в языке используется что-то для обозначения того, что это не просто текст или числа (например, $ в адресе $), это действительно не должно иметь значения, поскольку это сообщит компилятору, что то, что следует ниже, следует рассматривать как переменную ( в таком случае).
источник
Переменная может рассматриваться как значение также во время компиляции компилятором, поэтому значение может вызывать значение снова и снова рекурсивно.
источник
На этапе лексического анализа при компиляции фрагмента кода исключается обратный поиск . Переменная типа Apple; , компилятор узнает свой идентификатор сразу же, когда он встретит букву «A» на этапе лексического анализа. Однако такая переменная, как 123apple; , компилятор не сможет решить, является ли это числом или идентификатором, пока он не достигнет 'a' и ему не потребуется обратный путь, чтобы перейти на фазу лексического анализа, чтобы определить, что это переменная. Но в компиляторе это не поддерживается.
Ссылка
источник
Когда дело доходит до объявления переменной, в этом нет ничего плохого, но есть некоторая двусмысленность, когда он пытается использовать эту переменную где-то еще, например:
let 1 = "Привет, мир!" печать (1) печать (1)
print - это общий метод, который принимает все типы переменных. поэтому в этой ситуации компилятор не знает, к какому (1) программисту относится: к 1 целочисленного значения или 1, хранящему строковое значение. может быть, лучше для компилятора в этой ситуации позволить определить что-то подобное, но при попытке использовать этот неоднозначный материал выведите ошибку с возможностью исправления, чтобы исправить эту ошибку и устранить эту неоднозначность.
источник