2010-12-31 13 views
6

Nehmen wir an, ich schreibe char c[99] = {'Stack Overflow'}; in C oder C++. Es kompiliert gut, aber ist das gültig? Mit gültig meinte ich, kein undefiniertes oder nicht spezifiziertes Verhalten aufzurufen.Ist dies eine gültige C-Anweisung?

Nochmal wenn ich schreibe char c[99] = 'Stack Overflow'; gcc beklagt sich über Multicharacter-Konstante, die offensichtlich ist, aber in dem oben, wenn ich in geschweiften Klammern eingeschlossen Compiler ist glücklich! Wieso ist es so?

Ich bemerke auch, dass puts(c); nach der ersten Anweisung 'w' genau das letzte Zeichen einer allgemeinen Zeichenfolge anstelle von Stack Overflow ausgeben wird. Warum?

Kann jemand diese Verhaltensweisen separat erklären?

+3

Kompilieren Sie es und finden Sie es heraus. – Falmarri

+5

Er sagte bereits, dass er es kompiliert hat ... – indiv

+22

@Falmarri: Ich denke, dass Sie den RTFQ Preis gewinnen. Er sagte "es kompiliert gut" und beschreibt auch die Ausgabe, offensichtlich hat er es getestet. Aber Tests zeigen nicht, ob es portabel oder vom Standard gut definiert ist. –

Antwort

14

Sie sind beide nur ein einzelnes Literal, also c[0] wird auf das Literal gesetzt und c[1] ... c[98] werden mit Null (NUL-Zeichen) gefüllt.

Ich denke, welcher Wert tatsächlich in c[0] gestopft wird, ist abhängig von der Implementierung, aber es sollte zumindest kompilieren auf jedem kompatiblen Compiler.

EDIT: Geprüfte gegen den Standard, in C++ 0x mindestens:

A Multizeichen literal hat int und Implementierung definierten Wert ein.

Und in C99 (mit the draft, weil es frei ist):

Der Wert eines konstanten ganzzahligen Charakter mehr als ein Zeichen enthält (zB 'ab'), oder ein Zeichen enthält, oder eine Sequenz entweichen die nicht auf ein Ein-Byte-Ausführungszeichen abgebildet wird, ist implementierungsdefiniert.

+1

+1 Willkommen in der Welt der Multi-Zeichen-Literal. –

+0

Hm, aber warum die Anweisung mit geschweiften Klammern die syntaktische Überprüfung des Compilers passiert? – Quixotic

+1

@Philando: Weil es ein " Compound-Initialisierer "wird verwendet, um ein Array zu initialisieren? Das ist vollkommen legal. Es gibt keine Regel, dass Compound-Initialisierer mehr als ein Element haben müssen, in der Tat sind Dinge wie' int a [10] = {0}; 'sehr häufig. –

1

Vereinbart - in Windows Kernel-Code - Sie sehen eine Menge Tagging-Speicher. Und es ist tatsächlich pro Plattform implementiert. Sie verwenden jedoch ULONGs, um Speicher zu markieren, und es ist immer ein 4-stelliges Literal in umgekehrter Reihenfolge: ULONG tagMemory = 'kscf';

Die Interpretation ist plattformspezifisch, aber ein Strom von Zeichen.

Verwandte Themen