Forum: Mikrocontroller und Digitale Elektronik Frage/Problem Datentyp Arduino Nano


Announcement: there is an English version of this forum on EmbDev.net. Posts you create there will be displayed on Mikrocontroller.net and EmbDev.net.
von A. H. (less)


Angehängte Dateien:

Lesenswert?

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

von Sebastian R. (sebastian_r569)


Lesenswert?

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

von Lothar M. (lkmiller) (Moderator) Benutzerseite


Lesenswert?

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
von fop (Gast)


Lesenswert?

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.

von fop (Gast)


Lesenswert?

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.

von A. H. (less)


Lesenswert?

Ja, das funktioniert so.

von EAF (Gast)


Lesenswert?

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.

von EAF (Gast)


Lesenswert?

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.

von EAF (Gast)


Lesenswert?

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.

von Stefan ⛄ F. (stefanus)


Lesenswert?

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.

: Bearbeitet durch User
von EAF (Gast)


Lesenswert?

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.

von Stefan ⛄ F. (stefanus)


Lesenswert?

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.

: Bearbeitet durch User
von EAF (Gast)


Lesenswert?

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.

von Stefan ⛄ F. (stefanus)


Lesenswert?

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

: Bearbeitet durch User
von EAF (Gast)


Lesenswert?

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.

von Norbert (Gast)


Lesenswert?

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.

Antwort schreiben

Die Angabe einer E-Mail-Adresse ist freiwillig. Wenn Sie automatisch per E-Mail über Antworten auf Ihren Beitrag informiert werden möchten, melden Sie sich bitte an.

Wichtige Regeln - erst lesen, dann posten!

  • Groß- und Kleinschreibung verwenden
  • Längeren Sourcecode nicht im Text einfügen, sondern als Dateianhang

Formatierung (mehr Informationen...)

  • [c]C-Code[/c]
  • [code]Code in anderen Sprachen, ASCII-Zeichnungen[/code]
  • [math]Formel in LaTeX-Syntax[/math]
  • [[Titel]] - Link zu Artikel
  • Verweis auf anderen Beitrag einfügen: Rechtsklick auf Beitragstitel,
    "Adresse kopieren", und in den Text einfügen




Bild automatisch verkleinern, falls nötig
Bitte das JPG-Format nur für Fotos und Scans verwenden!
Zeichnungen und Screenshots im PNG- oder
GIF-Format hochladen. Siehe Bildformate.

Mit dem Abschicken bestätigst du, die Nutzungsbedingungen anzuerkennen.