2013-09-04 5 views
14
signiert

Noch einmal lehre ich eine Klasse, wo ich Studenten Fragen über C beantworten. Hier ist eine, ich weiß nicht die Antwort auf: Gab es eine Begründung hinter der Annahme signed als Standardmodifikator für C? Man hätte gedacht, unsigned wäre die natürliche Wahl. War das wirklich eine Designentscheidung?als Standard in C

+3

Die "Begründung" selbst ist nicht ganz korrekt. Für ein einfaches "Char" ist es nicht immer "signiert". –

+0

Warum wäre unsigned int natürlicher? Ich denke, die meisten Probleme der realen Welt betreffen sowohl positive als auch negative Werte. – jxh

+0

@jxh Genauer gesagt, die meisten Probleme der realen Welt beschäftigen sich mit _small_ Zahlen - das heißt, Zahlen relativ nahe 0. Ich denke, dass die meisten Leute in den meisten Fällen viel wahrscheinlicher brauchen, Zahlen unter (oder mindestens nahe) 0 dann sind sie um Zahlen größer als (oder sogar in der Nähe von) MAX_INT zu benötigen. Mit Vorzeichen versehene Zahlen halten die obere und untere Grenze so weit wie möglich von den am häufigsten verwendeten Zahlen entfernt. –

Antwort

15

In Bezug auf die Standard (da Ihre Frage als solche markiert ist), signed als Standard markiert wurde, weil das ist, wie es mit den C-Implementierungen war die die Standard vor kam.

Das ursprüngliche ANSI/ISO-Standardmandat bestand darin, bestehende Praktiken zu kodifizieren, anstatt eine neue Sprache zu erstellen. Daher ist das Verhalten der Vornorm Implementierungen war der wichtigste Faktor, gemäß dem Grundprinzip Dokument:

Die ursprüngliche X3J11 Charta eindeutig gemeinsame bestehende Praxis beauftragt kodifiziert und die C89 Ausschuß hielt an Präzedenzfall, wo das war klar und eindeutig. Die große Mehrheit der von C89 definierten Sprache entsprach genau der in Anhang A der ersten Ausgabe von The C Programmiersprache von Brian Kernighan und Dennis Ritchie definierten Sprache und wurde in fast allen C-Übersetzern dieser Zeit implementiert . (Dieses Dokument wird im folgenden als K & R.)

Wenn Sie suchen die Vornorm-Implementierungen, um herauszufinden, warum signed bevorzugt, werden Sie wahrscheinlich in die Architektur des PDP suchen n Maschinen, für die ursprünglich UNIX und C entwickelt wurden.

Die History of C Seite zeigt, dass unsigned tatsächlich eine relative Nachzügler der Sprache, war irgendwann in der Mitte der 70er Jahre mit:

Während 1973-1980, die Sprache ein wenig gewachsen: die Art Struktur gewonnen unsigned, Lange, Vereinigungs- und Aufzählungstypen und Strukturen wurden zu fast erstklassigen Objekten (es fehlte nur eine Notation für Literale).

+0

Hah. Das ist interessant. Ich lehne mich dieser Antwort zu, aber beachte, dass es immer noch die Frage aufwirft: Warum wurden frühere C-Implementierungen als Standard "signiert"? –

+2

@Dervin, warum nicht? 'signed' Typ eignet sich sowohl für positive als auch für negative Werte, die im täglichen Leben verwendet werden. –

+0

@Eric, Richtig, es war nur, dass ich dachte, die Modifikatoren kämen zur selben Zeit zustande (was ich falsch annehmen sollte), also wäre ich in der Phase des Sprachdesigns, hätte Char ohne Unterschrift gemacht und den Programmierer gebeten Sag mir explizit, dass er es anders wollte. Geschichte ist so interessant! –

0

Die Standard-Signedness von char ist nicht durch die Sprache definiert. Es ist durch die Implementierung definiert. Einige CPUs sind natürlicher signiert und andere sind natürlich nicht signiert.

+0

was meinst du "natürlich" signiert? –

+0

@DervinThunk: Die Natürlichkeit der Anweisungen zum Erweitern einer 8-Bit-Menge auf 16-Bit oder größer haben bestimmte Annahmen eingebaut, vor allem CPUs vor etwa 1985 oder so. Um ein Zeichen in einem Int in der * unnatürlichen * Richtung zu fördern, bedarf es zusätzlicher Anweisungen, um es zu machen. Die * natürliche * Richtung erfordert nur eine einzige Anweisung. – wallyk

+0

@wallyk, Sind Sie sicher, dass der Standard die Signedness von plain 'int' nicht vorschreibt? Ich erinnere mich, dass der Standard den kleinsten Wertebereich vorgibt, der durch "int" repräsentiert werden kann. Siehe http://stackoverflow.com/questions/6155784/range-of-values-in-c-int-and-long-32-64-bits –

3

Nach The Development of the C Language, der Begriff der unsigned war eine Erweiterung der Sprache, wenn Merkmale zwischen 1973 bis es werden zugegeben und 1980. Obwohl es nicht ausdrücklich erwähnt, die Erzählung schlägt vor, es erst 1977 eingeführt wurde (siehe Übertragbarkeit, Absatz 3).

So war die Standardsetzung zu signed aufgrund der Tatsache, dass die Sprache zunächst nur signierte Typen hatte.

5

Es geht hauptsächlich um Abwärtskompatibilität und Cs Abstieg von früheren Sprachen, die nicht einfach sowohl vorzeichenbehaftete als auch vorzeichenlose Ganzzahlen unterstützen können.

C wurde von einer älteren Sprache namens B abgeleitet, die von einer noch älteren Sprache namens BCPL (eine vereinfachte Version von CPL) abgeleitet wurde.

BCPL war eine weitgehend untypisierte Sprache.Eine Variablendeklaration hat den Typ eines Objekts nicht angegeben; vielmehr würde eine Operation für eine gegebene Variable sie so behandeln, als ob sie von einem bestimmten Typ wäre.

Die BCPL Betreiber +, -, *, / und REM behandelt ihre Operanden als unterzeichnet ganzen Zahlen und integer Ergebnissen geführt.

Wenn BCPL vorzeichenlose Ganzzahlen unterstützt hätte, dann hätte es entweder eine andere Gruppe von Operatoren mit nicht signierten Operanden oder gar keine negativen Zahlen geben können. (Beachten Sie, dass BCPL keinen Fließkommawert unterstützt.)

Die Syntax von B war von BCPLs (und näher zu Cs) ziemlich verschieden, aber sie behielt viel von der gleichen Semantik bei. Insbesondere Variablen und Funktionen waren standardmäßig vom Integer-Typ - und es gab kein unsigned Schlüsselwort.

Frühes C, basierend auf B, hatte auch kein unsigned Schlüsselwort. Es hatte nur vier grundlegende numerische Typen: char, int, float und double. (unsigned wurde hinzugefügt, zusammen mit long, , und enum, einige Zeit zwischen 1973 und 1980.) Angesichts der schwach typisierten Natur der Sprache verwendeten Programmierer manchmal Zeiger, wenn sie vorzeichenlose Arithmetik benötigten. Das Merkmal, dass eine Entität ohne deklarierten Typ implizit vom Typ int ist, wurde in C beibehalten, bis der ISO-Standard 1999 schließlich die "implizite int" -Regel entfernte.

Darüber hinaus neigen vorzeichenbehaftete Integer-Typen eher dazu nützlich als unsigned Typen. Die Möglichkeit, negative Werte darzustellen, kann äußerst komfortabel sein. Bei der typischen Wraparound-Semantik kann ein Fehler in einer unsignierten Subtraktion von zwei kleinen Werten einen großen positiven Wert ergeben (3 - 4 == 65535 zum Beispiel für einen vorzeichenlosen 16-Bit-Typ). Selbst in der Systemprogrammierdomäne, die das Hauptziel aller dieser Sprachen ist, ist es manchmal notwendig, negative Werte darzustellen (zum Beispiel eine Änderung in einer bestimmten Menge).

Referenzen:

0

unsigned Semantik sind garantiert einfacher zu sein: modulo base-2 n ohne Ausnahmen. Aber machen Sie keine Vermutung darüber, was n ist: Die Größe des Bereichs muss nicht mit der des entsprechenden signierten Typs übereinstimmen.

Die einzige Voraussetzung ist, dass alle positiv signierten Werte auch durch den entsprechenden vorzeichenlosen Typ dargestellt werden können.

Eine gültige Implementierung von unsigned wäre, vorzeichenbehaftete Arithmetik mit zwei Vorzeichen zu verwenden und das Vorzeichenbit nach jeder Operation auf Null zu setzen.Dies wird im wirklichen Leben wahrscheinlich nicht auftauchen, aber Maschinen mit Nicht-Zwei-Komplement-Arithmetik können mehr Schwierigkeiten haben, die negative Zahlenlogik zu umgehen.

In der Praxis sind negative Zahlen ein wesentliches Merkmal jeder Hardwareplattform, aber die Fähigkeit, ein gesamtes Register als eine positive Zahl zu behandeln, ist nur ein Icing auf dem Kuchen. C ist so konzipiert, dass es sich eng um die effizientesten Teile der Hardware wickelt.