Hallo, ich habe ein Programm für das Arduino Nano Board (Arduino IDE) geschrieben und habe ein Problem bzw. eine Frage zu den Datentypen. Der Code funktioniert, allerdings verstehe ich nicht genau, warum ich die Typumwandlung mit (String) machen muss. Habe auch schon ausprobiert, nur den Datentyp char zu verwenden, allerdings klappt dies auch nicht... Hat jemand eine plausible Erklärung dafür? Danke
Alessa H. schrieb: > Typumwandlung mit (String) machen muss. Damit aus einem Char-Array ein String wird (Null-Terminierung und sowas) Alessa H. schrieb: > Habe auch schon ausprobiert, nur den Datentyp char zu verwenden, Ein Char hat nur ein Byte, also ein einziges Zeichen
Alessa H. schrieb: > ich habe ein Programm Als JPEG-Bild. Klasse! Da kann man ganz toll einfach was rauskopieren oder anpassen... > allerdings verstehe ich nicht genau, warum ich > die Typumwandlung mit (String) machen muss. Weil namen und stoerung_namen unterschiedliche Datentypen sind. Das ist so, wie wenn du im Kindergartensteckspiel den Zylinder ohne Nachbearbeitung nicht durch das dreieckige Loch bekommst: https://www.amazon.de/Binnan-Geometrie-Sortierw%C3%BCrfel-Lernspielzeug-Sortierspielzeug/dp/B07H55NP7R/ref=asc_df_B07H55NP7R/ Die Typumwandlung ist diese "Nachbearbeitung" vom Kreis zum Dreieck. > Habe auch schon ausprobiert, nur den Datentyp char zu verwenden, > allerdings klappt dies auch nicht... Zeig doch mal was du da "ausprobiert" hast und was nicht geklappt hat.
:
Bearbeitet durch Moderator
Also char ist ein Zeichen. Dann ist char* ein Zeiger auf ein Zeichen. Oft zeigt ein solcher Zeiger aber halt auf das erste Zeichen einer Zeichenfolge. Damit man das Ende der Folge erkennt nutzt man in C \0, also das Ascii Steuerzeichen NUL.
1 | char hurz[12]; |
Wiederum erstellt ein Array mit Platz für 12 Zeichen. Dabei musst Du oft einen Platz für die Endekennung abzwacken. Macht dann maximal 11 Zeichen, die man sieht. Weil C seine Wurzeln in Zeiten hat, als man die Programme mit dem Locher auf Karten eingeben musste, gibt es eine Kurzschreibform. Nach der Arraydefinition von eben ist hurz ein Zeiger auf das erste Zeichen von hurz. Ausführlich &hurz[0]. Strings kamen erst mit C++ und sind Objekte. Also was völlig anderes. Einfach froh sein, dass man mit einem einfachen Typecast so ein Objekt erzeugen kann. In Deinem Fall würde ich einfach einen Zeiger auf ein Zeichen in die Struktur packen. Der Zeiger zeigt dann auf das erste Zeichen der passenden Zeichenfolge in dem Array vom Array von Zeichen. Äh und die Endekennungen setzt der Compiler übrigens in diesem Fall auch automatisch.
Funktioniert das so, wie es da in Deinem Bild gemalt ist ? Würde erwarten, dass da ein typedef oder struct nötig ist, damit der Compiler es schluckt.
Alessa H. schrieb: > Ja, das funktioniert so. Bitte poste den Quellcode! Nicht als Bild.. Auch deinen code, der nicht funktioniert. Denn: Wie soll man etwas prüfen/korrigieren, was man nicht sieht. Zudem ist die extensive Nutzung der String Klasse auf den kleinen AVRs etwas problematisch. Somit eher keine gute Idee.
fop schrieb: > dass da ein typedef oder struct nötig ist, damit der Compiler > es schluckt. Struct ist doch da. Und typedef ist in C++ so ziemlich aus dem Rennen. Wird nur noch in ganz speziellen Fällen wirklich benötigt.
Alessa H. schrieb: > warum ich die Typumwandlung mit (String) machen muss. Der billig aussehende Cast ist in Wirklichkeit recht teuer, da er mit einem Konstruktor Aufruf und dynamischer Speicherverwaltung einhergeht.
EAF schrieb: > Der billig aussehende Cast ist in Wirklichkeit recht teuer, da er mit > einem Konstruktor Aufruf und dynamischer Speicherverwaltung einhergeht. Genau deswegen benutze ich diese cast Syntax nicht mit Objekten. Mir ist lieber, wenn man direkt sehen kann, was da passiert.
Stefan ⛄ F. schrieb: > Mir ist > lieber, wenn man direkt sehen kann, was da passiert. Das ist doch kein echtes Argument.
1 | const char *kette = "Eierkuchen"; |
2 | |
3 | String feld[3]; |
4 | |
5 | feld[0] = (String)kette; |
6 | feld[1] = String(kette); |
7 | feld[2] = kette; |
8 | |
9 | for(auto &s:feld) Serial.println(s); |
Es bleibt sich (fast) gleich...... Alle 3 Wege funktionieren Und ob man (String)kette oder String(kette) schreibt, ist doch nun wirklich, in Sachen Lesbarkeit egal. Unter der Prämisse dürftest du keinerlei Fremdcode, noch nicht mal die mitgelieferten Lib Funktionen nutzen. Denn bei den meisten wirst du auch wohl nicht EXAKT wissen, was sie intern tun. Bei der Verwendung von String sollte man grundsätzlich auf dem Schirm haben, dass diese Klasse, bzw. die Instanzen, fleißig auf dem Heap rum rutschen.
EAF schrieb: > Unter der Prämisse dürftest du keinerlei Fremdcode, noch nicht mal die > mitgelieferten Lib Funktionen nutzen. > Denn bei den meisten wirst du auch wohl nicht EXAKT wissen, was sie > intern tun. Das stimmt. Im Rahmen meines Hobbies muss ich mich in der Tat nur wenig mit fremden Code befassen. Die Qt Bibliothek nutze ich oft, aber die ist so gut dokumentiert, dass ich da nur selten in den Quelltext schauen muss. Auf der Arbeit läuft es anders, aber da sind java und Go angesagt. > Bei der Verwendung von String sollte man grundsätzlich auf dem Schirm > haben, dass diese Klasse, bzw. die Instanzen, fleißig auf dem Heap > rum rutschen. Ja, das habe ich schnell auf einem ESP8266 (mit Arduino) zu spüren bekommen. Seit dem benutze ich die String Klasse dort nicht mehr. Mit den c Zeichenketten bin ich besser vertraut.
Stefan ⛄ F. schrieb: > Seit dem benutze ich die String Klasse dort nicht mehr. Hmmm... Wenn man sich selber mit dem Hammer auf die Fingerchen haut. Dann kann man völlig überziehen und sagen: Hammer ist Böse! Sowas fasse ich nie wieder an! Man könnte auch damit üben, sich kundig machen, solange bis man den richtigen Umgang mit dem Hammer gelernt hat. Es dauert etwas, bis man richtig mit Hammer und Meißel umgehen kann. Es ist sogar ein exzellentes Beispiel für einen Lernprozess. Ich halte also in Sachen String schon eine gewisse Vorsicht und Sorgfalt für nötig. Aber es grundsätzlich aus dem Leben zu streichen, nur weil man sich einmal dumm angestellt hat. Naja... Musst du selber wissen. Aber eine Empfehlung kann das nicht sein.
EAF schrieb: > Wenn man sich selber mit dem Hammer auf die Fingerchen haut. > Dann kann man völlig überziehen und sagen: Hammer ist Böse! > Sowas fasse ich nie wieder an! Ja, so ungefähr ist es in meinem Fall gelaufen. Spaß beiseite, ganz so schlimm ist es nicht. Ich habe schon verstanden, wie die Fragmentierung des Heap zustande kommt und wann sie völlig harmlos ist. > Ich halte also in Sachen String schon eine gewisse Vorsicht > und Sorgfalt für nötig Genau
A. H. schrieb: > Der Code funktioniert, allerdings verstehe ich nicht genau, warum ich > die Typumwandlung mit (String) machen muss. > Habe auch schon ausprobiert, nur den Datentyp char zu verwenden, > allerdings klappt dies auch nicht... Ich weiß nicht, was du falsch machst, aber ich habe den Bildchen mal abgetippt (danke für die Qual), weil ich wissen wollte, was da nicht klappt.
1 | void setup() |
2 | {
|
3 | Serial.begin(9600); |
4 | const char * const kette[] {"Eierkuchen", "Zwiebelsalat", "Nudelsuppe"}; |
5 | struct Uff |
6 | {
|
7 | String nahrung; |
8 | };
|
9 | Uff feld[3]; |
10 | feld[0].nahrung = (String)kette[0]; |
11 | feld[1].nahrung = String(kette[1]); |
12 | feld[2].nahrung = kette[2]; |
13 | |
14 | for(auto &s : feld) Serial.println(s.nahrung); |
15 | }
|
16 | |
17 | void loop() |
18 | {
|
19 | }
|
Und, was soll ich sagen? Das klappt perfekt.
Lothar M. schrieb: > Alessa H. schrieb: >> ich habe ein Programm > Als JPEG-Bild. Klasse! > Da kann man ganz toll einfach was rauskopieren oder anpassen... Sei froh! Wenn's eine Waldorf Schülerin wäre, gäb's eine Audio-Datei mit gesungenem und geklatschtem Quelltext.
Bitte melde dich an um einen Beitrag zu schreiben. Anmeldung ist kostenlos und dauert nur eine Minute.
Bestehender Account
Schon ein Account bei Google/GoogleMail? Keine Anmeldung erforderlich!
Mit Google-Account einloggen
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.