[xpert.press] moderne c-programmierung || c-zeichensatz, konstanten, kommentare
TRANSCRIPT
4
C-Zeichensatz, Konstanten, Kommentare
4.1 Zeichenmenge
abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ_0123456789
Obenstehend diejenigen Zeichen, die für Namen (und Konstanten) verwendet wer-den dürfen. Der Unterstrich _ gilt als Buchstabe. C unterscheidet glücklicherweisezwischen Groß- und Kleinbuchstaben! Namen müssen mit einem Buchstaben begin-nen.
Die ersten 31 (C99: 63) Zeichen eines internen Namens sind signifikant. Der Stan-dard C99 fordert 31 Zeichen für externe Namen, die vom Linker verarbeitet werden.
Nur die Zahlenwerte der Ziffernzeichen "0123456789" müssen in der gezeigtenReihenfolge eine Differenz von je +1 aufweisen! Deren absolute und alle anderenWerte sind plattform-spezifisch. Beispielsweise die Zeichen a...z müssen folglichkeineswegs aufsteigende Werte noch Differenzen von 1 besitzen.
!"#%&’()*+,-./:;<=>?[\]^{|}~
Die vorstehenden Zeichen sind Operatoren- und Punktuatorenzeichen.$ @ ‘ sind die einzigen (sichtbaren) in C nicht verwendeten ASCII-Zeichen.
Leerzeichen, beide Tabs, Zeilen- und Seitenvorschub sind Zwischenraumzeichen,die völlig beliebig in einen Quelltext geschrieben werden können, solange sie nichtSchlüsselworte oder Operatoren (aus zwei oder mehr Zeichen) oder sonstige Syn-taxeinheiten zerteilen. In einer Preprocessor-Zeile ab # dürfen nur Leerzeichen undh-Tab als White space verwendet werden. An manchen Stellen müssen Zwischen-raumzeichen stehen, um eine Trennwirkung zu erzielen: unsigned long kannnicht so: unsignedlong geschrieben werden.
H. Schellong, Moderne C-Programmierung, Xpert.press,DOI 10.1007/978-3-642-40058-2_4, © Springer-Verlag Berlin Heidelberg 2013
26 4 C-Zeichensatz, Konstanten, Kommentare
4.2 Zahlenkonstanten
Wert Typ Zahlenbasis/Anm. Ziffernmenge12345 int dezimal:10 0...904567 int oktal:8 0...70x12AF int hexadezimal:16 0...9a...f, 0...9A...F12345L long12345LL long long C9912345u unsigned12345ul unsigned long12345ull unsigned long long C991.2345 double1.2345f float1.2345L long double1.2345e-6 double 1.2345 · 10−6
uUlLfFeE sind als Suffix/Exponentmarkierer gültig.
Oktal-Darstellung beginnt mit 0Hex-Darstellung beginnt mit 0x oder 0X
Oktal- und Hexzahlen haben eine Besonderheit, da deren Zahlenbasen 8 und 16 Po-tenzen von 2 sind: 8 = 23, 16 = 24 : Jede Ziffer steht für genau 3 bzw. 4 Bit. Diejeweilige Ziffernmenge nutzt diese Bit-Felder voll aus:
0777 == 1111111110x777 == 111011101110xFFF == 111111111111
Eine besondere Konstante ist der NULL-Pointer. Im Pointer-Kontext wird die int-Konstante 0 in eine spezielle Null-Adresse umgewandelt, die als Erkennungsmarkebeim Umgang mit Adressen verwendet wird.
Suffixe müssen nur selten angegeben werden:
long long ll;unsigned u;short s;
ll = -678;ll = 857322624983473ll;ll = 857322624983473; // Compiler-Warnung!ll = 1u << 31; // Suffix u erforderlich!u = 16;u = 3847772663u;s = 28433;
4.4 Zeichenkettenkonstanten 27
Der Compiler erweitert oder verengt eben die drei int-Konstanten entsprechend demZieltyp, denn die Zahlenwerte passen ja in den Wertebereich der Ziele, so daß auchkeine Information verloren geht.
Im Wesentlichen muß aufgepaßt werden, daß keine int-Konstante in ihren negativenZahlenwertebereich geschoben wird oder Ähnliches. Und Warnungen des Compilerssollten abgestellt werden durch entsprechende Korrekturen im Kode, nicht durchAbschaltung per Option.
4.3 Zeichenkonstanten
’A’ ’#’ ’ä’ ’\’’ ’\x41’ ’\0’ L’x’ (wchar_t)
Zeichenkonstanten haben den Typ int und den Zahlenbereich: -128...127.Mit entsprechender Compiler-Option:(int)(unsigned char)’x’ und 0...255.Manche Compiler akzeptieren keine Zeichen >127, wie z. B. ’ü’. Es müssen dannandere Darstellungen des gewünschten Wertes verwendet werden:’\x81’ oder ’\201’ oder 0201 oder 129 oder 0x81.Die folgenden Zeichen-Ersatzdarstellungen sind im nächsten Abschnitt erklärt:
\’ \" \? \\ \a \b \f \n \r \t \v \ooo \xhh
4.4 Zeichenkettenkonstanten
Zeichenkettenkonstanten werden von einem Paar Doppelapostroph eingefaßt:
"Die Programmiersprache \"C\" hat wenige Schlüsselwörter."
L"Die Programmiersprache \"C++\" hat mehr davon." //wchar_t
und haben (im Pointer-Kontext) den Typ: const char*. Beispielsweise ein Aus-druck: "abcdef"+2 ist möglich, um auf die Zeichen ab c zuzugreifen.char c= "abcdef"[2]; ist ebenfalls möglich. Der Compiler fügt beim Speichernein Null-Zeichen ’\0’ an, "abc" belegt also 4 Bytes im Speicher.In Zeichenkettenkonstanten soll nicht hineingeschrieben werden! Einige Compilerermöglichen das zwar per Option, aber es ist mittlerweile kaum portabel. Ein Aus-weg ist: char A[]= "abc";
28 4 C-Zeichensatz, Konstanten, Kommentare
printf("aaaaaaa" "bbb""ccccc" "\n" );
printf("aaaaaaabbbccccc\n");
Die beiden Funktionsaufrufe ergeben die gleiche Ausgabe, da der Compiler die erste,in Teilstücken angegebene Zeichenkette automatisch zusammenfügt. Es gibt eineweitere – schlechtere – Möglichkeit durch den Preprocessor, mit einem \ direkt vordem Zeilenvorschub:
printf("aaaaaaa\bbb\ccccc\\n" );
Die folgenden Zeichen-Ersatzdarstellungen können in Zeichen- und Zeichenketten-Konstanten verwendet werden. Sie ermöglichen das Schreiben von unsichtbarenSteuerzeichen und dienen der Aufhebung der Spezialbedeutung von Zeichen (Mas-kierung):
\n Zeilenvorschub (LF,NL)\r Wagenrücklauf (CR,^M)\t Tabulator\b Rückschritt (Backspace)\a Klingelzeichen (Bell,Beep,Alarm,Alert)\f Seitenvorschub (Formfeed,^L)\v Vertikal Tabulator\\ \ ’\\’ "\\"\’ ’ ’\’’\" " "\""\0 Null-Zeichen, Wert==0\ooo Oktal-Escape-sequenz\xhh Hex-Escape-sequenz
Es ist zu beachten, daß die Oktal-Sequenz 1 bis 3 Oktal-Ziffern enthalten kann, dieHex-Sequenz jedoch 1 bis n Hex-Ziffern/-Zeichen! Beide Sequenzen werden beimersten unpassenden Zeichen beendet, aber nur die Oktal-Sequenz hat eine anzahlbe-zogene Längenbegrenzung.
Mit \000...\377 oder \x00...\xFF kann der gesamte Zeichensatz angegebenwerden. Direkte Angabe von Zeichen mit Wert >127 (’ä’ "öü" ...) ist nicht vollportabel!
Enumerationen (� 89) gehören ebenfalls zu den Konstanten.
4.5 Kommentare 29
4.5 Kommentare
/* Dies ist ein Kommentar */
// Dies ist ein Zeilenkommentar
Alles zwischen /* und */ wird ignoriert, auch Zeilenvorschübe. Sobald /* ge-sichtet wurde, wird nach */ gesucht; es ist auf mögliche Verschachtelung zu achten,die zu Fehlerhaftigkeit führt.
Zeilenkommentare gelten bis zum Zeilenende, ausschließlich des Zeilenvorschubs.In C gültig ab C99.
Achtung!:
a= b + c - d / 70;
a= b + c - d //*70*/ 80;
Eine Funktion, die beispielsweise "10001110100111011" erzeugt, die einen Inte-gerwert in einen Dualzahl-String umwandelt:
int ultob_F(byte *buf, ulong u){register byte *bp= buf;register int l=1;int l0;if (u) l=sizeof(u)*CHAR_BIT;while (u && !(u&~((~0ul)>>1))) u<<=1, --l;l0=l;do*bp= u&~((~0ul)>>1) ? ’1’ : ’0’;
while (++bp,u<<=1, --l>0);*bp=0;return (l0);
}
Der Zielpuffer muß mindestens sizeof(ulong)*CHAR_BIT+1 Byte groß sein. Füh-rende 0-Bits werden übersprungen; Führende "000" können an anderer Stelle indi-viduell hinzugefügt werden. Das ist konzeptionell besser. Mindestens "0" oder "1"wird geschrieben. Die String-Länge wird retourniert.
Der Operand zu u&, sizeof(xyz) und CHAR_BIT sind konstante Ausdrücke undKonstanten, die zur Kompilierzeit berechnet werden! (� 184)
30 4 C-Zeichensatz, Konstanten, Kommentare
Die Verwendung der Ziffernwerte ’0’ bis ’9’ ist nachfolgend portabel:
#define ZIFFER(N) while (u>=N) u-=N, ++c, f=1; \if (c>’0’ || f) *a++ = c, c=’0’;
int itoa_F(byte *a0, int i){register unsigned u;register byte *a= a0;register byte c=’0’, f=0;
if (i<0) i= -i, *a++=’-’;u=(unsigned)i;
if (u<1000U) goto U100;# if defined(UNIX) || defined(DOS32)if (u<100000U) goto U10000;ZIFFER(1000000000u);ZIFFER( 100000000u);ZIFFER( 10000000u);ZIFFER( 1000000u);ZIFFER( 100000u);U10000:;
# endifZIFFER( 10000u);ZIFFER( 1000u);U100:;ZIFFER( 100u);ZIFFER( 10u);*a++=(byte)u+’0’;*a=0;return (a-a0);
}#undef ZIFFER
Um die Aufgabenstellung dieser Funktion (int → ascii) zu lösen, reicht im Nor-malfall eine ganz kleine Funktion mit Division und Restwertdivision pro Ziffer aus(� 36). Diese Variante hier arbeitet schneller. Noch deutlich effizienter ist eine Va-riante, die dem gleichen Konzept folgt wie die auf � 74 präsentierte Funktion, diejedoch 200 Zeilen lang ist und daher nicht abgedruckt werden kann. (� 184)