C99 gibt es seit über 10 Jahren, aber die Unterstützung dafür kommt nur langsam, so dass die meisten Entwickler bei C89 geblieben sind. Selbst heute bin ich manchmal leicht überrascht, wenn ich auf C99-Funktionen im C-Code stoße.
Da die meisten großen Compiler C99 unterstützen (MSVC ist eine bemerkenswerte Ausnahme, und einige eingebettete Compiler bleiben ebenfalls zurück), sollten Entwickler, die mit C arbeiten, wahrscheinlich wissen, welche C99-Funktionen ihnen zur Verfügung stehen. Einige der Funktionen sind nur allgemeine Funktionen, die zuvor noch nie standardisiert wurden ( snprintf
z. B.) oder aus C ++ bekannt sind (flexible Platzierung von Variablendeklarationen oder einzeilige //
Kommentare). Einige der neuen Funktionen wurden jedoch erstmals in C99 eingeführt und sind es auch vielen Programmierern unbekannt.
Was sind die nützlichsten neuen Funktionen in C99?
Als Referenz der C99-Standard (als Entwurf gekennzeichnet, aber meines Wissens identisch mit dem aktualisierten Standard), die Liste der neuen Funktionen und der Implementierungsstatus des GCC C99 .
Bitte eine Funktion pro Antwort; Fühlen Sie sich frei, mehrere Antworten zu hinterlassen. Es wird empfohlen, kurze Codebeispiele zu verwenden, die neue Funktionen demonstrieren.
Antworten:
Ich bin es so gewohnt zu tippen
for (int i = 0; i < n; ++i) { ... }
In C ++ ist es ein Schmerz, einen Nicht-C99-Compiler zu verwenden, wo ich gezwungen bin zu sagen
int i; for (i = 0; i < n; ++i ) { ... }
quelle
sub esp, 4
undadd esp, 4
werden entfernt! </ Sarkasmus>stdint.h
, was definiertint8_t
,uint8_t
usw. Sie müssen keine nicht tragbaren Annahmen mehr darüber treffen, wie breit Ihre ganzen Zahlen sind.uint32_t truth = 0xDECAFBAD;
quelle
Ich denke, dass die neuen Initialisierungsmechanismen äußerst wichtig sind.
struct { int x, y; } a[10] = { [3] = { .y = 12, .x = 1 } };
OK - kein überzeugendes Beispiel, aber die Notation ist korrekt. Sie können bestimmte Elemente eines Arrays und bestimmte Elemente einer Struktur initialisieren.
Vielleicht wäre dies ein besseres Beispiel - obwohl ich zugeben würde, dass es nicht sehr überzeugend ist:
enum { Iron = 26, Aluminium = 13, Beryllium = 4, ... }; const char *element_names[] = { [Iron] = "Iron", [Aluminium] = "Aluminium", [Beryllium] = "Beryllium", ... };
quelle
Arrays mit variabler Länge:
int x; scanf("%d", &x); int a[x]; for (int i = 0; i < x; ++i) a[i] = i * i; for (int i = 0; i < x; ++i) printf("%d\n", a[i]);
quelle
if (x < 0) x = 0; else if (x > 1024) x = 1024;
Unterstützung für einzeilige Kommentare beginnend mit
//
.quelle
In der Lage sein, Variablen an anderen Stellen als am Anfang eines Blocks zu deklarieren.
quelle
int a; int b; a = f(); b = g();
zuint a = f(); int b = g();
? Das Deklarieren einer Variablen in der Nähe des Initialisierungsortes ist sehr wichtig, um Fehler zu reduzieren./* this block is just for scoping */ {
} /* scope */
:)if(1) /* Scoping block */ {
}
ist ein bisschen besser, aber ein größeres Problem ist, dass Scoping und Kontrolle orthogonale Konzepte sind. Es gibt Zeiten, in denen es sinnvoll ist, Dinge innerhalb einer Schleife zu erfassen, aber es ist häufiger nützlich, Dinge nur um die Schleife herum zu haben, und es gibt auch viele Male, in denen Code Objekte mit Werten erstellt, die für die Erstellung von erforderlich sindfloat dx=x2-x1, dy=y2-y1; float distance = sqrt(dx*dx+dy*dy);
Variadische Makros. Erleichtert das Generieren von Boilerplate-Code mit unbegrenzter Anzahl von Argumenten.
quelle
snprintf()
- Im Ernst, es ist viel wert, sichere formatierte Zeichenfolgen erstellen zu können.quelle
Zusammengesetzte Literale. Das Setzen von Strukturen von Mitglied zu Mitglied ist also '89;)
Sie können sie auch verwenden, um Zeiger auf Objekte mit automatischer Speicherdauer abzurufen, ohne unnötige Variablen zu deklarieren, z
foo(&(int){ 4 });
insteand von
int tmp = 4; foo(&tmp);
quelle
Flexible Array-Mitglieder.
Beispiel:
typedef struct { int len; char buf[]; } buffer; int bufsize = 100; buffer *b = malloc(sizeof(buffer) + sizeof(int[bufsize]));
quelle
Der Bool-Typ.
Sie können jetzt so etwas tun:
bool v = 5; printf("v=%u\n", v);
wird gedruckt
1
quelle
bool
in C99 wird der der Variablen zugewiesene Wert immer auf 1 oder 0 gesetzt. Deshalb müssen Sie vorsichtig sein, wenn Sie Code haben, der auf einem C99-Compiler und auf einem älteren Compiler mit "simuliertem"bool
Typ ausgeführt wird. Mit!!
wird das tragbar.v = !!5;
hat die gleiche Semantik, ist aber nicht so lesbar.Unterstützung für
inline
Funktionen.quelle
inline
hilft trotzdem, da Sie die Funktion in mehr als einer Übersetzungseinheit definieren können. Sie können sie also in eine Header-Datei einfügen, die modulübergreifende Inlining-Möglichkeiten bietet.inline __attribute__((force_inline))
Zusammengesetzte Literale, bereits erwähnt, aber hier ist mein überzeugendes Beispiel:
struct A *a = malloc(sizeof(*a)); *a = (struct A){0}; /* full zero-initialization */ /* or */ *a = (struct A){.bufsiz=1024, .fd=2}; /* rest are zero-initialized. */
Es ist eine klare Möglichkeit, Daten zu initialisieren, selbst wenn sie sich auf dem Heap befinden. Es gibt keine Möglichkeit zu vergessen, etwas auf Null zu initialisieren.
quelle
Das
restrict
Schlüsselwort. Vor allem, wenn Sie Zahlen knacken ...quelle
Unterstützung für Unicode-Escape-Sequenzen:
printf("It's all \u03B5\u03BB\u03BB\u03B7\u03BD\u03B9\u03BA\u03AC to me.\n");
Oder sogar wörtliche Unicode-Zeichen:
printf("日本語\n");
(Hinweis: Abhängig von Ihrem Gebietsschema funktioniert dies möglicherweise nicht. Die tragbare Unterstützung für verschiedene Codierungen erfordert mehr Arbeit.)
quelle
Hexadezimale Gleitkommakonstanten (
0x1.8p0f
) und Konvertierungsspezifizierer (%a
,%A
). Wenn Sie häufig mit numerischen Details auf niedriger Ebene arbeiten, ist dies eine enorme Verbesserung gegenüber Dezimalliteralen und Konvertierungen.Sie ersparen Ihnen die Sorge um Rundungen bei der Angabe von Konstanten für einen Algorithmus und sind äußerst nützlich für das Debuggen von Gleitkomma-Code auf niedriger Ebene.
quelle
Persönlich mag ich die Anerkennung von IEC 60559: 1989 (Binäre Gleitkomma-Arithmetik für Mikroprozessorsysteme) und eine viel bessere Gleitkomma-Unterstützung.
In ähnlicher Weise ist es großartig, den Gleitkomma-Rundungsmodus einzustellen und abzufragen, nach Nan / Infinity / subnormalen Zahlen usw. zu suchen.
quelle