Frage zu; wie viele Zeichen in "Char" möglich? (C#)

Hallo.

Ich hoffe das ich hier richtig bin. Ich habe eine Frage, auf dessen Antwort ich gerade nicht komme. Ich stehe echt auf dem Schlauch.
Der Datentyp „Char“ ist in C# 2 byte groß?! Wenn ich’s richtig verstanden habe ist das für UNICODE nötig.
aber warum kann man in dem Datentyp „Char“ genau 2^31 Zeichen speichern?
Aus was ergibt sich das 2^31?

Ich habe jetzt versucht das zu Googlen, versucht selbst darauf zu kommen…aber nichts.
Stehe auf m Schlauch.
Und ich bin mir sicher, das ich mich am Ende, sobald ich eine Antwort bekomme, darüber ärgere das ich nicht selbst drauf gekommen bin.

Würde mich über Antwort freuen.

Ps:
Entschuldigt wenn ich meine Frage an falscher stelle gestellt habe.

Mit grüßen

Deine Verwirrung kommt daher, dass Unicode nicht das gleiche wie UTF-16 ist.

Hier ist die Referenz: https://docs.microsoft.com/en-us/dotnet/csharp/language-reference/builtin-types/char

Danach kann ist ein Char 2 byte = 16 bit lang, kann also 2^16 verschiedene „Zustände“ speichern, nicht 2^31.

Unicode ist kompliziert, es gibt verschiedene Versionen, und wenn man immer den vollen Zeichenvorrat mitschleppen will, müssten die Zeichen - wie du schon bemerkt hast - länger sein. Deshalb gibt es Codierungen wie UTF-16, das immer nur 2 byte lang ist, für seltene Zeichen aber mehrere Chars braucht (u.U. sogar länger als es in Unicode wäre). Dazu gibt es Bytefolgen, die nicht als Zeichen, sondern als „übrigens, hier kommt noch was hinterher“ interpretiert werden.

Im Prinzip erkauft man sich, dass „normale“ Zeichen kurz sind damit, dass „seltene“ Zeichen länger sind und intern eine Sonderbehandlung brauchen.

Hallo.
Ich danke erst einmal für deine Antwort und muss mich gleichzeitig entschuldigen.
ich habe einen Satz falsch verstanden. Es geht um String.

String soll 2^31 Zeichen speichern können, und meine Frage sollte dann lauten warum string 2^31 Zeichen speichern kann.

Der Satz aus dem Buch
Zitat;

char beschränkt sich auf ein Zeichen. Um eine Zeichenkette, die sich aus keinem oder bis zu maximal ca. 2^31 Einzelzeichen zusammensetzt, zu speichern oder zu bearbeiten, deklarieren Sie eine Variable vom Datentyp string.

Ich war wohl schon zu müde um zu erkennen das es um String geht, die Frage aber bleibt immer noch bestehen. Ich ärgere mich das ich mir die Frage nicht selbst beantworten kann.

Resultiert das Ergebnis daraus das 2^31 Zeichen auf einem 32Bit System gespeichert werden können. aber warum dann 2^31 wenn 32Bit…
Hat es was mit dem Einer- bzw. Zweierkomplement zu tun?
2^32 -1 weil die Null mit einbezogen wird?

Oder hab ich mir da jetzt was in den Kopf gesetzt, was überhaupt keinen Sinn mehr macht?
Danke für die schnelle Antwort.
Grüße
Steffen

es wird wohl damit zutun haben, dass eine String intern ein char-array verwendet. Da int signed ist, und als Index nur positive Werte verwendet werden können bleiben eben 2^31 mögliche Werte übrig.

LG

2^31 deswegen, weil eines der 32 Bit vom Stadart-Datentyp int für das Vorzeichen drauf geht und nur positive Indices für das Char-Array in Frage kommen, wie das AmunRa bereits erwähnte. Es ist also 2^(32-1), weil 32-1=31 Bit und nicht (2^32)-1, weil die 0 mit einbezogen wird.

Ja, es geht um die interne Adressierung eines Char-Arrays in C#…

Ein vorzeichenbehafteter Integer besteht aus 32 Bit. Der Wertebereich umfasst -(2^31) bis +((2^31)-1). Die -1 rührt daher, dass die 0 mit der Binärfolge 0000… dargestellt wird. Also steht für die interne Adressierung des Char-Arrays 31 Bit zur Verfügung. +((2^31)-1) ist nach dem Taschenrechner in Zahlen 2.147.483.647(*) - es gibt also meistens ausreichend Platz für auch sehr lange Zeichenketten…

lg :slight_smile:

*: +1, wenn Arrays in C# 0-indexbasiert sind, das weiß ich aber nicht genau; allerdings fangen Array-Elemente meist mit dem Index 0 an. Eine kurze Suche (https://www.geeksforgeeks.org/c-sharp-arrays/) hat aber nun ergeben, dass der „lower bound“ wohl 0 ist.

Um das „aus der anderen Richtung“ zu beantworten: Ein String ist, vereinfacht gesagt, eine Folge von Zeichen (chars). Und eigentlich soll die beliebig lang sein können. Zehn Zeichen. Ein Million Zeichen. Eine Millarde Zeichen. Drölfzig Zilliarden Zeichen. Aber in der Praxis ist es eben so, dass es nicht „beliebig“ viele Zeichen sein können. Bei C# sind es offenbar höchstens ca. 2^31 Zeichen.

Der Grund dafür hängt sicher indirekt damit zusammen, dass bis vor einigen Jahren PCs meistens „32bit“ hatten, und bei der Frage, was genau das bedeutet (oder warum das so ist) könnte man beliebig weit in Details gehen. Aber vereinfacht gesagt: Der Computer kennt (gaaanz intern) die Speicheradresse, an der der String anfängt, und auf einzelne Zeichen kann man dann zugreifen, indem man zu dieser Speicheradresse einen „offset“ dazurechnet. Und (ganz, ganz tief unten in der Hardware) war (oder ist) das besonders effizient und einfach möglich, wenn dieser „offset“ mit einer 32bit-Zahl dargestellt werden kann.

(Man könnte bei so einer abstrakten High-Level-Sprache wie C# auf diese ~„durch die Hardware vorgegebene“ Grenze ignorieren und z.B. Strings erlauben, die eine Trillion Zeichen enthalten. Aber … in einer normalen Anwendung sollten Strings, die länger als 2147483648 Zeichen sind, ohnehin nicht vorkommen)