Ist C stark getippt?


86

Um Wikipedia zu zitieren :

Zwei häufig verwendete Sprachen, die viele Arten der impliziten Konvertierung unterstützen, sind C und C ++, und es wird manchmal behauptet, dass es sich um schwach typisierte Sprachen handelt. Andere argumentieren jedoch, dass diese Sprachen die Art und Weise, wie Operanden unterschiedlicher Typen gemischt werden können, ausreichend einschränken und dass beide Sprachen als stark typisierte Sprachen angesehen werden sollten.

Gibt es eine endgültigere Antwort?


187
Für einen C-Programmierer bedeutet starkes Tippen, dass die Tasten stärker gedrückt werden.
Dan Dyer

2
C ist im Schreibkontinuum auf der schwachen Seite. Aber es gibt genug Punkte auf beiden Seiten, die Sie so oder so argumentieren können. Wenn Sie schon dabei sind, können Sie auch fragen (vi oder Emacs, Netbeans oder Eclipse usw.)
Cervo

4
Der Stand der Dinge auf Wikipedia war so schlecht, dass ich mich gezwungen fühlte, mehrere Wikipedia-Seiten zu bearbeiten. Vielleicht ist es jetzt etwas besser. Vielleicht.
Norman Ramsey

40
Betreff: Dans Kommentar (um zu würdigen, wo es fällig ist) Peter van der Lindens Buch "Expert C Programming" enthält die folgende Zeile: "Bis heute glauben viele C-Programmierer, dass 'starkes Tippen nur bedeutet, extra hart auf die Tastatur zu schlagen."
Alexandros Gezerlis

Sehr gute Frage !!!
Zerstörer

Antworten:


153

"Stark typisiert" und "schwach typisiert" sind Begriffe, die keine allgemein anerkannte technische Bedeutung haben. Begriffe, die eine genau definierte Bedeutung haben, sind

  • Dynamisch typisiert bedeutet, dass Typen zur Laufzeit an Werte angehängt werden und der Versuch, Werte verschiedener Typen zu mischen, kann zu einem "Laufzeit-Typfehler" führen. Wenn Sie beispielsweise in Schema versuchen, durch Schreiben (+ 1 #t)einen Wert zu true hinzuzufügen, führt dies zu einem Fehler. Der Fehler tritt nur auf, wenn Sie versuchen, den fehlerhaften Code auszuführen.

  • Statisch typisiert bedeutet, dass Typen zur Kompilierungszeit überprüft werden und ein Programm ohne statischen Typ vom Compiler abgelehnt wird. Wenn Sie beispielsweise in ML versuchen, durch Schreiben einen Wert zu true hinzuzufügen 1 + true, wird das Programm mit einer (wahrscheinlich kryptischen) Fehlermeldung abgelehnt. Sie erhalten immer den Fehler, auch wenn der Code möglicherweise nie ausgeführt wird.

Unterschiedliche Personen bevorzugen unterschiedliche Systeme, je nachdem, wie sehr sie Flexibilität schätzen und wie sehr sie sich um Laufzeitfehler sorgen.

Manchmal wird "stark typisiert" lose verwendet, um "statisch typisiert" zu bedeuten, und "schwach typisiert" wird falsch verwendet, um "dynamisch typisiert" zu bedeuten. Eine bessere Verwendung für den Begriff "stark typisiert" ist, dass "Sie das Typsystem nicht umgehen oder untergraben können", während "schwach typisiert" bedeutet "es gibt Lücken im Typensystem". Perverserweise haben die meisten Sprachen mit statischen Typsystemen Lücken, während viele Sprachen mit dynamischen Typsystemen keine Lücken haben.

Keiner dieser Begriffe hängt in irgendeiner Weise mit der Anzahl der impliziten Konvertierungen zusammen, die in einer Sprache verfügbar sind.

Wenn Sie genau über Programmiersprachen sprechen möchten, vermeiden Sie am besten die Begriffe "stark typisiert" und "schwach typisiert". Ich würde sagen, dass C eine Sprache ist, die statisch typisiert ist, aber viele Lücken aufweist. Eine Lücke besteht darin, dass Sie jeden Zeigertyp frei in einen anderen Zeigertyp umwandeln können. Sie können auch eine Lücke zwischen zwei beliebigen Typen Ihrer Wahl erstellen, indem Sie eine C-Union mit zwei Mitgliedern deklarieren, eines für jeden der betreffenden Typen.

Ich habe mehr über statisches und dynamisches Tippen geschrieben, warum-interpretiert-langs-meistens-ducktyped-während-kompiliert-haben-stark-tippen .


2
Woher haben Sie die Definitionen, die Sie für starkes / schwaches Tippen vorschlagen (die Lücke)?
Sydius

2
Warum brauchen Sie eine "Lücke" in einer dynamischen Schreibumgebung?
Chris Conway

4
@Sydius: Nachdem ich einen Großteil der letzten 20 Jahre mit Leuten verbracht habe, die Programmiersprachen und Typsysteme entwerfen, bauen und analysieren. Das ist mein bezahlter Job :-)
Norman Ramsey

@ Chris: Ich habe noch nie eine dynamisch getippte Sprache mit 'Lücke' gesehen. Die übliche Verwendung von Lücken besteht darin, mit einem Laufzeitsystem oder Betriebssystem zu arbeiten, z. B. eine Rohadresse zu nehmen und sie in einen Zeiger auf einen gut erzogenen Sprachwert zu konvertieren. Sie könnten dies in einer dynamischen Umgebung tun, aber ich kenne keine Versuche.
Norman Ramsey

1
@NormanRamsey Ich denke, dass Chris mit seiner Frage bezog sich auf:whereas "weakly typed" means "there are loopholes in the type system
Nir Alfasi

23

Es ist schwer, jede Sprache in "schwach" oder "stark" zu klassifizieren - es ist eher ein Kontinuum. Im Vergleich zu anderen Sprachen ist C jedoch ziemlich stark typisiert. Jedes Objekt hat einen Typ zur Kompilierungszeit, und der Compiler teilt Ihnen (laut) mit, ob Sie etwas mit einem Objekt tun, das sein Typ nicht zulässt. Beispielsweise können Sie keine Funktionen mit den falschen Parametertypen aufrufen, auf nicht vorhandene Struktur- / Gewerkschaftsmitglieder zugreifen usw.

Es gibt jedoch einige Schwächen. Eine große Schwäche sind Typecasts - sie sagen im Wesentlichen, dass Sie mit den Objekttypen herumspielen werden, und der Compiler sollte leise sein (wenn es geht). void*ist auch eine weitere Schwäche - es ist ein generischer Zeiger auf einen unbekannten Typ, und wenn Sie sie verwenden, müssen Sie besonders vorsichtig sein, dass Sie das Richtige tun. Der Compiler kann die meisten Verwendungen von nicht statisch überprüfen void*. void*kann auch in einen Zeiger auf einen beliebigen Typ ohne Umwandlung konvertiert werden (nur in C, nicht in C ++), was eine weitere Schwäche darstellt.


Schöne Antwort, obwohl "Typecasts ... und Compiler sollten leise sein" mich stört. Ein Typecast ist nicht wie das Ausschalten einer Warnung, sondern ändert tatsächlich die Interpretation des Werts, auf den verwiesen wird.
Tall Jeff

15
Sie verwechseln "statisch" und "stark" in Bezug auf das Tippen. Diese beiden Konzepte sind unabhängig voneinander.
Bendin

1
Dennis Richie (C-Autor) nannte C "stark getippt und schwach geprüft"
TimZaman

11

Die Literatur ist darüber nicht klar. Ich denke, dass stark getippt nicht Ja / Nein ist, es gibt unterschiedliche Grade starker Typisierung.

Eine Programmiersprache hat eine Spezifikation, wie sie Programme ausführt. Manchmal ist es nicht klar, wie mit bestimmten Programmen ausgeführt werden soll. Zum Beispiel Programme, die versuchen, eine Zeichenfolge von einer Zahl zu subtrahieren. Oder Programme, die durch Null teilen. Es gibt verschiedene Möglichkeiten, mit diesen Bedingungen umzugehen. Einige Sprachen haben Regeln für den Umgang mit diesen Fehlern (z. B. lösen sie eine Ausnahme aus). Andere Sprachen haben einfach keine Regeln, um mit diesen Situationen umzugehen. Diese Sprachen verfügen im Allgemeinen über Typsysteme, um das Kompilieren von Programmen zu verhindern, die zu nicht angegebenem Verhalten führen. Es gibt auch Sprachen mit nicht spezifiziertem Verhalten und ohne Typsystem, um diese Fehler beim Kompilieren zu verhindern (wenn Sie ein Programm schreiben, das auf nicht spezifiziertes Verhalten trifft, werden möglicherweise die Raketen gestartet).

So:

Sprachen, die in jedem Fall angeben, was zur Laufzeit geschieht (z. B. Hinzufügen einer Zahl zu einer Zeichenfolge), werden als dynamisch typisiert bezeichnet. Sprachen, die verhindern, dass Programme zur Kompilierungszeit fehlerhaft ausgeführt werden, werden statisch typisiert. Sprachen, die nicht angeben, was passiert, und auch kein Typsystem zur Vermeidung von Fehlern haben, werden als schwach typisiert bezeichnet.

Ist Java also statisch typisiert? Ja, da das Typsystem das Subtrahieren einer Zeichenfolge von einer Zahl nicht zulässt. Nein, weil Sie damit durch Null teilen können. Sie können die Kompilierung durch Null zur Kompilierungszeit mit einem Typsystem verhindern. Zum Beispiel durch Erstellen eines Zahlentyps, der nicht Null sein kann (z. B. NonZeroInt) und nur durch Zahlen mit diesem Typ dividieren darf.

Ist C also stark oder schwach typisiert? C ist stark typisiert, da das Typsystem einige Typfehler nicht zulässt. In anderen Fällen ist es jedoch schwach typisiert, wenn nicht definiert ist, was passiert (und das Typsystem Sie nicht schützt).


Ich mag Ihre Ausrichtung von dynamisch und statisch als Formen von stark gegen schwach. Ich bin mir jedoch nicht sicher, ob ich Ihre Meinung zu statisch typisierten Systemen verstehe, die die Division durch Null stoppen. Wenn mein statisch eingegebener intWert einen Wert von den Benutzer- oder Befehlszeilenargumenten oder einer Datei erhält, kann der Compiler nichts tun, um zu verhindern, dass dies eine Null ist!
Rikki

1
Es gibt statische Typsysteme, die dies verhindern, aber die meisten Sprachen werden entweder schwach oder dynamisch in Bezug auf die Division durch Null "typisiert", weil es sich um undefiniertes Verhalten handelt (C) oder sie eine Ausnahme auslösen (Java).
Jules

11

C wird als schwach typisiert angesehen, da Sie jeden Typ durch einen Cast ohne Compilerfehler in einen anderen Typ konvertieren können. Weitere Informationen zu diesem Problem finden Sie hier .


2
Wikipedia ist hier irreführend. C ist stark typisiert, Typen sind sehr gültig und der Compiler wird gesperrt, wenn Sie sie falsch verstehen. C bietet jedoch auch Funktionen, mit denen Sie dies umgehen können. Vergleichen Sie mit Sprachen wie BCPL, die nur einen Bytetyp haben.
Gbjbaanb

12
Schwach getippt bedeutet nicht, dass eine Sprache keine Typen hat, sondern nur, dass Typen implizit von einem Typ zum anderen gezwungen werden können. Vergleichen Sie mit Python, einer stark typisierten Sprache, in der Sie Typen mit Funktionsaufrufen explizit konvertieren müssen.
Mipadi

Kann die Fähigkeit, etwas in C zu wirken, auch dazu beitragen, dass es ein schwacher Typ ist? Ich habe diesen Zweifel für immer
Suraj Jain

8

C ist stärker typisiert als Javascript und weniger stark typisiert als Ada.

Ich würde sagen, es fällt mehr in die stark typisierte Seite des Kontinuums. aber jemand anderes könnte anderer Meinung sein (auch wenn er sich irrt).

Wie ist das endgültig?


Es war eine etwas ironische Antwort. Aber erläutern Sie die Unrichtigkeit.
Michael Burr

1
Javascript ist stark typisiert. Es ist einfach nicht statisch typisiert. Alle Typprüfungen finden zur Laufzeit statt (dynamisch, nicht statisch), aber sie treten auf und verhindern, dass Sie den Speicher beschädigen (ein Aspekt der starken Typisierung).
Bendin

5
Nun, wie Norm Ramseys sehr gute Antwort zeigt, sind "stark typisiert" und "schwach typisiert" keine besonders gut definierten Begriffe. Soweit Javascript stark typisiert ist, könnten einige glauben, dass ("4" / ​​"2") als gültiger Javascript-Ausdruck etwas anderes anzeigen könnte.
Michael Burr

5

C wird als statisch typisiert betrachtet (Sie können keine Variablenänderung von int zu float vornehmen). Sobald eine Variable deklariert ist, bleibt sie auf diese Weise hängen.

Es wird jedoch als schwach typisiert angesehen, da die Typen Flip-Flops sein können.

Was ist 0? '\ 0', FALSE, 0.0, etc ..

In vielen Sprachen kann man nicht IF (Variable) sagen, da Bedingungen nur boolesche Werte aus booleschen Ausdrücken übernehmen. Diese sind stärker typisiert. Gleiches gilt für das Wechseln zwischen Zeichen und Ganzzahlen.

Grundsätzlich hat c zwei einfache Hauptdatentypen, Ganzzahlen und Gleitkommazahlen (obwohl verschiedene Präzisionen). Alles andere Boolesche Werte, Aufzählungen (nicht einfach, aber es passt) usw. werden als eine davon implementiert. Sogar Zeichen sind im Grunde ganze Zahlen.

Vergleichen Sie mit anderen Sprachen, in denen es Zeichenfolgentypen gibt, Aufzählungstypen, die nur den definierten Werten zugewiesen werden können, Boolesche Typen, in denen nur Ausdrücke verwendet werden können, die Boolesche Werte oder true / false generieren.

Aber Sie können argumentieren, dass im Vergleich zu Perl C stark typisiert ist. Es ist also eines dieser berühmten Argumente (vi gegen Emacs, Linux gegen Windows usw.). C # ist stärker typisiert als C. Grundsätzlich kann man so oder so argumentieren. Und Ihre Antworten werden wahrscheinlich in beide Richtungen gehen :) Auch einige Lehrbücher / Webseiten sagen, dass C schwach getippt ist, und einige sagen, dass C stark getippt ist. Wenn Sie zu Wikipedia gehen, sagt der C-Eintrag "teilweise schwache Eingabe". Ich würde sagen, im Vergleich zu Python C ist schwach typisiert. Also Python / C #, C, Perl auf dem Kontinuum.


Bitte erläutern Sie Ihre Argumentation, dass Perl weniger stark typisiert ist als C.
user51568

print "Testing" + 0 # perl macht 0; $ var = "string"; $ var = 1; $ var = 123,4; Was ist das für eine Variable?
Cervo

In C char * test = "testing"; printf (Testen + 0); wird immer noch eine Zeichenfolge sein, es ist nur so, dass sich in C der Index ändert, wenn ich anstelle von Null eine Zahl verwende. Es ist immer noch ziemlich schwach, aber etwas stärker als Perl. char * test; Test = 0; Test = 123,4; test = "c"; ... mein Compiler generiert Fehler
Cervo

Der Fehler besagt, dass eine Besetzung erforderlich ist. Trotzdem ist es eine etwas stärkere Typprüfung als Perl, daher muss ich im Kontinuum sagen, dass C stärker typisiert ist als Perl. Sie können immer noch test = (char *) gehen und dann 0, 123.4, 'C' usw. verwenden. Es ist jedoch ein Fehler, dies einfach zu tun.
Cervo

4

Viele gute Antworten hier. Ich möchte einen wichtigen Punkt aus Real World Haskell ansprechen :

Es ist nützlich zu wissen, dass viele Sprachgemeinschaften ihre eigenen Definitionen eines „starken Typs“ haben. Trotzdem werden wir kurz und allgemein über den Begriff der Stärke in Typensystemen sprechen.

(schnipsen)

Das Feuerwerk um Typensysteme hat seine Wurzeln im gewöhnlichen Englisch, wo die Leute den Begriffen „schwach“ und „stark“ Wertvorstellungen beimessen: Wir denken normalerweise, dass Stärke besser ist als Schwäche. Viel mehr Programmierer sprechen einfaches Englisch als akademische Fachsprache, und ziemlich oft werfen Akademiker Brickbats auf ein System, das nicht ihren Vorstellungen entspricht. Das Ergebnis ist oft der beliebte Internet-Zeitvertreib, ein Flammenkrieg.

Schauen Sie sich also die Antworten zu C und C ++ an, aber denken Sie daran, dass "stark" und "schwach" nicht "gut" und "schlecht" zugeordnet sind.


3

Meiner Meinung nach sind C / C ++ stark typisiert. Die Art der Hacks, mit denen Typen konvertiert werden können (void *), ist aufgrund der Nähe von C zur Maschine vorhanden. Mit anderen Worten, Sie können Assembler-Befehle von Pascal aus aufrufen und Zeiger bearbeiten, und Pascal wird immer noch als stark typisierte Sprache angesehen. Sie können Assembler- und C-ausführbare Dateien von Java über JNI aufrufen, aber Java wird dadurch nicht schwach typisiert.

In C ist nur ein Assembler mit Rohzeigern und dergleichen "eingebettet".


3

Der stark typisierte Begriff hat keine vereinbarte Definition. Daher ist es unmöglich, Ihre Frage zu beantworten, es sei denn, Sie definieren, was Sie unter "stark typisiert" verstehen .

Nach meiner Erfahrung werden die Begriffe "stark typisiert" und "schwach typisiert" ausschließlich von Trollen verwendet, da die Trolle aufgrund ihrer fehlenden Definitionen sie in der Mitte des Arguments neu definieren können, um sie ihrer Agenda anzupassen. Anders als beim Starten von Flamewars sind diese Begriffe so gut wie nutzlos.

Vielleicht möchten Sie auch einen Blick auf Was sind die Schlüsselaspekte einer stark typisierten Sprache? hier auf StackOverflow.


2
Ich bin nicht einverstanden. "Stark typisiert" bedeutet, dass der Datentyp eines Werts ermittelt werden kann und nur für diesen Typ geeignete Operationen zulässig sind. "Dynamisch" und "statisch" geben an, wann diese Bestimmung vorgenommen werden kann.
joel.neely

2
Sie tun erkennen , die Ironie zu versuchen , die Behauptung zu widerlegen , dass es keine Definition-vereinbart wird durch noch eine weitere Definition einzuführen, nicht wahr?
Jörg W Mittag

1
@Jorg: Ich versuche nicht, einen anderen vorzustellen. nur diejenige angeben, die üblicherweise in den Kreisen verwendet wird, in denen ich mich bewege.
joel.neely

3

Laut Dennis Ritchie ( Schöpfer von C ) und Brian Kernighan ist C keine stark typisierte Sprache. Die folgenden Zeilen stammen aus dem Buch Die Programmiersprache C Seite 3 Absatz 5

C ist keine stark typisierte Sprache, aber im Laufe der Entwicklung wurde die Typprüfung verstärkt.


1

Es gibt ein Kontinuum mit mehreren parallelen Wegen zwischen "schwach typisiert" und "stark typisiert", zwei Begriffe, die nicht einmal genau definiert sind.

C ist statisch typisiert, da der Compiler den deklarierten Typ jeder lokalen Variablen und jedes Strukturelement kennt .

Dynamisch typisierte Sprachen sind möglicherweise immer noch stark typisiert, wenn jedes Objekt einen bestimmten Typ hat, der Compiler diesen Typ jedoch nicht kennen kann.


0

Was ist der Grund für Ihre Anfrage? Der Grund, den ich frage, ist, dass dies ein kleiner Unterschied ist und Ihre spezielle Verwendung von "stark typisiert" möglicherweise mehr oder weniger geklärt werden muss. Ich würde definitiv sagen, dass Java und andere Sprachen strengere Einschränkungen für implizite Typkonversationen haben.


Meistens neugierig, aber ich bewerbe mich um eine C-Stelle und wollte es wissen, falls sie mich darüber befragen.
Sydius

Dann ist wahrscheinlich die längere Antwort, die die Nuancen von "stark typisiert" angibt, der beste Ansatz, anstatt nur "Ja" oder "Nein" zu sagen.
BobbyShaftoe

0

Es ist schwierig, eine konkrete Antwort zu geben, wenn es keine konkrete Definition von "stark typisiert" gibt. Ich würde sagen, dass C stark typisiert ist, da jede Variable und jeder Ausdruck einen Typ hat, aber schwach typisiert, so dass Sie Typen mithilfe von Casts ändern und die Darstellung eines Typs als einen anderen interpretieren können.


Es gibt eine offizielle def. für stark getippt. Es heißt, dass ein sys. ist ST, wenn garantiert wird, dass kein Laufzeitfehler vorliegt. Beispiel: ML, Haskell. Dies ist nützlich, damit das System Typ-Tags in Objekten weglässt und die Operatoren jedoch auf die richtigen Typen anwenden. Weil wir vor der Ausführung wissen, dass keine Tags in Objekten erforderlich sind. Da C gegossen und Zeiger Zugriff auf beliebige Notiz versehen ist, ist C nicht st
alinsoar

0

Ich würde sagen, dass C so stark typisiert ist, wie es Ihr Compiler / Ihre Plattform vorschreibt. Wenn Sie beispielsweise auf einer strengen Plattform aufbauen, wird die Dereferenzierung eines Zeigers vom Typ punned wahrscheinlich unterbrochen:

void m_free(void **p)
{
        if (*p != NULL) {
                free(*p);
                *p = NULL;
        }
}

....
char *str = strdup("foo");
m_free((void **) &foo);

Wenn Sie dem Compiler nun sagen, dass er striktes Aliasing überspringen soll, ist dies kein Problem, aber nicht sehr portabel. In diesem Sinne ist es möglich, die Grenzen der Sprache zu überschreiten, aber wahrscheinlich nicht die beste Idee. Das geht einen Schritt über das typische Casting hinaus, dh das Casting int so lange und zeigt wirklich eine der möglichen Fallstricke der Leere.

Ich würde also sagen, dass C grundsätzlich streng typisiert ist, aber die verschiedenen Compiler setzen voraus, dass der Programmierer es am besten weiß und eine gewisse Flexibilität zulässt. Dies hängt wirklich vom Compiler ab, einige würden dieses potenzielle Hoppla nicht aufgreifen. In diesem Sinne spielt der Compiler der Wahl wirklich eine Rolle bei der Beantwortung der Frage. Was richtig ist, unterscheidet sich oft von dem, was Ihr Compiler Ihnen ermöglicht, damit durchzukommen.



-1

Nicht stark getippt.

Überlegen Sie, was der folgende Funktionsprototyp über die Datentypen der Argumente aussagt:

void func (int n, char ch, ...);

Nichts. Daher schlage ich vor, dass hier keine starke Eingabe erfolgt.


Huh? Es sagt Ihnen, dass es ein int gibt, gefolgt von einem Zeichen, gefolgt von einer beliebigen Anzahl von Argumenten eines beliebigen Typs. Das ist nicht "nichts".
Lawrence Dol

Das ... sagt nichts über die Arten der Argumente aus, die übergeben werden. Es ist wahr, dass der Typ der Funktion selbst bekannt ist. Das hat Software Monkey gesagt.
Johannes Schaub - litb

Ich spreche von diesen "beliebig vielen Argumenten jeglicher Art". Eine Kette ist nur so stark wie ihr schwächstes Glied.
joel.neely

-3

Ich würde sagen, es sind starke Typen, da jeder Ausdruck einen Typ hat, der nicht von seinem Wert abhängt. ei kann es vor der Laufzeit bekannt sein.

OTOH Ich bin mir nicht sicher, ob das die richtige Beschreibung von stark getippt ist. Die einzige stärkere Behauptung, die ich als Grund für eine Sprache sehen kann, wäre die Gewissheit, dass Sie das Typsystem zur Laufzeit nicht durch Neuinterpretation von Typumwandlungen, Gewerkschaften, Aufrufen in andere Sprachen, Zeiger, Assemblersprache usw. untergraben können. Sprachen wie diese existieren, sind aber so verkrüppelt, dass sie für Programmierer außerhalb von hoher Sicherheit und Wissenschaft nicht von großem Interesse zu sein scheinen. Wie jemand nonZeroIntbetont hat, braucht man Typen wie und so weiter , um das wirklich richtig zu machen . Yuck.


3
Was ist nicht? Meine Definition von stark getippt oder C?
BCS
Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.