Warum gibt es keine Hashtabellen in der C-Standardbibliothek?

Lesezeit: 9 Minuten

Benutzeravatar von Shankar Raju
Shankar Raju

Warum gibt es keine Hashtable-Unterstützung als Teil der Standard-C-Bibliothek? Gibt es dafür einen bestimmten Grund?

  • es ist Teil einer Strategie zur Steigerung der Beschäftigung unter C-Entwicklern.

    – Käse

    25. Mai 2011 um 1:14 Uhr

  • Anleitung zur Version: stackoverflow.com/questions/4384359/…

    – Ciro Santilli OurBigBook.com

    20. August 2017 um 18:36 Uhr

Benutzeravatar von Dietrich Epp
Dietrich Ep

C erscheint nach heutigen Maßstäben ungewöhnlich, da keine nützlichen Datenstrukturen definiert sind. Keiner. Nicht einmal Strings – und wenn Sie denken, dass ein C-String eine Datenstruktur ist, müssen wir uns darüber einigen, was eine „Datenstruktur“ ist.

Wenn Sie C mögen, dann stellen Sie es sich als “leeres Blatt” vor … Ihre gesamte Anwendung besteht aus Code, der von Ihnen geschrieben wurde, und Bibliotheken, die Sie abrufen möchten, plus ein paar ziemlich primitiven Standardbibliotheksfunktionen, mit vielleicht ein oder zwei Ausnahmen wie qsort. Heutzutage verwenden die Leute C, um Dinge wie Python, Ruby, Apache oder den Linux-Kernel zu implementieren. Dies sind Projekte, die sowieso alle ihre eigenen Datenstrukturen verwenden, und sie würden wahrscheinlich nicht so etwas wie die STL verwenden.

Viele C-Bibliotheken implementieren generische Hash-Tabellen. Es gibt Kompromisse, und Sie können Ihren Favoriten auswählen. Einige von ihnen sind über Callbacks konfigurierbar.

  • Glib hat ein Hash-Tabellenobjekt (Dokumentation)
  • Apache Portable Runtime hat eine Hash-Tabelle (Dokumentation)
  • Die Core Foundation-Bibliothek von Apple hat eine Hash-Tabelle (Dokumentation) Hinweis: Ja, Sie können jedes Objekt als Schlüssel oder Wert einfügen.
  • UTHash ist eine Hash-Tabellenbibliothek (Dokumentation)
  • Eine weitere Hash-Tabellenbibliothek (Verknüpfung)

Bei all diesen Bibliotheken, die tun, was Sie wollen, was bringt es dann, dem C-Standard eine Hash-Tabelle hinzuzufügen?

  • Hmm, ich bin mir nicht sicher, ob ich dem Bit “C-String ist keine Datenstruktur” zustimme (allerdings nicht genug, um abzulehnen) – sie haben eine definierte Struktur und Funktionen, um sie zu manipulieren. Abgesehen von der Komplexität bin ich mir nicht sicher, ob sich das von einem BTree oder einer HashTable unterscheidet. Haben wir jedenfalls auch FILE * 🙂

    – paxdiablo

    25. Mai 2011 um 2:43 Uhr


  • +1 für eine Antwort, die den Teil “Warum” tatsächlich anständig beantwortet.

    – R.. GitHub HÖR AUF, EIS ZU HELFEN

    25. Mai 2011 um 3:34 Uhr

  • @paxdiablo: Ich dachte darüber nach, es zu erwähnen FILE*… das ist ein guter Punkt.

    – Dietrich Ep

    25. Mai 2011 um 5:04 Uhr

  • Ich schlage hiermit die Datenstruktur punchcard_t als endgültige Lösung für die String-Probleme von C vor. Die Datenstruktur soll definiert werden als typedef struct { char data[81];} punchcard_t; und soll in stdpunchcard.h definiert werden. Es wird die Lösung sein, “allgemeine, für Menschen sinnvolle Zeichenfolgen aus Funktionen zurückzugeben”.

    – Dmitri

    1. September 2016 um 12:03 Uhr


  • Beste Antwort. Es besteht keine Notwendigkeit, eine standardmäßige Hash-Tabellenbibliothek zu erstellen, da es Ihnen auf dieser Ebene wirklich wichtig ist, welche Sie verwenden, also sollten Sie sich einige Open-Source-Bibliotheken ansehen oder Ihre eigenen schreiben.

    – sudo

    26. Juli 2017 um 10:38 Uhr

Benutzeravatar von paxdiablo
paxdiablo

Es gibt keine Hashtabelle in der Standard-C-Bibliothek, weil entweder:

  • niemand hat der Arbeitsgruppe einen Vorschlag unterbreitet; oder
  • die Arbeitsgruppe hält dies für unnötig.

So funktioniert ISO. Vorschläge werden eingebracht und angenommen oder abgelehnt.

Sie müssen vorsichtig sein, was Sie der Standardbibliothek hinzufügen, da Sie zwei widersprüchliche Gruppen haben. Als ein Benutzer, Sie möchten vielleicht, dass jede Datenstruktur unter der Sonne zum Standard hinzugefügt wird, um die Sprache nützlicher zu machen.

Aber als Sprache Implementierer (Nebenbei gesagt, das sind wahrscheinlich die Leute, die die meisten der verschiedenen Arbeitsgruppen bilden, so dass ihre Ansicht wahrscheinlich mehr Einfluss hat), Sie wollen nicht wirklich den Aufwand haben, Dinge implementieren zu müssen, die möglicherweise nicht verwendet werden von allen. Alles, was es gab, als C89 erschien, hatte mit der Tatsache zu tun, dass der Hauptzweck darin bestand, bestehende Praktiken zu kodifizieren, anstatt neue Praktiken einzuführen. Alle Iterationen der Standards waren seitdem etwas freier in dem, was sie tun können, aber die Abwärtskompatibilität ist immer noch ein wichtiges Thema.

Ich selbst habe auch Konflikte. Ich würde gerne alle Funktionen der Java-, C++- oder Python-Bibliotheken in C zur Verfügung haben. Das würde es natürlich für Neulinge so viel schwieriger machen, alles zu lernen, und, wie ein Kommentator sagte, wahrscheinlich machen Code Monkey kann nützlichen Code auspumpen und dabei meinen Wert mindern 🙂

Und ich ziemlich haben alle Datenstrukturen, die ich jemals brauchen werde, aus meiner langen und (größtenteils) illustren Karriere. Sie sind für diese Art von Dingen nicht auf die Standardbibliothek beschränkt. Es gibt viele Tools von Drittanbietern, mit denen Sie die Arbeit erledigen können, und (wie ich) können Sie auch Ihre eigenen erstellen.

Wenn Sie wissen möchten, warum bestimmte Entscheidungen in jeder Iteration getroffen wurden, veröffentlicht ISO (und ursprünglich ANSI, bevor ISO übernahm) normalerweise Begründungsdokumente. Der C89 von ANSI ist zu finden hier. Es enthält diese kleine Schönheit im Umfang:

Diese Begründung konzentriert sich in erster Linie auf Ergänzungen, Klarstellungen und Änderungen, die an der in den Basisdokumenten beschriebenen Sprache vorgenommen wurden. Es ist keine Begründung für die C-Sprache als Ganzes: Das Komitee wurde damit beauftragt, eine bestehende Sprache zu kodifizieren, nicht eine neue zu entwerfen. In dieser Begründung wird kein Versuch unternommen, die bereits vorhandene Syntax der Sprache zu verteidigen, wie etwa die Syntax von Deklarationen oder die Bindung von Operatoren.

Ich genieße besonders das Eingeständnis, dass sie nicht für irgendein unheiliges Durcheinander verantwortlich sind, das ihren Standardisierungsversuchen vorausgegangen sein könnte.

Aber vielleicht liegt die wahre Antwort auf Ihre Frage in diesem Teil, einem der Leitprinzipien:


Bewahre den Geist von C. Das Komitee hat sich zum Ziel gesetzt, den traditionellen Geist von C zu bewahren. Es gibt viele Facetten des Geistes von C, aber die Essenz ist ein Gemeinschaftsgefühl der zugrunde liegenden Prinzipien, auf denen die C-Sprache basiert. Einige der Facetten des Geistes von C können in Sätzen zusammengefasst werden wie:

  • Vertrauen Sie dem Programmierer.
  • Verhindern Sie nicht, dass der Programmierer das tut, was getan werden muss.
  • Halten Sie die Sprache klein und einfach.
  • Geben Sie nur eine Möglichkeit an, eine Operation durchzuführen.
  • Machen Sie es schnell, auch wenn es nicht garantiert tragbar ist.

Dieser dritte ist wahrscheinlich der Hauptgrund, warum die Bibliothek nicht mit den anfänglichen Standardisierungsbemühungen massiv erweitert wurde – das, und die Tatsache, dass eine solche Erweiterung von einem Komitee wahrscheinlich dazu geführt hätte, dass ANSI C die Bezeichnung C2038 statt C89 erhalten hätte.

  • “Halten Sie die Sprache klein und einfach. Bieten Sie nur eine Möglichkeit an, eine Operation durchzuführen.” In diesem noch C redest du? int oder or signed oder signed int, if-else oder ?:, if-else oder switch, funktionsähnliche Makros oder Funktionen, Continue oder Break oder Goto oder Return ;, const int oder int const, typedef struct oder struct, enum or const oder #define, malloc oder calloc, NULL oder 0 oder ‘\0’, *(ptr+n) oder ptr[n]. Etc, etc, das ist nur die Spitze des Eisbergs, auf dem ich wirklich den ganzen Tag weitermachen könnte.

    – Ludin

    25. Mai 2011 um 6:22 Uhr

  • Außerdem hat sich das Komitee wirklich bewundernswert bemüht, die Sprache unnötig komplex zu machen. Wann haben Sie das letzte Mal die folgenden Header verwendet: complex.h, errno.h, fenv.h, float.h, inttypes.h, iso646.h, locale.h, signal.h, wctype.h. Mir scheint eine Header-Datei, die eine Hash-Tabelle enthält, etwa hundertmal nützlicher als diese.

    – Ludin

    25. Mai 2011 um 6:29 Uhr

  • @Lundin: Siehe den Abschnitt mit “Aufgeladen mit der Kodifizierung einer vorhandenen Sprache, nicht Design a Neu one”. Das meiste davon war bereits vor ANSI vorhanden. Von diesen Headern habe ich oft verwendet errno, locale und signal – Ich glaube nicht je Ich habe einen der anderen verwendet, aber andererseits bin ich nicht der einzige C-Codierer auf dem Planeten 🙂 Dinge wie complex, fenv, inttypes, iso646 und wctype kam später, hat also nichts mit der C89-Begründung zu tun. Sie müssten sich die Gründe für die spezifischen Iterationen ansehen.

    – paxdiablo

    25. Mai 2011 um 6:45 Uhr


  • @Lundin: zum Beispiel: “Ein neues Feature von C99, komplexe Typen wurden zu C hinzugefügt, um C für die allgemeine numerische Programmierung geeignet und attraktiv zu machen. Komplexe Arithmetik wird in bestimmten wichtigen Anwendungsbereichen stark verwendet.” – aus open-std.org/jtc1/sc22/wg14/www/C99RationaleV5.10.pdf

    – paxdiablo

    25. Mai 2011 um 6:49 Uhr


  • Wenn also das C90-Komitee mit der Kodifizierung einer bestehenden Sprache beauftragt wurde, kann man sich fragen, womit das C99-Komitee beauftragt wurde. “Erfinden Sie so viele sinnlose neue Funktionen wie möglich, während Sie nennenswerte Verbesserungen der Sprache vermeiden”, oder so ähnlich. Scheinbar treffen sie sich noch mehrmals im Jahr und sprechen von der guten alten Zeit.

    – Ludin

    25. Mai 2011 um 6:57 Uhr

Benutzeravatar von caf
Café

Die Standard-C-Bibliothek enthält nicht irgendein große, persistente Datenstrukturen – weder Listen, noch Bäume, noch Stacks, noch Hashtables.

Es ist nicht wirklich möglich, eine endgültige Antwort zu geben, ohne die Autoren der ursprünglichen C-Bibliothek zu fragen. Eine plausible Erklärung ist jedoch, dass die Implementierung solcher Datenstrukturen verschiedene Kompromisse beinhaltet und nur der Autor der Anwendung in der richtigen Position ist, diese Kompromisse einzugehen.

Beachten Sie, dass die POSIX-Standard-C-Bibliothek generische Hashtable-Funktionen spezifiziert: hcreate(), hsearch() und hdestroy(); und beachten Sie auch, dass ihre “eine Grösse passt allen” Die Natur neigt dazu, sie für die meisten Anwendungsfälle in der realen Welt unangemessen zu machen, was das obige Argument unterstützt.

  • Hm, sieht so aus, als ob Sie mit den POSIX-Hash-Tabellen nur jeweils eine Hash-Tabelle erstellen können. Das klingt sehr nützlich.

    – Dietrich Ep

    25. Mai 2011 um 1:30 Uhr

  • Die POSIX-Hashtabellenfunktionen sind im realen Code ziemlich nutzlos.

    – R.. GitHub HÖR AUF, EIS ZU HELFEN

    25. Mai 2011 um 3:33 Uhr

  • Sehen hcreate_r die diese Einschränkung nicht hat (aber eine Nicht-POSIX-Erweiterung ist).

    – jjg

    10. Februar 2014 um 10:52 Uhr


Ciro Santilli Benutzeravatar von OurBigBook.com
Ciro Santilli OurBigBook.com

Aufgrund fehlender Vorlagen

Dies ist eine Vermutung, aber ohne Vorlagen in der Sprache wie C++ ist die Implementierung von Containern sehr unelegant, da Sie Dutzende von Definitionen benötigen würden, um alle möglichen Typen abzudecken, ganz zu schweigen von benutzerdefinierten Typen.

Es gibt C-Strategien, um dies zu mildern, wie z. B. herumspielen void *aber sie verlieren Typüberprüfungen zur Kompilierzeit.

GLib und gnulib sind im Moment meine empfohlenen Implementierungen: Quick Way to Implement Dictionary in C

1418070cookie-checkWarum gibt es keine Hashtabellen in der C-Standardbibliothek?

This website is using cookies to improve the user-friendliness. You agree by using the website further.

Privacy policy