C Einführung

Die Sprache C ist eine universelle höhere Programmiersprache, die ursprünglich von Dennis Ritchie bei Bell Labs für die Entwicklung des UNIX-Betriebssystems entworfen wurde. C wurde erstmals 1972 auf dem DEC PDP-11-Computer implementiert und ist eine der einflussreichsten Sprachen in der modernen Programmiersprachenlandschaft.

1978 veröffentlichten Brian Kernighan und Dennis Ritchie gemeinsam das Buch „The C Programming Language“, das die erste vollständige öffentliche Beschreibung von C lieferte. Diese Version wurde als K&R-Standard bekannt und diente in den folgenden Jahren als De-facto-Spezifikation der Sprache C.

Das Betriebssystem UNIX, der C-Compiler und fast alle UNIX-Anwendungen sind in C geschrieben. Mit seiner knappen Syntax, den Möglichkeiten zur Steuerung auf Hardwareebene und seiner hervorragenden Laufzeiteffizienz ist C zur wichtigsten professionellen Sprache in der Systemprogrammierung geworden und hat die Gestaltung vieler Nachfolgesprachen wie C++, Java, Go und Rust tiefgreifend beeinflusst.

  • Prägnante Syntax, einfach zu erlernen und zu beherrschen.
  • Eine strukturierte Programmiersprache mit klarer Logik.
  • Kompiliert zu hocheffizientem Maschinencode, mit einer Ausführungsgeschwindigkeit nahe der von Assemblersprache.
  • Sie kann Speicher und Hardware direkt manipulieren und Aufgaben auf niedriger Ebene übernehmen.
  • Hochgradig portabel, kann auf einer Vielzahl von Computerplattformen und Betriebssystemen kompiliert und ausgeführt werden.
  • Sie verfügt über eine umfangreiche Standardbibliothek, ein ausgereiftes Ökosystem und eine große Community.

Über C

  • Die Sprache C wurde ursprünglich entwickelt, um das UNIX-Betriebssystem zu schreiben, und entstand 1972 in den Bell Labs.
  • C entwickelte sich aus der B-Sprache, die um 1970 von Ken Thompson entworfen wurde.
  • 1983 begann das American National Standards Institute (ANSI) mit der Arbeit an einem C-Sprachstandard und veröffentlichte 1989 offiziell C89 (auch ANSI C genannt). Dies war der erste offizielle Standard für C.
  • Bis 1973 war der Kernel des UNIX-Betriebssystems vollständig in C neu geschrieben worden, was C eine grundlegende Position in der Systemprogrammierung verlieh.
  • C ist derzeit die am weitesten verbreitete Systemprogrammiersprache und nimmt seit Langem eine zentrale Position in der Embedded-Entwicklung, bei Betriebssystemen, Compilern und anderen Bereichen ein.
  • Viele wichtige grundlegende Software und Frameworks (darunter der CPython-Interpreter, die zugrunde liegenden Komponenten der V8-Engine usw.) sind in C implementiert.
  • Der Kernel des beliebtesten Linux-Betriebssystems und die Kernteile des relationalen Datenbankmanagementsystems MySQL sind beide in C geschrieben.
  • C hat sich über mehrere Standardversionen wie C89, C99, C11 und C17 weiterentwickelt und bewahrt weiterhin Vitalität und Modernität.

Warum C verwenden?

C wurde ursprünglich für die Systementwicklung verwendet, insbesondere für die Kernprogramme, aus denen Betriebssysteme bestehen. Da der durch das Kompilieren von C erzeugte Maschinencode nahezu mit der gleichen Geschwindigkeit läuft wie Assemblersprache und zugleich eine bessere Lesbarkeit und Wartbarkeit als Assembler bietet, ist es die bevorzugte Sprache für die Entwicklung auf Systemebene geworden. Nachfolgend sind mehrere typische Anwendungsszenarien für C aufgeführt:

  • Betriebssystem-Kernel (z. B. Linux, Windows-NT-Kernel, macOS-XNU-Kernel)
  • Compiler und Interpreter für Programmiersprachen (z. B. GCC, Clang, CPython)
  • Assembler und Linker
  • Texteditoren und Kommandozeilenwerkzeuge
  • Drucker-Firmware und Treiber
  • Netzwerkprotokollstapel und Netzwerktreiber
  • Eingebettete Systeme und Mikrocontroller-Entwicklung
  • Datenbanksysteme (wie SQLite, MySQL, PostgreSQL)
  • Hochleistungsrechnen und wissenschaftliche Rechenbibliotheken (wie BLAS, LAPACK)
  • Innenleben von Game-Engines und Grafik-Rendering-Bibliotheken (wie OpenGL-Implementierungen)

C-Programm

Ein Programm in der Sprache C kann nur wenige Zeilen oder bis zu Millionen von Zeilen umfassen. Der Quellcode wird in Dateien mit der Erweiterung".c"in einer Textdatei gespeichert, zum Beispielhello.c. Bei großen Projekten wird der Code üblicherweise auf mehrere".c"Quelldateien und".h"Header-Dateien aufgeteilt, und die Kompilierung wird einheitlich vom Build-System verwaltet.

Sie können"vi"、"vim"、"VS Code"oder jeden anderen Texteditor verwenden, um C-Programme zu schreiben. Nach dem Schreiben kompilieren Sie den Quellcode mit Compilern wie GCC oder Clang in eine ausführbare Datei:

gcc hello.c -o hello   # 编译
./hello                # 运行(Linux/macOS)

Dieses Tutorial setzt voraus, dass Sie bereits wissen, wie man Textdateien bearbeitet und wie man Quellcode in Programmdateien schreibt.


C11

C11 (auch bekannt als C1X) ist der dritte große offizielle C-Standard und entspricht dem ISO-Standard ISO/IEC 9899:2011, der im Dezember 2011 offiziell veröffentlicht wurde. Aufbauend auf C99 verfeinerte er die Sprachmerkmale weiter, mit Schwerpunkt auf der Verbesserung der Multithreading-Unterstützung, generischen Programmierung und Sicherheit.

Neue Funktionen

  • Standardisierung der Ausrichtungsbehandlung (Alignment): Einführung von_AlignasSpezifizierern undalignofOperatoren undaligned_alloc()Funktionen und<stdalign.h>Header-Datei, die es Programmierern ermöglicht, die Ausrichtung von Daten im Speicher präzise zu steuern, was besonders für leistungssensitive Low-Level-Entwicklung wichtig ist.

  • _NoreturnFunktionsspezifizierer: wird verwendet, um Funktionen zu kennzeichnen, die niemals zurückkehren (wie z. B.exit()、abort()), ähnlich wie GCCs__attribute__((noreturn)), wodurch der Compiler bessere Optimierungen und Warnanalysen durchführen kann.

  • _GenericSchlüsselwörter für generische Auswahl: Ermöglicht die Auswahl verschiedener Codepfade zur Kompilierzeit anhand des Typs eines Ausdrucks; es ist der grundlegende Mechanismus zur Implementierung typsicherer generischer Makros in C und gleicht den langjährigen Mangel von C an generischen Fähigkeiten aus.

  • Multithreading-Unterstützung: Erstmals native Multithreading-Unterstützung auf Ebene des C-Sprachstandards eingeführt, einschließlich:

    • _Thread_localThread-lokaler Speicher-Typspezifizierer, wobei jeder Thread seine eigene unabhängige Kopie von Variablen hat.
    • <threads.h>Header-Datei, die das Erstellen von Threads ermöglicht (thrd_create), Synchronisation (mtx_lock/cnd_wait) und andere Verwaltungsfunktionen.
    • _AtomicTypqualifizierer und<stdatomic.h>Header-Datei, die lock-freie atomare Operationen bereitstellt, was eine wichtige Grundlage für die Multithread-Programmierung ist.
  • Erweiterte Unicode-Unterstützung: basierend auf ISO/IEC TR 19769:2004, hinzugefügtchar16_tundchar32_tDatentypen, die jeweils UTF-16- und UTF-32-Kodierungen entsprechen, und bieten<uchar.h>Header-Datei enthält Unicode-String-Konvertierungsfunktionen, wodurch die Unterstützung von C für internationalisierte Programmierung verbessert wird.

  • Removegets()Funktion: dagets()keine Puffergrenzen prüft und historisch eine häufige Quelle für Pufferüberlauf-Schwachstellen war. C11 hat sie offiziell aus dem Standard entfernt und empfiehlt die sichererefgets()oder neu hinzugefügtegets_s()Ersetzung.

  • Schnittstellen für grenzprüfende Funktionen (Anhang K): definiert eine Reihe von_ssichere Funktionen mit dem Suffix, wie z. B.fopen_s()、strcat_s()、strcpy_s()usw. Diese Funktionen erfordern, dass der Aufrufer die Puffergröße übergibt, wodurch Pufferüberlaufprobleme an der Wurzel verhindert werden.

  • weitere Makros zur Gleitkommabehandlung: erweitert<math.h>und<fenv.h>Die Makros zur Gleitkommabehandlung bieten eine feinere Steuerung von Gleitkommaoperationen und Fähigkeiten zur Ausnahmebehandlung und erfüllen die Anforderungen hochpräziser wissenschaftlicher Berechnungen.

  • Unterstützung anonymer Structs / Unions: Ermöglicht die verschachtelte Definition unbenannter Strukturen oder Unions innerhalb einer Struktur oder Union. Beim Zugriff auf ihre Mitglieder ist kein Name einer Zwischenschicht erforderlich, was die Definition komplexer Datenstrukturen vereinfacht. Diese Funktion existierte lange als Erweiterung in GCC, und C11 integrierte sie in den Standard.

  • statische Assertion_Static_assert(): führt zur Kompilierzeit Assertion-Prüfungen für konstante Ausdrücke durch; wenn die Bedingung nicht erfüllt ist, wird ein Kompilierfehler erzeugt (statt eines Laufzeitfehlers). Sie wird oft verwendet, um Kompilierzeit-Annahmen wie Typgrößen und Struct-Offsets zu überprüfen, was die Code-Robustheit verbessert.

  • fopen()neuer exklusiver Modus"x": an die Zeichenkette für den Dateiöffnungsmodus anhängen"x"(wie z. B."wx"), was exklusive Erstellung angibt – wenn die Datei bereits existiert, schlägt es fehl, ähnlich wie in POSIXO_CREAT|O_EXCLFlag, das häufig in Szenarien zur sicheren Erstellung temporärer Dateien verwendet wird.

  • hinzugefügtquick_exit()Funktion: Bietet einen dritten Weg, ein Programm zu beenden (die anderen beiden sindreturnundexit()), wennexit()wenn die Bereinigung nicht normal abgeschlossen werden kann,quick_exit()wird ausgeführt bisat_quick_exit()beendet sofort nach der registrierten Handler-Funktion, geeignet für Notausstiegsszenarien in Multithread-Programmen.

Weitere Erweiterungen