Wenn Sie in einer bestimmten Situation eine Reihe von Zeichen haben (die natürlich mit dem Null-Zeichen enden) und unmittelbar danach an der nächsten Stelle im Speicher 0
als vorzeichenloses int speichern möchten , wie unterscheidet der Computer diese zwei?
29
pic X occurs m to n depending on v
( und die Zählung kann überall sein, nicht nur unmittelbar davor, aber das Speichern ist komplizierter.Antworten:
Das tut es nicht.
Der Zeichenkettenabschluss ist ein Byte, das alle 0 Bits enthält.
Das vorzeichenlose int besteht aus zwei oder vier Bytes (abhängig von Ihrer Umgebung), die jeweils alle 0 Bits enthalten.
Die beiden Elemente werden an verschiedenen Adressen gespeichert. Ihr kompilierter Code führt Operationen aus, die für Zeichenfolgen an der ersten Position und für nicht vorzeichenbehaftete Binärzahlen an der zweiten Position geeignet sind. (Es sei denn, Sie haben einen Fehler in Ihrem Code oder einen gefährlich cleveren Code!)
Aber alle diese Bytes sehen für die CPU gleich aus. Daten im Speicher (in den meisten derzeit üblichen Befehlssatzarchitekturen) sind keinem Typ zugeordnet. Das ist eine Abstraktion, die nur im Quellcode existiert und nur dem Compiler etwas bedeutet.
Bearbeiten hinzugefügt: Als Beispiel: Es ist durchaus möglich, auch häufig, Arithmetik mit den Bytes durchzuführen, aus denen eine Zeichenfolge besteht. Wenn Sie eine Zeichenfolge mit 8-Bit-ASCII-Zeichen haben, können Sie die Buchstaben in der Zeichenfolge zwischen Groß- und Kleinschreibung umwandeln, indem Sie 32 (dezimal) addieren oder subtrahieren. Wenn Sie in einen anderen Zeichencode übersetzen, können Sie deren Werte als Indizes in einem Array verwenden, dessen Elemente die entsprechende Bitcodierung im anderen Code bereitstellen.
Für die CPU sind die Zeichen wirklich sehr kurze ganze Zahlen. (jeweils acht Bits anstelle von 16, 32 oder 64.) Für uns Menschen sind ihre Werte zufällig mit lesbaren Zeichen verknüpft, aber die CPU hat keine Ahnung davon. Es weiß auch nichts über die "C" -Konvention von "null Byte endet eine Zeichenkette" (und wie viele in anderen Antworten und Kommentaren angemerkt haben, gibt es Programmierumgebungen, in denen diese Konvention überhaupt nicht verwendet wird). .
Natürlich gibt es in x86 / x64 einige Anweisungen, die häufig für Zeichenfolgen verwendet werden - beispielsweise das REP-Präfix -, aber Sie können sie auch für ein Array von Ganzzahlen verwenden, wenn sie das gewünschte Ergebnis erzielen.
quelle
Kurz gesagt, es gibt keinen Unterschied (außer dass ein int 2 oder 4 Bytes breit ist und ein char nur 1).
Die Sache ist, dass alle modernen Bibliotheken entweder die Null-Terminator-Technik verwenden oder die Länge eines Strings speichern. In beiden Fällen weiß das Programm / der Computer, dass es das Ende einer Zeichenfolge erreicht hat, wenn es entweder ein Nullzeichen liest oder so viele Zeichen gelesen hat, wie die Größe es vorgibt.
Probleme mit diesem Start, wenn das Null-Abschlusszeichen fehlt oder die Länge falsch ist, da das Programm beginnt, aus dem Speicher zu lesen, den es nicht sollte.
quelle
Es gibt keinen Unterschied. Maschinencode (Assembler) hat keine Variablentypen, stattdessen wird der Typ der Daten durch die Anweisung bestimmt.
Ein besseres Beispiel wäre
int
undfloat
wenn Sie 4 Bytes im Speicher haben, gibt es keine Informationen darüber, ob es einint
oder einfloat
(oder etwas ganz anderes) ist, es gibt jedoch 2 verschiedene Anweisungen für die Ganzzahladdition und die Gleitkommazahladdition, wenn also die Ganzzahladdition Befehl wird für die Daten verwendet, dann ist es eine Ganzzahl und umgekehrt.Gleiches gilt für Zeichenfolgen. Wenn Sie Code haben, der beispielsweise eine Adresse ansieht und Bytes zählt, bis ein
\0
Byte erreicht ist, können Sie sich dies als Länge einer Funktionsberechnungszeichenfolge vorstellen.Natürlich wäre das Programmieren so ein Wahnsinn, deshalb haben wir höhere Sprachen, die sich zu Maschinencode kompilieren lassen, und fast keine Programme in Assembler direkt.
quelle
Die wissenschaftliche Einzelwortantwort wäre: Metadaten.
Die Metadaten teilen dem Computer mit, ob es sich bei einigen Daten an einem bestimmten Ort um ein Int, eine Zeichenfolge, einen Programmcode oder was auch immer handelt. Diese Metadaten können Teil des Programmcodes sein (wie von Jamie Hanrahan erwähnt) oder sie können explizit irgendwo gespeichert werden.
Moderne CPUs können häufig zwischen Speicherbereichen, die Programmcode zugeordnet sind, und Datenbereichen unterscheiden (z. B. das NX-Bit https://en.wikipedia.org/wiki/NX_bit ). Manche exotische Hardware kann auch zwischen Zeichenfolgen und Zahlen unterscheiden, ja. Der übliche Fall ist jedoch, dass sich die Software um dieses Problem kümmert, entweder durch implizite Metadaten (im Code) oder explizite Metadaten (objektorientierte VMs speichern die Metadaten (Typ- / Klasseninformationen) häufig als Teil der Daten (Objekt)). .
Ein Vorteil der Nichtunterscheidung zwischen verschiedenen Datentypen besteht darin, dass einige Vorgänge sehr einfach werden. Das E / A-Subsystem muss nicht unbedingt wissen, ob es sich bei den Daten, die es gerade liest oder auf die Festplatte schreibt, tatsächlich um Programmcode, lesbaren Text oder Zahlen handelt. Es sind alles nur Teile, die durch die Maschine transportiert werden. Lassen Sie den Programmcode sich mit den Schreibproblemen befassen.
quelle
Das tut es nicht. Tun sie es!
Oder Ihren Compiler / Interpreter.
Wenn der Computer angewiesen wird, die
0
Nummer als Nummer hinzuzufügen , wird er dies tun. Wenn sie Computer sagen , das drucken Daten nach Reichweite zu stoppen0
, als "\0'
Zeichen, es wird es tun.Sprachen verfügen über Mechanismen, um den Umgang mit Daten sicherzustellen. In C haben Variablen Typen wie
int
,float
undchar
, und der Compiler generiert für jeden Datentyp die richtigen Anweisungen. Mit C können Sie jedoch Daten von einer Variablen in eine andere Variable eines anderen Typs umwandeln, wobei auch ein Zeiger als Zahl verwendet werden kann. Für den Computer sind alle Teile gleich.quelle
Ein Nullzeichen ist ein Byte und ein Int ohne Vorzeichen ist zwei Bytes.
quelle