nfet schrieb:> Ja, aber mit der ersten Schreibweise macht man klarer, dass man> gedenkt> sein char als Buchstaben und nicht als Zahl zu benutzen.
Hab ich mir gedacht. Besten Dank.
nfet schrieb:> Ja, aber mit der ersten Schreibweise macht man klarer, dass man gedenkt> sein char als Buchstaben und nicht als Zahl zu benutzen.
Dann ist das "unsigned" freilich nicht sinnvoll.
ASCII-Zeichen: char
Ganzzahlen von -128 bis +127: signed char
Ganzzahlen von 0 bis 255: unsigned char
Dirk B. schrieb:> Hier ist das aber etwas merkwürdig, da man für Zeichen nur char als> Typ verwenden sollte.
Das Buch ist alt und enthält selbst für sein Alter ziemliche
oldschool-Konstrukte. Im Vorwort wird zwar darauf herumgeritten, dass es
um sinnvolle Software-Entwicklung geht und nicht nur um das C-Lernen,
aber es kommen ständig Kracher wie
1
main()
2
{
3
printf("Hello World!\n");
4
}
,
1
#define SWAP(a, b) {int swap = a; a = b; b = swap;}
oder Beispielprogramme, die ausschließlich (unnötig) globale Variablen
enthalten, vor.
Koe schrieb:> unsigned char a_uchar_= '\0';> unsigned char a_uchar_= 0;> Bewirkt doch das selbe, oder nicht ?
NEIN,
das eine ist 0x00 oder auch bekannt als NULL,
das andere ist 0x30 ASCII für die Zahl Null.
Damit ist es ein Unterschied.
In der Tat ist es sinnvoll, char zu verwenden und nicht signed oder
unsigned char, solange man wirklich Zeichen damit speichern will.
Schon aus dem einfachen Grund, weil alle einschlägigen
Bibliotheksfunktionen nicht signed oder unsigned char, sondern halt char
verwenden und man unnötiges Casten und Gemecker vermeidet.
signed char oder unsigned char macht nur Sinn, wenn man den Typ nicht
für Zeichen benutzt, sondern konkret damit rechnet, also einfach als
kleine Zahl nutzt.
Ob der Name des Datentyps sinnvoll ist, sei dahingestellt - ist halt so.
Marc D. schrieb:> Koe schrieb:>>> unsigned char a_uchar_= '\0';>> unsigned char a_uchar_= 0;>>> Bewirkt doch das selbe, oder nicht ?>> NEIN,> das eine ist 0x00 oder auch bekannt als NULL,> das andere ist 0x30 ASCII für die Zahl Null.>> Damit ist es ein Unterschied.
wo sieht du hier ein "0x30 ASCII für die Zahl Null"??
Marc D. schrieb:> NEIN,> das eine ist 0x00 oder auch bekannt als NULL,> das andere ist 0x30 ASCII für die Zahl Null.>> Damit ist es ein Unterschied.
Unfug, erst selbst C lernen.
S.J. hat es korrekt formuliert.
unsigned char a_uchar_= '0';
würde die Variable mit 0x30 für die ZIFFER NULL initialisieren.
Peter II schrieb:> wo sieht du hier ein "0x30 ASCII für die Zahl Null"??
Asche auf das Haupt deren die unwürdig sind und nicht nachdenken
bevor sie schreiben: namentlich Mich.
Ist natürlich Schwachsinn was ich da verzapft habe ohne nachzudenken,
oder richtig zu lesen.
S.J hat natürlich recht.
Marc D. schrieb:> Asche auf das Haupt deren die unwürdig sind und nicht nachdenken> bevor sie schreiben: namentlich Mich.
Ist ja erst Dienstag. Die Woche ist noch lang, hast also noch Zeit
wachzuwerden :-)
Matthias L. schrieb:> Gibt es auch negative (ASCII-)Zeichen?
Bei ASCII: nein.
Sonst: möglicherweise. Das ist Darstellungssache. (Wie wird das
Bitmuster als Zahlenwert interpretiert)
Dirk B. schrieb:> Sonst: möglicherweise. Das ist Darstellungssache. (Wie wird das> Bitmuster als Zahlenwert interpretiert)
Logisch. Letztendlich sind Strings nur Zahlenarrays die als ASCII
interpretiert werden. Ich verwende dafür immer ein u8.
Warum sollte man da signed verwenden?
Matthias L. schrieb:> Warum sollte man da signed verwenden?
weil es Compiler geben kann, die char als signed definiert haben. Damit
musst du sonst immer casten.
Marc D. schrieb:> das eine ist 0x00 oder auch bekannt als NULL,
NULL ist für Pointer reserviert. Das ist also Unfug:
unsigned char a_uchar_= NULL;
obwohl ich das gelegentlich schon gesehen habe.
>> Gibt es auch negative (ASCII-)Zeichen?>Bei ASCII: nein.
Die USA benutzen nur 7 Bit - ob das 8. Bit als negative Zahl
interpretiert wird ist denen egal. In Deutschland wird das 8. Bit für
Umlaute benutzt.
Der größte Murks, den jemals ein Amerikaner erfunden hat.
1
int[] characterType = {....};
2
char c = getc();
3
int type = characterType[c];
Funktioniert mit 7 Bit Ascii einwandfrei. Ob es in Deutschland
funktioniert, hängt davon ab, ob der Compiler char als signed oder
unsigned behandelt.
So ein verdammter Murks schrieb:>>> Gibt es auch negative (ASCII-)Zeichen?>>Bei ASCII: nein.>> Die USA benutzen nur 7 Bit - ob das 8. Bit als negative Zahl> interpretiert wird ist denen egal. In Deutschland wird das 8. Bit für> Umlaute benutzt.
Kommt drauf an was für ein Zeichensatz verwendet wird. Die gängigen
(UTF-8 und UTF-16) brauchen 2 Byte für Umlaute. ISO-Codepages sind eher
Altlasten die nicht mehr verwendet werden sollten.
Matthias L. schrieb:> Dirk B. schrieb:>> Sonst: möglicherweise. Das ist Darstellungssache. (Wie wird das>> Bitmuster als Zahlenwert interpretiert)>> Logisch. Letztendlich sind Strings nur Zahlenarrays die als ASCII> interpretiert werden. Ich verwende dafür immer ein u8.>> Warum sollte man da signed verwenden?
Man benutzt weder explizit signed noch unsigned, sondern einfach nur
char. Was der Compiler dafür als interne Repräsentation verwendet, kann
einem völlig egal sein, da man damit sowieso nicht rechnet.
Also ist ein char mit Vorzeichen genauso sinnvoll oder sinnlos wie einer
ohne.
So ein verdammter Murks schrieb:> Der größte Murks, den jemals ein Amerikaner erfunden hat.> int[] characterType = {....};> char c = getc();> int type = characterType[c];>> Funktioniert mit 7 Bit Ascii einwandfrei. Ob es in Deutschland> funktioniert, hängt davon ab, ob der Compiler char als signed oder> unsigned behandelt.
Deshalb macht man das auch nicht so. Man muß es in C halt machen, wie in
vielen anderen Sprachen auch: Wenn ich einen Zahlenwert haben will, muß
ich eine geeignete Typkonvertierung machen. Der einzige Unterschied ist,
daß man bei C (anders als z.B. in Pascal) auch direkt an den internen
Wert der char-Variable kommt.
So ein verdammter Murks schrieb:> Der größte Murks, den jemals ein Amerikaner erfunden hat.>> int[] characterType = {....};> char c = getc();> int type = characterType[ c];
Du meinst wahrscheinlich
1
intcharacterType[]={....};
2
charc=getchar();
3
inttype=characterType[c];
getchar liefert ein int, als Array-Index wird ein size_t erwartet.
Deklariert man c als einen diese beiden Typen, funktioniert das Ganze
auch mit 8-Bit-Zeichencodierungen. char als Datentyp für c ist hier
aber völlig fehl am Platz.
Yalu X. schrieb:> getchar liefert ein int, als Array-Index wird ein size_t erwartet.
Wie ist dass zu verstehen? Meines wissens gibt es keine Vorgabe mit
welchen arithmetischen Datentypen die Arraysubscription durchgeführt
werden sollte. Es gillt sogar ""[0] ist equivalent zu *(""+0) und zu
0[""]
> Deklariert man c als einen diese beiden Typen, funktioniert das Ganze> auch mit 8-Bit-Zeichencodierungen.
Das trifft zu, aber ich finde Code sollte immer funktionieren, und nicht
nur wenn gewisse Annahmen zutreffen. Ich würde c in diesem Beispiel als
'unsigned int' definieren, da dieser Datentyp gleichgross ist wie ein
int, aber nicht negativ sein kann, und mit sizeof prüfen ob etwas an dem
Arrayindex steht:
Yalu X. schrieb:> getchar liefert ein int,
Schon richtig.
Aber der Hintergrund ist ein anderer.
getchar liefert prinzipiell schon einen char (promomted nach int), hat
aber die Notwendigkeit auch EOF liefern zu können. Und damit ist der
Wertebereich, den getchar liefern können muss um 1 über dem Wertebereich
von char. Deshalb ist der Return Wert ein int.
> Deklariert man c als einen diese beiden Typen, funktioniert das Ganze> auch mit 8-Bit-Zeichencodierungen.
Da EOF meistens als -1 codiert ist, gibt es dann allerdings Probleme,
wenn das nicht vorher ausgefiltert wird.
Daniel A. schrieb:> Yalu X. schrieb:>> getchar liefert ein int, als Array-Index wird ein size_t erwartet.>> Wie ist dass zu verstehen? Meines wissens gibt es keine Vorgabe mit> welchen arithmetischen Datentypen die Arraysubscription durchgeführt> werden sollte.
Ja, es gibt lediglich die Vorgabe, dass der Index "integer type" haben
muss. Damit ist von signed char bis zu long long int alles erlaubt.
Aber natürlich sollte der Wertebereich des verwendeten Typs groß genug
sein, um die gesamte Array-Größe abzudecken. Der Wertebereich eines
vorzeichenbehafteten char reicht aber üblicherweise nur bis 127. Mit
size_t ist man aber immer auf der sicheren Seite, da kein Array mehr
als size_t Elemente enthalten kann (sonst würde der sizeof-Operator
nicht mehr funktionieren).
Karl H. schrieb:> Schon richtig.> Aber der Hintergrund ist ein anderer.
Auf jeden Fall ist es in obigem Beispiel unsinnig, ein char zu nehmen,
da dieses dort weder als Array-Index taugt noch die Unterscheidung
zwischen dem Zeichen '\xff' und EOF erlaubt (wenn man eine entsprechende
Abfrage einbauen wollte).
Yalu X. schrieb:> Ja, es gibt lediglich die Vorgabe, dass der Index "integer type" haben> muss. Damit ist von signed char bis zu long long int alles erlaubt.
Nicht zu vergessen: bool.
Das ist auch ein "integer type".
Klugscheißer schrieb:> Nicht zu vergessen: bool.> Das ist auch ein "integer type".
sollte aber auch kein Problem darstellen. ein bool was auf int gewandelt
wird, wird eine 0 oder eine 1.
Marc D. schrieb:> Koe schrieb:>>> unsigned char a_uchar_= '\0';>> unsigned char a_uchar_= 0;>>> Bewirkt doch das selbe, oder nicht ?>> NEIN,> das eine ist 0x00 oder auch bekannt als NULL,> das andere ist 0x30 ASCII für die Zahl Null.
Beides leider falsch. Ersteres ist bekannt als NUL - mit einem L. Mit
NULL, meist im Zusammenhang mit "Nullpointern" zu sehen, hat das
überhaupt nichts zu tun.
Siehe auch:
http://man7.org/linux/man-pages/man7/ascii.7.html
Das andere ist nicht 0x30 ASCII, denn dann hätte man es '0' (mit
Hochkommata) schreiben müssen. Wurde es aber nicht. 0 ist 0 und nix
anderes. Beide Zuweisungen ergeben denselben Code.
Frank M. schrieb:> Beides leider falsch. Ersteres ist bekannt als NUL - mit einem L. Mit> NULL, meist im Zusammenhang mit "Nullpointern" zu sehen, hat das> überhaupt nichts zu tun.
Es hätte gepasst, hätte er NULL kleingeschrieben. Denn C nennt das
offiziell den "null character".
Frank M. schrieb:>> das eine ist 0x00 oder auch bekannt als NULL,>> das andere ist 0x30 ASCII für die Zahl Null.>> Beides leider falsch. Ersteres ist bekannt als NUL - mit einem L. Mit> NULL, meist im Zusammenhang mit "Nullpointern" zu sehen, hat das> überhaupt nichts zu tun.
Das ist durchaus als Definition für NULL erlaubt:
1
#define NULL 0x00
Allerdings nutzt man NULL beser nur im Zeigerkontext.
Rolf M. schrieb:> Das ist durchaus als Definition für NULL erlaubt:>
1
>#defineNULL0x00
2
>
Natürlich ist das als NULL erlaubt. Ist auch meistens genau so
definiert, siehe <stdio.h>.
Aber das Zeichen '\0' heisst NUL (mit einem L), so wie
'\a' BEL (bell)
'\b' BS (backspace)
'\t' HT (horizontal tab)
'\n' NL (newline)
'\v' VT (vertical tab)
'\f' FF (formfeed)
'\r' CR (carriage return)
heisst.
Also ausführlich:
'\0' NUL (null character)
Und NUL (das Zeichen) hat nichts mit NULL (dem Nullpointer) zu tun. Dass
beide Werte in den meisten C-Programmierumgebungen den numerischen Wert
0 haben, ist purer Zufall - aber meist bequem für den Programmierer.
Deshalb sollte man, wenn man das Zeichen meint, auch '\0' schreiben,
z.B.
Rolf M. schrieb:> Das ist durchaus als Definition für NULL erlaubt:
Yep. Aber das ist ebenfalls zulässig - und macht sich als Ersatz von
'\0' dann nicht mehr sonderlich gut:
#define NULL ((void *)0)
http://c-faq.com/null/nullor0.html
Da frage ich mich wie viel Asche Ihr noch über mich aus kippen wollt :-)
Aber ich bin ja selber Schuld, habe aber auch wieder was gelernt.
Bisher bin ich davon ausgegangen das
null = NULL = NUL = \0 = 0x00 = 0
und damit NUL nur eine Abkürzung von NULL ist.
Danke vor allem Frank für die kleine Schulung in Sachen NULL