[xpert.press] moderne c-programmierung || c-zeichensatz, konstanten, kommentare

6
4 C-Zeichensatz, Konstanten, Kommentare 4.1 Zeichenmenge abcdefghijklmnopqrstuvwxyz ABCDEFGHIJKLMNOPQRSTUVWXYZ _0123456789 Obenstehend diejenigen Zeichen, die für Namen (und Konstanten) verwendet wer- den dürfen. Der Unterstrich _ gilt als Buchstabe. C unterscheidet glücklicherweise zwischen 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 Ziernzeichen "0123456789" müssen in der gezeigten Reihenfolge eine Dierenz von je +1 aufweisen! Deren absolute und alle anderen Werte sind plattform-spezifisch. Beispielsweise die Zeichen a...z müssen folglich keineswegs aufsteigende Werte noch Dierenzen 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 nicht Schlüsselworte oder Operatoren (aus zwei oder mehr Zeichen) oder sonstige Syn- taxeinheiten zerteilen. In einer Preprocessor-Zeile ab # dürfen nur Leerzeichen und h-Tab als White space verwendet werden. An manchen Stellen müssen Zwischen- raumzeichen stehen, um eine Trennwirkung zu erzielen: unsigned long kann nicht 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

Upload: helmut

Post on 11-Dec-2016

217 views

Category:

Documents


3 download

TRANSCRIPT

Page 1: [Xpert.press] Moderne C-Programmierung || C-Zeichensatz, Konstanten, Kommentare

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

Page 2: [Xpert.press] Moderne C-Programmierung || C-Zeichensatz, Konstanten, Kommentare

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;

Page 3: [Xpert.press] Moderne C-Programmierung || C-Zeichensatz, Konstanten, Kommentare

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";

Page 4: [Xpert.press] Moderne C-Programmierung || C-Zeichensatz, Konstanten, Kommentare

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.

Page 5: [Xpert.press] Moderne C-Programmierung || C-Zeichensatz, Konstanten, Kommentare

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)

Page 6: [Xpert.press] Moderne C-Programmierung || C-Zeichensatz, Konstanten, Kommentare

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)