Почему имена переменных не могут начинаться с чисел?



Я работал с новым разработчиком c++ некоторое время назад, когда он задал вопрос: "Почему имена переменных начинаются с цифры?"



Я не мог придумать ответ, за исключением того, что некоторые числа могут иметь текст в них (123456L, 123456U), и это было бы невозможно, если бы компиляторы думали, что все с некоторым количеством Альфа-символов было именем переменной.



это правильный ответ? Есть еще какие-то причины?



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

24 ответов:

потому что тогда строка цифр будет действительным идентификатором, а также действительным числом.

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

Ну подумай об этом:

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

что это? 2.0? или 42?

подсказка, если вы не получите его, d после числа означает число до того, как это двойной литерал

теперь это конвенция, но она началась как техническое требование.

в старые времена Парсеры языков, таких как FORTRAN или BASIC, не требовали использования пробелов. Таким образом, в основном, следующие идентичны:

10 V1=100
20 PRINT V1

и

10V1=100
20PRINTV1

теперь предположим, что числовые префиксы были разрешены. Как бы вы это истолковали?

101V=100

как

10 1V = 100

или

101 V = 100

или как

1 01V = 100

Итак, это было сделано незаконным.

потому что в лексическом анализе при компиляции избегается обратное отслеживание. Переменная типа:

Apple;

компилятор будет знать, что это идентификатор сразу же, когда он встречает букву "А".

однако переменная типа:

123apple;

компилятор не сможет решить, является ли это числом или идентификатором, пока он не попадет в "a", и в результате ему нужно вернуться.

компиляторы / Парсеры / лексические анализаторы были для меня давным-давно, но я думаю, что помню, что было трудно однозначно определить, является ли числовой символ в единице компиляции литералом или идентификатором.

языки, где пространство незначительно (например, ALGOL и оригинальный FORTRAN, если я правильно помню), не могли принимать числа для начала идентификаторов по этой причине.

Это происходит задолго до специальных обозначений обозначает хранилище или числовую базу.

Это, вероятно, решение, которое пришло по нескольким причинам, когда вы анализируете токен, вам нужно только посмотреть на первый символ, чтобы определить, является ли он идентификатором или литералом, а затем отправить его в правильную функцию для обработки. Так что это оптимизация производительности.

другой вариант - проверить, не является ли он литералом и оставить домен идентификаторов в качестве Юниверса минус литералы. Но для этого вам придется изучить каждый символ, каждый знак чтобы знать, как его классифицировать.

существует также стилистические последствия идентификаторы должны быть мнемоники, так что слова гораздо легче запомнить, чем цифры. Когда многие оригинальные языки были написаны, устанавливая стили в течение следующих нескольких десятилетий, они не думали о замене "2" На "to".

Я согласен, что было бы удобно, чтобы идентификаторы начинались с цифры. Один или два человека упомянули, что вы можете обойти это ограничение, добавив подчеркивание к своему идентификатору, но это действительно уродливо.

Я думаю, что часть проблемы исходит из числовых литералов, таких как 0xdeadbeef, которые затрудняют создание простых в запоминании правил для идентификаторов, которые могут начинаться с цифры. Одним из способов сделать это может быть разрешить все, что соответствует [A-Za-z_]+, что не является a ключевое слово или числовой литерал. Проблема в том, что это приведет к странным вещам, таким как 0xdeadpork, но не 0xdeadbeef. В конечном счете, я думаю, что мы должны быть справедливы ко всем мясу :P.

когда я впервые изучал C, я помню, что правила для имен переменных были произвольными и ограничительными. Хуже всего было то, что их было трудно запомнить, поэтому я бросил попытки выучить их. Я просто сделал то, что считал правильным, и это сработало довольно хорошо. Теперь, когда я узнал намного больше, это не кажется таким уж плохим, и я наконец-то научился этому правильно.

использование цифры для начала имени переменной делает проверку ошибок во время компиляции или взаимодействия намного сложнее.

разрешение использования имен переменных, которые начинались как число, вероятно, вызовет огромные проблемы для разработчиков языка. Во время синтаксического анализа исходного кода всякий раз, когда компилятор/интерпретатор сталкивался с токеном, начинающимся с цифры, где ожидалось имя переменной, ему пришлось бы искать через огромный, сложный набор правил, чтобы определить, является ли токен был действительно переменной или ошибкой. Дополнительная сложность, добавленная к синтаксическому анализатору языка, может не оправдать эту функцию.

насколько я помню (около 40 лет), я не думаю, что когда-либо использовал язык, который позволял использовать цифру для начала имен переменных. Я уверен, что это было сделано хотя бы один раз. Может быть, кто-то здесь действительно видел это где-то.

Как заметили несколько человек, существует много исторического багажа о допустимых форматах для имен переменных. И языковые дизайнеры всегда находятся под влиянием того, что они знают, когда они создают новые языки.

тем не менее, почти все время язык не позволяет именам переменных начинаться с чисел, потому что это правила дизайна языка. Часто это происходит потому, что такое простое правило значительно упрощает синтаксический анализ и лексику языка. Не все однако языковые дизайнеры знают, что это настоящая причина. Современные инструменты лексики помогают, потому что если вы попытаетесь определить его как допустимый, они дадут вам разбор конфликтов.

OTOH, если ваш язык имеет однозначно идентифицируемый символ для имен переменных herald, можно настроить его для них, чтобы начать с числа. Аналогичные варианты правил можно также использовать для разрешения пробелов в именах переменных. Но получившийся язык, скорее всего, не будет напоминать ни один популярный общепринятый языка очень много, если вообще есть.

для примера довольно простого языка шаблонов HTML, который позволяет переменным начинаться с чисел и иметь встроенные пробелы, посмотрите на Qompose.

потому что, если вы разрешили ключевое слово и идентификатор начинать с числовых символов, лексер (часть компилятора) не мог легко различать начало числового литерала и ключевое слово, не становясь намного сложнее (и медленнее).

ограничение является произвольным. Различные шепелявит разрешение имен символов начнем с цифр.

имена переменных не могут начинаться с цифры, потому что это может вызвать некоторые проблемы, как показано ниже:

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

что такое значение c? это 4 или 10!

еще пример:

float 5 = 25;
float b = 5.5;

первые 5 число, или объект (. оператор) Есть аналогичная проблема со вторым 5.

возможно, есть и другие причины. Таким образом, мы не должны использовать какую-либо цифру в начале имени переменной.

COBOL позволяет переменным начинаться с цифры.

в C++ не может иметь его, потому что разработчики языка сделали его правилом. Если бы вы создали свой собственный язык, вы, конечно, могли бы позволить это, но вы, вероятно, столкнетесь с теми же проблемами, что и они, и решите не позволять этого. Примеры имен переменных, которые могут вызвать проблемы:

0x, 2d, 5555

разве не Дикстра сказал ,что"самый важный аспект любого инструмента-это его влияние на пользователя"?

наверное, потому, что это делает его легче для человека, чтобы сказать, является ли это число или идентификатор, и из-за традиции. Наличие идентификаторов, которые могут начинаться с цифры, не сильно усложнит лексическое сканирование.

не все языки имеют Запрещенные идентификаторы, начинающиеся с цифры. В Forth они могли быть числами, а маленькие целые числа обычно определялись как слова Forth (по существу идентификаторы), так как было быстрее читать "2" Как процедуру, чтобы нажать 2 на стек, чем признать "2" как число, значение которого было 2. (При обработке входных данных от программиста или дискового блока, четвертая система разделила бы входные данные в соответствии с пробелами. Он попытается найти токен в словаре, чтобы увидеть, было ли это определенное слово, и если нет, попытается перевести его в число, а если нет, то отметит ошибку.)

предположим, что вы разрешили имена символов начинаться с цифр. Теперь предположим, что вы хотите назвать переменную 12345foobar. Как бы вы отличили это от 12345? На самом деле это не так уж сложно сделать с регулярным выражением. Проблема на самом деле заключается в производительности. Я не могу объяснить, почему это очень подробно, но это по существу сводится к тому, что дифференциация 12345foobar от 12345 требует возврата. Это делает регулярное выражение недетерминированный.

есть гораздо лучшее объяснение этого здесь.

компилятору легко идентифицировать переменную, используя ASCII в ячейке памяти, а не число .

Я думаю, что простой ответ заключается в том, что он может, ограничение основано на языке. В C++ и многих других это невозможно, потому что язык не поддерживает его. Это не встроено в правила, чтобы позволить это.

вопрос сродни вопросу, Почему король не может переместить четыре пространства за один раз в шахматах? Это потому, что в шахматах это незаконный ход. Может он в другой игре уверен. Это просто зависит от правил, по которым играют.

первоначально это было просто потому, что легче запомнить (вы можете дать ему больше смысла) имена переменных в виде строк, а не чисел, хотя числа могут быть включены в строку, чтобы улучшить значение строки или разрешить использование одного и того же имени переменной, но обозначить его как имеющее отдельное, но близкое значение или контекст. Например, loop1, loop2 и т. д. Всегда сообщали бы вам, что вы находитесь в цикле и/или цикл 2 был циклом внутри loop1. Что бы вы предпочли (с больше значения) как переменная: адрес или 1121298? Что легче запомнить? Однако, если язык использует что-то, чтобы обозначить, что это не просто текст или числа (например, $ in $address), это действительно не должно иметь значения, так как это сообщило бы компилятору, что следующее должно рассматриваться как переменная (в этом случае). В любом случае это сводится к тому, что языковые дизайнеры хотят использовать в качестве правил для своего языка.

переменная может рассматриваться как ценность и во время компиляции компилятором таким образом, значение может вызывать значение снова и снова рекурсивно

отступление избегается на этапе лексического анализа при компиляции фрагмента кода. Переменная, такая как Apple; , компилятор сразу узнает свой идентификатор, когда он встретит символ буквы " A " на этапе лексического анализа. Тем не менее , переменная, такая как 123apple;, компилятор не сможет решить, является ли ее число или идентификатор, пока он не попадет в "a", и ему нужно вернуться в фазу лексического анализа, чтобы определить, что это переменная. Но это не поддерживается в компилятор.

ссылка

компилятор имеет 7 фазу следующим образом:

  1. лексический анализ
  2. Анализ Синтаксис
  3. Семантический Анализ
  4. Генерация Промежуточного Кода
  5. Оптимизация Кода
  6. Генерация Кода
  7. Таблица Символов

откат можно избежать на этапе лексического анализа при компиляции кусок кода. Переменная, как Apple, компилятор будет знать его идентификатор сразу же, когда он встречается буква ' A ' символ на этапе лексического анализа. Тем не менее, переменная, такая как 123apple, компилятор не сможет решить, является ли ее число или идентификатор, пока он не попадет в "a", и ему нужно вернуться в фазу лексического анализа, чтобы определить, что это переменная. Но он не поддерживается в компиляторе.

когда вы анализируете токен, вам нужно только посмотреть на первый символ, чтобы определить, является ли он идентификатором или литералом, а затем отправить его в правильную функцию для обработка. Так что это оптимизация производительности.

там не может быть ничего плохого с ним, когда приходит в объявлении переменной.но есть некоторая двусмысленность, когда он пытается использовать эту переменную где-то еще вроде этого :

пусть 1 = "Привет, мир!" печати(1) print (1)

печать-это универсальный метод, который принимает все типы переменных. поэтому в этой ситуации компилятор не знает, к какому (1) программисту относится : к 1 целочисленного значения или к 1, хранящему строковое значение. может лучше для компилятора в этой ситуации позволяет определить что-то вроде этого, но при попытке использовать этот неоднозначный материал, принесите ошибку с возможностью исправления, чтобы исправить эту ошибку и очистить эту двусмысленность.

Comments

    Ничего не найдено.