it-swarm.com.de

Warum können Variablennamen nicht mit Zahlen beginnen?

Ich habe vor einiger Zeit mit einem neuen C++ - Entwickler gearbeitet, als er die Frage stellte: "Warum können Variablennamen nicht mit Zahlen beginnen?"

Ich konnte keine Antwort finden, es sei denn, einige Zahlen können Text enthalten (123456L, 123456U), und das wäre nicht möglich, wenn die Compiler meinen, alles mit einer gewissen Anzahl von Alpha-Zeichen wäre ein Variablenname.

War das die richtige Antwort? Gibt es noch mehr Gründe?

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

Denn dann wäre eine Ziffernfolge ein gültiger Bezeichner sowie eine gültige Zahl.

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

Denken Sie darüber nach:

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

Was ist ein 2,0? oder 42?

Hinweis, wenn Sie es nicht bekommen, bedeutet d hinter einer Zahl die Zahl, bevor es ein Doppel-Literal ist

109
Pyrolistical

Es ist jetzt eine Konvention, aber es begann als technische Anforderung.

Parser von Sprachen wie FORTRAN oder BASIC benötigten in früheren Zeiten keine Leerzeichen. Grundsätzlich sind also die folgenden identisch:

10 V1=100
20 PRINT V1

und

10V1=100
20PRINTV1

Nun nehmen wir an, dass Zahlenpräfixe erlaubt waren. Wie würdest du das interpretieren?

101V=100

wie

10 1V = 100

oder als

101 V = 100

oder als

1 01V = 100

Also wurde dies illegal gemacht.

42
Roy Dictus

Weil das Backtracking bei der lexikalischen Analyse beim Kompilieren vermieden wird. Eine Variable wie:

Apple;

der Compiler weiß sofort, dass es sich um eine Kennung handelt, wenn er den Buchstaben 'A' trifft. 

Eine Variable wie:

123Apple;

der Compiler kann erst dann entscheiden, ob es sich um eine Zahl oder eine Kennung handelt, wenn er auf "a" trifft und als Ergebnis eine Rückverfolgung erforderlich ist. 

34
Jiayang

Compiler/Parser/lexikalische Analysatoren waren für mich schon lange, aber ich denke, ich erinnere mich daran, dass es schwierig war, eindeutig zu bestimmen, ob ein numerisches Zeichen in der Kompilierungseinheit ein Literal oder einen Bezeichner darstellt.

Sprachen, in denen der Speicherplatz unbedeutend ist (wie ALGOL und das ursprüngliche FORTRAN, wenn ich mich recht erinnere), konnten aus diesem Grund keine Nummern akzeptieren, um Identifikatoren zu starten.

Dies geht weit zurück - vor speziellen Notizen, die Speicher oder numerische Basis angeben.

13
Ken Gentle

Ich stimme zu, dass es praktisch wäre, Identifikatoren mit einer Ziffer zu beginnen. Ein oder zwei Leute haben erwähnt, dass Sie diese Einschränkung umgehen können, indem Sie Ihrer Kennung einen Unterstrich voranstellen, aber das ist wirklich hässlich.

Ich denke, ein Teil des Problems kommt von Zahlenliteralen wie 0xdeadbeef, die es schwer machen, leicht zu merkende Regeln für Bezeichner zu finden, die mit einer Ziffer beginnen können. Eine Möglichkeit, dies zu tun, könnte darin bestehen, alles zuzulassen, das [A-Za-z _] + entspricht und KEIN Schlüsselwort oder Zahlenliteral ist. Das Problem ist, dass dies zu seltsamen Dingen wie 0xdeadpork führen würde, nicht aber 0xdeadbeef. Letztendlich denke ich, dass wir zu allem Fleisch fair sein sollten: P.

Als ich C zum ersten Mal lernte, erinnere ich mich, dass die Regeln für Variablennamen willkürlich und restriktiv waren. Am schlimmsten waren sie schwer zu merken, also gab ich den Versuch auf, sie zu lernen. Ich habe einfach getan, was sich richtig anfühlte, und es hat ziemlich gut funktioniert. Nun, da ich viel mehr gelernt habe, scheint es nicht so schlimm zu sein, und ich habe es endlich gelernt, es richtig zu lernen.

7
allyourcode

Dies ist wahrscheinlich eine Entscheidung, die aus mehreren Gründen getroffen wurde: Wenn Sie das Token analysieren, müssen Sie nur das erste Zeichen prüfen, um festzustellen, ob es sich um einen Bezeichner oder ein Literal handelt, und es dann zur Verarbeitung an die richtige Funktion senden. Das ist also eine Leistungsoptimierung.

Die andere Option wäre zu prüfen, ob es kein Literal ist, und die Domäne der Bezeichner als Universum abzüglich der Literale belassen. Um dies zu tun, müsstest du jeden Charakter jedes Tokens untersuchen, um zu wissen, wie man ihn klassifiziert.

Es gibt auch die stilistischen Implikationen, die Identifikatoren Mnemonics sein sollen, so dass Wörter viel einfacher zu merken sind als Zahlen. Als viele der Originalsprachen geschrieben wurden, um die Stile für die nächsten Jahrzehnte festzulegen, haben sie nicht daran gedacht, "2" durch "bis" zu ersetzen.

6
William

Wie viele Leute bemerkt haben, gibt es viel historisches Gepäck über gültige Formate für Variablennamen. Und Sprachdesigner werden immer davon beeinflusst, was sie wissen, wenn sie neue Sprachen erstellen. 

Das heißt, fast immer, wenn eine Sprache Variablennamen nicht mit Zahlen beginnen darf, weil dies die Regeln des Sprachdesigns sind. Oft liegt es daran, dass eine solche einfache Regel das Parsing und Lexing der Sprache erheblich vereinfacht. Nicht alle Sprachdesigner wissen jedoch, dass dies der wahre Grund ist. Moderne Lexer-Tools helfen, denn wenn Sie versucht haben, es als zulässig zu definieren, erhalten Sie Parsing-Konflikte.

OTOH: Wenn Ihre Sprache einen eindeutig identifizierbaren Charakter hat, um Variablennamen anzukündigen, können Sie festlegen, dass sie mit einer Zahl beginnen. Ähnliche Regelvariationen können auch verwendet werden, um Leerzeichen in Variablennamen zuzulassen. Aber die sich daraus ergebende Sprache wird wahrscheinlich keiner sehr beliebten herkömmlichen Sprache ähneln, wenn überhaupt. 

Ein Beispiel für eine relativ einfache HTML-Schablonensprache, die es erlaubt, dass Variablen mit Zahlen beginnen und Leerzeichen enthalten, finden Sie unter Qompose

4
staticsan

Variablennamen können nicht mit einer Ziffer beginnen, da dies zu folgenden Problemen führen kann:

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

was ist der Wert von c? ist 4 oder 10! 

ein anderes Beispiel:

float 5 = 25;
float b = 5.5;

ist zuerst 5 eine Zahl oder ist ein Objekt (. Operator) Ein ähnliches Problem gibt es mit Sekunde 5.

Vielleicht gibt es noch andere Gründe. Daher sollten wir am Anfang eines Variablennamens keine Ziffer verwenden.

4
sbagdat

Mit COBOL können Variablen mit einer Ziffer beginnen.

4
brad

Die Einschränkung ist willkürlich. Verschiedene Lisps lassen Symbolnamen mit Zahlen beginnen.

4
Kyle Jones

Wenn Sie Schlüsselwörter und Bezeichner mit nummerischen Zeichen beginnen ließen, konnte der Lexer (Teil des Compilers) nicht ohne weiteres zwischen dem Beginn eines numerischen Literal und einem Schlüsselwort unterscheiden, ohne dass dies komplizierter (und langsamer) wurde.

4
Nicholas Carey

Die Verwendung einer Ziffer zum Beginnen eines Variablennamens macht die Fehlerprüfung während der Kompilierung oder Interaktion viel komplizierter.

Die Verwendung von Variablennamen, die wie eine Zahl begonnen haben, würde für die Sprachdesigner wahrscheinlich große Probleme verursachen. Immer wenn ein Compiler/Interpreter bei der Quellcode-Analyse auf ein Token gestoßen ist, das mit einer Ziffer beginnt, bei der ein Variablenname erwartet wurde, müsste ein riesiger, komplizierter Satz von Regeln durchsucht werden, um festzustellen, ob das Token tatsächlich eine Variable oder ein Fehler ist . Die dem Sprachparser hinzugefügte zusätzliche Komplexität kann diese Funktion nicht rechtfertigen.

Soweit ich mich erinnern kann (ungefähr 40 Jahre), glaube ich nicht, dass ich jemals eine Sprache verwendet habe, die die Verwendung einer Ziffer für Variablennamen erlaubte. Ich bin sicher, dass dies mindestens einmal gemacht wurde. Vielleicht hat jemand hier das irgendwo gesehen.

4
mkClark

C++ kann es nicht haben, weil die Sprachdesigner es zur Regel gemacht haben. Wenn Sie Ihre eigene Sprache erstellen würden, könnten Sie dies sicherlich zulassen, aber Sie würden wahrscheinlich auf die gleichen Probleme stoßen, die sie gemacht haben, und sich entscheiden, sie nicht zuzulassen. Beispiele für Variablennamen, die Probleme verursachen würden:

0x, 2d, 5555

2
Kevin

Eines der Hauptprobleme bei der Lockerung syntaktischer Konventionen besteht darin, dass kognitive Dissonanz in den Kodierungsprozess eingeführt wird. Wie Sie über Ihren Code denken, könnte stark von der Unklarheit beeinflusst werden, die dadurch eingeführt wird.

War es nicht Dykstra, der sagte, dass der wichtigste Aspekt eines Tools seine Auswirkung auf den Benutzer ist?

2
caving

es ist für einen Compiler leicht, eine Variable anhand von ASCII für den Speicherort statt mit der Nummer zu identifizieren.

1
Vivek

Wahrscheinlich, weil es dem Menschen leichter fällt zu erkennen, ob es sich um eine Zahl oder eine Kennung handelt, und aus Tradition. Identifikatoren, die mit einer Ziffer beginnen könnten, würden die lexikalischen Scans nicht allzu komplizieren.

Nicht alle Sprachen haben Identifikatoren verboten, die mit einer Ziffer beginnen. In Forth könnten dies Zahlen sein, und kleine Ganzzahlen wurden normalerweise als Forth-Wörter (im Wesentlichen Bezeichner) definiert, da es schneller war, "2" als Routine zu lesen, um eine 2 auf den Stapel zu schieben, als "2" als Zahl zu erkennen Der Wert war 2. (Bei der Verarbeitung von Eingaben des Programmierers oder des Plattenblocks würde das Forth-System die Eingabe nach Leerzeichen aufteilen. Es würde versuchen, das Token im Wörterbuch nachzuschlagen, um zu sehen, ob es ein definiertes Wort ist, und Wenn nicht, würde es versuchen, es in eine Zahl zu übersetzen, und wenn nicht, würde es einen Fehler melden.)

1
David Thornley

Angenommen, Sie haben Symbolnamen mit Zahlen beginnen lassen. Angenommen, Sie möchten eine Variable 12345foobar benennen. Wie würden Sie das von 12345 unterscheiden? Mit einem regulären Ausdruck ist es eigentlich nicht besonders schwer. Das Problem ist eigentlich die Leistung. Ich kann nicht wirklich erklären, warum dies sehr detailliert ist, aber es läuft im Wesentlichen darauf hinaus, dass die Differenzierung von 12345foobar von 12345 eine Rückverfolgung erfordert. Dies macht den regulären Ausdruck nicht deterministisch.

Es gibt eine viel bessere Erklärung dafür hier .

1
Jason Baker

Es könnte nichts Falsches daran sein, wenn es darum geht, Variable zu deklarieren. Es gibt jedoch einige Unklarheiten, wenn versucht wird, diese Variable an anderer Stelle zu verwenden:

let 1 = "Hallo Welt!" print (1) print (1)

print ist eine generische Methode, die alle Variablentypen akzeptiert. In dieser Situation weiß der Compiler nicht, auf welche (1) der Programmierer sich bezieht: die 1 des ganzzahligen Werts oder die 1, die einen String-Wert speichert Beim Versuch, dieses mehrdeutige Zeug zu verwenden, bringen Sie einen Fehler mit Korrekturfunktion mit, wie dieser Fehler behoben werden kann, und löschen Sie diese Mehrdeutigkeit.

0
Ali Torabi

Die Variable kann vom Compiler auch während der Compile-Zeit als Wert betrachtet werden 

0
aravinth

Ursprünglich war es einfach deshalb, weil es einfacher ist, Variablennamen als Zeichenfolgen zu speichern (Sie können ihr mehr Bedeutung verleihen), obwohl Zahlen in die Zeichenfolge aufgenommen werden können, um die Bedeutung der Zeichenfolge zu verbessern oder die Verwendung des gleichen Variablennamens zu erlauben haben es als einen separaten, aber engen Sinn oder Kontext bezeichnet. Zum Beispiel würden Schleife1, Schleife2 usw. Sie immer wissen lassen, dass Sie sich in einer Schleife befanden und/oder Schleife 2 war eine Schleife innerhalb der Schleife1 . Was würden Sie als Variable bevorzugen (hat mehr Bedeutung): Adresse oder 1121298? Was ist leichter zu merken? Wenn die Sprache jedoch etwas verwendet, um darauf hinzuweisen, dass es sich nicht nur um Text oder Zahlen (wie die $ in $ -Adresse) handelt, sollte dies keinen Unterschied machen, da dies dem Compiler das sagen würde, was Folgendes ist als Variable zu behandeln (in diesem Fall) . In jedem Fall kommt es darauf an, was die Sprachdesigner als Regeln für ihre Sprache verwenden möchten.

0
cjtech

Der Compiler hat 7 Phasen wie folgt:

  1. Lexikalische Analyse
  2. Syntaxanalyse
  3. Semantische Analyse
  4. Zwischencodegenerierung
  5. Code-Optimierung
  6. Codegenerierung
  7. Symboltabelle

Rückverfolgung wird in der lexikalischen Analysephase beim Kompilieren des Codes vermieden. Bei der Variablen wie bei Apple erkennt der Compiler seine Kennung sofort, wenn er in der lexikalischen Analysephase auf das Zeichen "A" trifft. Bei einer Variablen wie 123Apple kann der Compiler jedoch nicht entscheiden, ob es eine Zahl oder ein Bezeichner ist, bis "a" angezeigt wird. In der lexikalischen Analysephase muss ein Backtracking durchgeführt werden, um festzustellen, dass es sich um eine Variable handelt. Es wird jedoch nicht vom Compiler unterstützt.

Wenn Sie das Token analysieren, müssen Sie nur das erste Zeichen prüfen, um festzustellen, ob es sich um einen Bezeichner oder ein Literal handelt, und es dann zur Verarbeitung an die richtige Funktion senden. Das ist also eine Leistungsoptimierung.

0
Harikesh

Ich denke, die einfache Antwort ist, dass es möglich ist, die Einschränkung ist sprachbasiert. In C++ und vielen anderen ist dies nicht möglich, da die Sprache dies nicht unterstützt. Es ist nicht in die Regeln eingebaut, um das zuzulassen. 

Die Frage ähnelt der Frage, warum der König nicht vier Felder gleichzeitig im Schach bewegen darf. Es ist deshalb so, weil es im Schachspiel eine illegale Bewegung ist. Kann es in einem anderen Spiel sicher sein. Es hängt nur von den Regeln ab, nach denen gespielt wird. 

0
kemiller2002

Backtracking wird in der lexikalischen Analysephase vermieden, während der Code kompiliert wird. Die Variable wie Apple; Der Compiler erkennt seine a-Kennung sofort, wenn er in der lexikalischen Analysephase auf das Zeichen 'A' trifft. Eine Variable wie 123Apple; Der Compiler kann nicht entscheiden, ob es sich um eine Zahl oder einen Bezeichner handelt, bis er ein "a" trifft und in der lexikalischen Analyse zurückgezogen werden muss, um festzustellen, dass es sich um eine Variable handelt. Es wird jedoch nicht im Compiler unterstützt.

Referenz

0
Angelin Nadar