# Wie wird in Java ein Char-Array terminiert ?



## ernst (21. Mrz 2017)

Hallo allerseits,
in der Programmiersprache C wird ein Feld mit dem Dtentyp char immer mit \0 terminiert.
Wie verhält sich dies in Java.
Angenommen, man hat ein Feld:
char[] feldChar = new char[1000];
und will jetzt die 2 Zeichen a und b reinschreiben.
Wird das dann so gemacht?
feld[0] ='a';
feld[1] ='b';
feld[2] ='\0';
Wenn nein, wie dann ?

mfg
Ernst


----------



## mrBrown (21. Mrz 2017)

Das ist Java, wenn man Strings braucht, nutzt man Strings (die man nicht händisch terminieren muss) 

Edit: 0 Bzw \0 in nem char-Array bringen nichts, wenn man es in einen String umwandelt


----------



## ernst (21. Mrz 2017)

>
>Das ist Java, wenn man Strings braucht, nutzt man Strings (die man nicht händisch terminieren muss) 
>
Ok, ich will aber - zu Testgründen - mal mit Char-Arrays arbeiten.
>
>Edit: 0 Bzw \0 in nem char-Array bringen nichts, wenn man es in einen String umwandelt
>
Angenommen, man hat ein Feld:
char[] feldChar = new char[1000];
das komplett mit Zeichen gefüllt ist (z.B. mit Gedichten)
Ich will jetzt die ersten zwei Zeichen "ausgeben".
Ich mache Folgendes:
feld[2] ='\0';
Welche Java-Methoden nutzen dieses \0 ?
D.h. zum Beispiel:
- Ausgabe der Zeichen bis \0 auf dem Bildschirm ?
- Umwandeln der Zeichen bis \0 in einen String ?
usw.

mfg
Ernst


----------



## mrBrown (21. Mrz 2017)

ernst hat gesagt.:


> >
> Angenommen, man hat ein Feld:
> char[] feldChar = new char[1000];
> das komplett mit Zeichen gefüllt ist (z.B. mit Gedichten)
> ...



Keine (zumindest keine mir bekannten aus java.lang).

Das wirst du händisch lösen müssen. (und ehrlich gesagt fällt mir kein Zweck dafür ein, außer den C-Weg in Java umsetzen zu wollen)


----------



## ernst (21. Mrz 2017)

mrBrown hat gesagt.:


> Keine (zumindest keine mir bekannten aus java.lang).
> 
> Das wirst du händisch lösen müssen. (und ehrlich gesagt fällt mir kein Zweck dafür ein, außer den C-Weg in Java umsetzen zu wollen)


Also wird \0 in Java _nicht_ zur Terminierung eines Char-Arrays benutzt.
Ist das richtig ?

mfg
Ernst


----------



## mrBrown (21. Mrz 2017)

ernst hat gesagt.:


> Also wird \0 in Java _nicht_ zur Terminierung eines Char-Arrays benutzt.
> Ist das richtig ?
> 
> mfg
> Ernst


Es wird auch in C nicht zur Terminierung von char-Arrays benutzt, sondern zur Terminierung von char-Arrays, die Strings darstellen.

Und ja, in Java ist das nicht nötig, sowas händisch zu machen . Arrays (und damit auch Strings) haben eine feste Länge, man muss deren Ende nicht anzeigen, weil man ehh nicht drüber hinaus lesen und schreiben könnte.


----------



## Thallius (21. Mrz 2017)

Wenn du nur die ersten beiden Zeichen ausgeben willst, dann machst du ein subString(0, 2).


----------



## Tobse (21. Mrz 2017)

mrBrown hat gesagt.:


> Und ja, in Java ist das nicht nötig, sowas händisch zu machen . Arrays (und damit auch Strings) haben eine feste Länge, man muss deren Ende nicht anzeigen, weil man ehh nicht drüber hinaus lesen und schreiben könnte.



Ich denke es ist mal wichtig zu erwähnen, warum das so ist. In C ist ein String ja meistens ein char*. Die Syntax charArray[index] ist nur Sugar für *(charArray + index * sizeof(char)). In Java selbst gibt es aber keine Pointerarithmetik. In Java ist jedes Array ein struct aus der Länge des Arrays und einem Pointer zum ersten Eintrag. Die JVM macht die Pointer-Arithmetik und überprüft bei *jedem *Zugriff, dass der Index kleiner als die Größe des Arrays ist. Ist das nicht der Fall, fliegt eine ArrayIndexOutOfBoundsException.

Strings in Java sind vollwertige Objekte. Wenn dir das noch kein Begriff ist, kläre das zuerst. Strings liegen in Java *immer *auf dem Heap. Jeder String hat ein char[], welches die Buchstaben enthält, die den String darstellen. Ein String wird in Java also nicht terminiert; die Größe ist immer gespeichert und man kann auch nur innerhalb der Größe darauf zugreifen; ein Terminierendes Spezial-Byte ist nicht nötig.

Wenn du C++ kennst: Der Java String ist sehr ähnlich zum std::string in C++, welcher im Endeffekt ja auch ein std::vector<char> ist.

Als kleines Beispiel: In Java kann ein String problemlos \0 enthalten (anders als in C natürlich):


```
String s = "abc\u0000def";
assert s.length() == 7;
```

Wohingegen in C ja folgendes auftritt:

```
char* s = "abc\u0000def"
println(strlen(s)); // gibt 3 aus
```


----------



## ernst (21. Mrz 2017)

Hallo Tobse,
Danke für die Infos.


Tobse hat gesagt.:


> Strings in Java sind vollwertige Objekte. Wenn dir das noch kein Begriff ist, kläre das zuerst. Strings liegen in Java *immer *auf dem Heap....
> [/CODE]


Beispiel:
char[] feldChar = new char[1000];
So wie ich das verstehe befindet sich dann in der Variable feldChar eine Adresse, die auf dem Stack liegt.
Diese Adresse zeigt auf die Zeichenfolge (String), die auf dem Heap liegt.
Ist das so korekt ?

mfg
E


----------



## Tobse (21. Mrz 2017)

Nein, das stimmt so nicht.

Auf dem Heap liegt dann soetwas:


```
struct CharArray {
   int size;
   char* first;
}
```

In der Variable feldChar (auf dem Stack) liegt dann ein Pointer auf dieses Datenstruktur (auf dem Heap). Ich kenne da die genauen Verhältnisse nicht; aber von der Semantik her ist es genau das.

EDIT:
Mit Strings verhält es sich nochmal anders:

Schreibst du in Java

```
String s = "foo";
```

Dann wird eine neue* Instanz hiervon auf den Heap gelegt:


```
struct String {
    CharArray* chars;
    // .. womöglich weitere Daten, weiss ich nicht ...
}
```

In der Stack-Variable s ist dann ein Pointer auf diese Datenstrukur im Heap.

---
* Die JVM versucht zu erreichen, dass jeder String nur einmal im Heap liegt. Das klappt nicht immer, aber in c.a. 80% der Fälle. Wenn du einen String anlegst schaut die JVM also erstmal in den Heap. Wenn da schon ein String liegt der identisch zu dem neuen ist, wird einfach der existierende referenziert.
Strings sind in Java immutable. Ein String kann nicht verändert werden, wenn er einmal angelegt wurde. Alle String-Manipulationen haben eine neue String Instanz zur folge (oder eine Referenz auf einen bestehenden, identischen).


----------



## ernst (21. Mrz 2017)

Hallo Tobse,


Tobse hat gesagt.:


> Nein, das stimmt so nicht.
> Auf dem Heap liegt dann soetwas:
> 
> ```
> ...


und first zeigt dann auf die endgültige Zeichenfolge, die auf dem Heap liegt.
Ist das korrekt ?




Tobse hat gesagt.:


> EDIT:
> Mit Strings verhält es sich nochmal anders:
> Schreibst du in Java
> 
> ...


und chars zeigt dann auf die endgültige Zeichenfolge, die auf dem Heap liegt.
Ist das korrekt ?

mfg
E


----------



## mrBrown (21. Mrz 2017)

ernst hat gesagt.:


> und first zeigt dann auf die endgültige Zeichenfolge, die auf dem Heap liegt.
> Ist das korrekt ?


Ja



ernst hat gesagt.:


> und chars zeigt dann auf die endgültige Zeichenfolge, die auf dem Heap liegt.
> Ist das korrekt ?


Nein, chars zeigt auf ein CharArray, in dem first auf die Zeichenkette zeigt.

Wobei, wenn ichs richtig im Kopf hab, String noch mal eigene Indizes für die Zeichenkette hat, sodass es sein kann, das der eigentliche String erst in der Mitte des Arrays beginnt und schon vor Ende des Arrays endet.


----------



## thecain (21. Mrz 2017)

Ich würde es mir einfach machen und gar nicht versuchen C Logik auf Java anwenden zu wollen. String ist String. Chat Arrays mit \0 gibt es nicht. Ende. Alles andere ist Theorie und in der Anwendung nur sehr selten von Belang


----------



## Xyz1 (21. Mrz 2017)

Deswegen hinkt der Vergleich von @Tobse auch gewaltig (und stinken tut er auch noch) - aber das habe ich schon in dem anderen Thema geschrieben.
Strings sind nichts als Klassen, mit ein paar Eigenschaften...


----------



## Meniskusschaden (21. Mrz 2017)

DerWissende hat gesagt.:


> Deswegen hinkt der Vergleich von @Tobse auch gewaltig (und stinken tut er auch noch) - aber das habe ich schon in dem anderen Thema geschrieben.


So abwegig finde ich den Vergleich eigentlich nicht.


DerWissende hat gesagt.:


> Strings sind nichts als Klassen, mit ein paar Eigenschaften...


Aber eine dieser Eigenschaften ist eben ein Char-Array:

```
public final class String
    implements java.io.Serializable, Comparable<String>, CharSequence {
    /** The value is used for character storage. */
    private final char value[];
...
```


----------



## mrBrown (22. Mrz 2017)

DerWissende hat gesagt.:


> Deswegen hinkt der Vergleich von @Tobse auch gewaltig (und stinken tut er auch noch) - aber das habe ich schon in dem anderen Thema geschrieben.
> Strings sind nichts als Klassen, mit ein paar Eigenschaften...


Und Klassen sind halt nichts anderes als structs und Pointer-Arithmetrik...von da her hinkt hier eher was anderes...


----------

