Frage Was sind die nützlichsten neuen Funktionen in C99? [geschlossen]


C99 gibt es seit über 10 Jahren, aber die Unterstützung dafür ist langsam gekommen, so dass die meisten Entwickler bei C89 geblieben sind. Selbst heute bin ich manchmal etwas überrascht, wenn ich auf C99-Features in C-Code stoße.

Nun, da die meisten großen Compiler C99 (MSVC ist eine bemerkenswerte Ausnahme, und einige Embedded-Compiler auch im Rückstand) unterstützen, glaube ich, dass Entwickler, die mit C arbeiten wahrscheinlich sollte darüber wissen, was C99 Funktionen stehen ihnen zur Verfügung. Einige der Funktionen sind nur allgemeine Merkmale, die zuvor noch nie standardisiert wurden (snprintfzum Beispiel), oder sind aus C ++ bekannt (flexible Variable Deklaration Platzierung oder Single-Line // Kommentare), aber einige der neuen Funktionen wurden zuerst in C99 eingeführt und sind vielen Programmierern unbekannt.

Was finden Sie an den nützlichsten neuen Funktionen in C99?

Als Referenz, der C99-Standard (Beschrieben als Entwurf, aber identisch mit dem aktualisierten Standard, soweit ich weiß), der Liste der neuen Funktionen, und das GCC C99-Implementierungsstatus.

Ein Feature pro Antwort, bitte; Fühlen Sie sich frei, mehrere Antworten zu hinterlassen. Kurze Codebeispiele, die neue Funktionen demonstrieren, werden empfohlen.


74


Ursprung


Antworten:


Ich bin so daran gewöhnt zu tippen

for (int i = 0; i < n; ++i) { ... }

in C ++, dass es ein Schmerz ist, einen Nicht-C99-Compiler zu verwenden, wo ich gezwungen bin zu sagen

int i;
for (i = 0; i < n; ++i ) { ... }

72



stdint.h, die definiert int8_t, uint8_tusw. Es müssen keine untragbaren Annahmen mehr getroffen werden, wie groß Ihre Ganzzahlen sind.

uint32_t truth = 0xDECAFBAD;

66



Ich denke, dass die neuen Initialisierungsmechanismen extrem 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 ein besseres Beispiel das - 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",
    ...
};

63



Unterstützung für einzeilige Kommentare beginnend mit //.


50



Arrays 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]);

48



Deklarieren von Variablen an anderen Stellen als am Anfang eines Blocks


40



Variadische Makros. Erleichtert das Generieren von Codebausteinen mit einer unbegrenzten Anzahl von Argumenten.


34



snprintf() - Ernsthaft, es ist eine Menge wert, um in der Lage zu sein, sicher formatierte Strings zu machen.


31



Flexible Array-Mitglieder.

6.7.2.1 Struktur- und Gewerkespezifikatoren

Als besonderen Fall kann das letzte Element einer Struktur mit mehr als einem benannten Mitglied vorkommen   einen unvollständigen Array-Typ haben; das nennt man a flexibles Array-Element. Mit zwei Ausnahmen wird das flexible Array-Element ignoriert. Erstens muss die Größe der Struktur sein   gleich dem des letzten Elements einer ansonsten identischen Struktur versetzt, der die flexible Anordnungs-Element mit einem Array von unspezifischen ed Länge) Zweitens, wenn ein ersetzt . (oder ->) -Operator besitzt einen linken Operanden, der (einen Zeiger auf), um eine Struktur mit einem flexiblen Array Elemente und den rechten Operandennamen, das Mitglied ist, es verhält sich, als ob das Mitglied mit der längsten Array ersetzt wurde (mit dem gleichen Typ-Elemente) das wäre nicht die Struktur größer als das Objekt machen, auf das zugegriffen wird; Der Versatz des Arrays soll der des flexiblen Array-Elements bleiben, auch wenn dieser sich von dem des Ersatz-Arrays unterscheidet. Wenn diese Anordnung keine Elemente haben würde, verhält sich, als wäre es ein Element, hatte aber das Verhalten undefiniert ist, wenn versucht wird, dieses Element zuzugreifen oder einen Zeiger einer letzten zu erzeugen,   es.

Beispiel:

typedef struct {
  int len;
  char buf[];
} buffer;

int bufsize = 100;
buffer *b = malloc(sizeof(buffer) + sizeof(int[bufsize]));

28



Zusammengesetzte Literale Setzen von Strukturen Mitglied für Mitglied ist so '89;)

Sie können sie auch verwenden, um Zeiger auf Objekte mit automatischer Speicherdauer zu erhalten, ohne unnötige Variablen zu deklarieren, z

foo(&(int){ 4 });

insteand von

int tmp = 4;
foo(&tmp);

27