Nochmal eine Frage an die Profis. Ich habe eine Funktion, die nennt sich 'taster1()'. Sie liefert 1 zurück, wenn der Taster gerückt ist, ansonsten 0. Ich will die Funktion nun um einen optionalen Parameter erweitern, also so: taster1(byte iStatus = 0)'. In iStatus sollen (bit-orientiert) Zustände zurückgegeben werden wie "Doppelklick" und "Taste länger als 5 Sekunden gedrückt". In der Timer-Interruptroutine der Taster funktioniert das bereis. Neben dem Entprellen der Taster werden die o.g. Zustände erkannt und als Flag im Statusbyte abgelegt. Aber nun die Frage: Wie kann ich das in 'iStatus' zurückliefern lassen? Funktionsparameter in C/C++ sind ja offenbar By Value. Also muss ich wohl einen Zeiger als Parameter einsetzen. Soweit kein Problem, kriege ich noch hin. Was aber, wenn ich 'taster1()' ohne Parameter aufrufe und innerhalb der Funktion wird 'iStatus' beschrieben? WOHIN wird der Wert geschrieben, wenn gar kein Parameter angegeben ist? Habe so meine Befürchtung, dass "irgendwas" überschrieben wird ... Zweite Möglichkeit wäre, wenn die Funktion feststellen könnte, ob ein Parameter da ist, oder ob sie ohne aufgerufen worden ist. Hoffentlich hat jeder verstanden, was ich will. danke schon mal.
wenn ein Zeiger auf iStatus als Argument verwendet wird sollte man den auf auf ungleich Null prüfen bevor man den benutzt. Alternativ kann man ein paar Bits ja auch in den return Wert der Funktion reinkodieren. Roth schrieb: > Funktionsparameter in C/C++ sind ja offenbar By Value. Referenzen gibt es aber auch, die können allerdings keinen initialisierer haben:
1 | int taster(uint32_t &status) |
2 | {
|
3 | status = 42; |
4 | return 0; |
5 | }
|
Ausgangsparameter übergeben zu müssen ist bad practice und wird heutzutage eigentlich nicht mehr gemacht. Stattdessen könnte zum Beispiel ein simples Struct retur gegeben werden, das die gewünschten Infos enthält: https://godbolt.org/z/f9hpgf /edit Johannes S. schrieb: > Referenzen gibt es aber auch, die können allerdings keinen > initialisierer haben: > >
1 | > int taster(uint32_t &status) |
2 | > { |
3 | > status = 42; |
4 | > return 0; |
5 | > } |
6 | >
|
Auch Referenzen können default Werte haben.
:
Bearbeitet durch User
Ausgangsparameter sollen bad practice sein? Sowas sagen vielleicht Javaprogrammierer, weil es das in Java nicht gibt. Für mehrere Rückgabeparameter jedesmal eine Struktur zu definieren ist wie sich die Hosen mit der Kneifzange anzuziehen und die Programme werden dadurch nicht gerade effizienter. In C# ist das mit den Rückgabeparametern allerdings besser gelöst als in C/C++. Irgendwelche Bits in den Rückgabewert zu kodieren, wie hier vorgeschlagen, halte ich für keine gute und saubere Lösung. Du kannst es so ähnlich machen wie du es geschrieben hast. Du solltest nur vor der Zuweisung prüfen, ob der Wert des Zeigers ungleich 0 ist:
1 | void taster1(byte *iStatus = 0) |
2 | {
|
3 | // ...
|
4 | |
5 | if (iStatus) |
6 | *iStatus = 123; |
7 | |
8 | // ...
|
9 | }
|
:
Bearbeitet durch User
Roth schrieb: > Also muss ich wohl einen Zeiger als Parameter einsetzen. Soweit kein > Problem, kriege ich noch hin. Was aber, wenn ich 'taster1()' ohne > Parameter aufrufe und innerhalb der Funktion wird 'iStatus' beschrieben? > WOHIN wird der Wert geschrieben, wenn gar kein Parameter angegeben ist? Das hängt davon ab, welchen Default-Wert dem Zeiger gibst. Dahin wird es geschrieben. Roth schrieb: > Zweite Möglichkeit wäre, wenn die Funktion feststellen könnte, ob ein > Parameter da ist, oder ob sie ohne aufgerufen worden ist. Der Parameter ist immer da. Er wird nur entweder mit einem beim Aufruf übergebenen Argument befüllt, oder mit dem Default-Argument, das du in der Deklaration angegeben hast. Da musst du eben einen Wert nehmen, anhand dem das erkannt werden kann. Bei einem Zeiger bietet sich NULL an:
1 | int taster1(byte* iStatus = NULL) |
2 | {
|
3 | if (iStatus) |
4 | {
|
5 | *iStatus = irgendwas; |
6 | }
|
7 | }
|
T. B. schrieb: > Ausgangsparameter sollen bad practice sein? Sowas sagen vielleicht > Javaprogrammierer, weil es das in Java nicht gibt. Jo, das sagen die "Javaprogrammierer" ausm standard committee... https://isocpp.github.io/CppCoreGuidelines/CppCoreGuidelines#Rf-out Und was genau an einer Struktur die selbst auf einem 8Bit Prozessor in ein einziges Register passt nicht effizient ist muss man mir bitte auch noch erklären. Das war selbst in C++98 schon sinnvoll...
Roth schrieb: > Sie liefert 1 > zurück, wenn der Taster gerückt ist, ansonsten 0. > ... > In iStatus sollen (bit-orientiert) Zustände zurückgegeben werden wie > "Doppelklick" und "Taste länger als 5 Sekunden gedrückt". Du gibst in dem int nur 1 oder 0 zurück, warum nicht den ganzen Status? In C++ würde ich enums definieren, und schon ist das sauber. Alternativ eine Bitmaske. merciless
Dirk K. schrieb: > Du gibst in dem int nur 1 oder 0 zurück, > warum nicht den ganzen Status? In C++ würde > ich enums definieren, und schon ist das sauber. Die würde ich übrigens in jedem Fall definieren, statt nur die magischen Werte 0 und 1 zu verwenden.
Roth schrieb: > Ich habe eine Funktion, die nennt sich 'taster1()'. Sie liefert 1 > zurück, wenn der Taster gerückt ist, ansonsten 0. > > Ich will die Funktion nun um einen optionalen Parameter erweitern, > also so: taster1(byte iStatus = 0)'. > > In iStatus sollen (bit-orientiert) Zustände zurückgegeben werden wie > "Doppelklick" und "Taste länger als 5 Sekunden gedrückt". Warum so umständlich? Gibt halt nicht einfach 0 oder 1 zurück, sondern gleich alle Bits in einem hinreichend breiten Typ. > Aber nun die Frage: Wie kann ich das in 'iStatus' zurückliefern lassen? > > Funktionsparameter in C/C++ sind ja offenbar By Value. Mööp. Falsch C kennt nur Parameterübergabe by value. C++ kann auch by reference. Spätestens jetzt solltest du dich mal entscheiden, welche Programmier- sprache du verwendest. Und wenn du das getan hast, dann schnapp dir ein dazu passendes Buch und lies es. Das ist alles schon mal von jemandem aufgeschrieben worden und es ergibt null Sinn, wenn das hier nochmal jemand schreibt.
:
Bearbeitet durch User
Viele gute Anregungen, die mich weiter bringen. Bin am Sprung, muss gleich weg und pick mal das hier raus: T. B. schrieb: > Du kannst es so ähnlich machen wie du es geschrieben hast. Du solltest > nur vor der Zuweisung prüfen, ob der Wert des Zeigers ungleich 0 ist: > >
1 | > void taster1(byte *iStatus = 0) |
2 | > { |
3 | > // ... |
4 | >
|
5 | > if (iStatus) |
6 | > *iStatus = 123; |
7 | >
|
8 | > // ... |
9 | > } |
10 | >
|
WAS wird in 'byte *iStatus = 0' auf 0 gesetzt? iStatus oder der Pointer auf iStatus? Falls letzteres, was ich vermute, habe ich die Zuweisung von 'nullptr' schon gesehen. Ist dasselbe wie 0, oder ? Bei VBA von M$ ist NULL (analog zu nullptr) was ganz anderes als 0, daher frage ich Sachen, die euch in C/C++ vlt. vielleicht dämlich vorkommen ;)
Rolf M. schrieb: > Die würde ich übrigens in jedem Fall definieren, statt nur die magischen > Werte 0 und 1 zu verwenden. Das wäre natürlich eine Möglichkeit. Für 0 und 1 habe ich mich entschieden, um die Syntax im Hauptprogramm auf das Minimum JA/NEIN zu reduzieren. Das hat auch Vorteile. 99% aller Abfragen kommen ohne Status aus. Da ist nur der Taster JA/NEIN von Bedeutung und nicht, wie lange der Taster gedrückt ist, oder ob Doppelklich vorliegt.
Roth schrieb: > WAS wird in 'byte *iStatus = 0' auf 0 gesetzt? > iStatus oder der Pointer auf iStatus? iStatus ist der Pointer, und der wird auf 0 gesetzt. > Falls letzteres, was ich vermute, habe ich die Zuweisung von 'nullptr' > schon gesehen. Ist dasselbe wie 0, oder ? Nicht ganz. nullptr ist nur in C++ verfügbar und dort das Mittel der Wahl für Nullzeiger. In C nimmt man NULL. 0 würde aber in beiden Sprachen auch gehen. Roth schrieb: > Rolf M. schrieb: >> Die würde ich übrigens in jedem Fall definieren, statt nur die magischen >> Werte 0 und 1 zu verwenden. > > Das wäre natürlich eine Möglichkeit. Für 0 und 1 habe ich mich > entschieden, um die Syntax im Hauptprogramm auf das Minimum JA/NEIN zu > reduzieren. Das hat auch Vorteile. Aber auch dann würde ich mir da einen enum definieren mit den Werten Pressed und NotPressed oder so. Oder wenigstens einen bool. Ich versuche, wo es geht, keine magischen Zahlenwerte, sondern sprechende Namen zu verwenden.
Ich werde das jetzt doch so machen wie ihr vorgeschlagen habt und die Sztatusbits in den Rückgabewert integrieren. Ich kann ja noch auf <> 0 abfragen und habe dann dasselbe wie vorher, nur um die Bits erweitert. Vielen Dank. Noch mal zum nullptr. Rolf M. schrieb: > Nicht ganz. nullptr ist nur in C++ verfügbar und dort das Mittel der > Wahl für Nullzeiger. In C nimmt man NULL. 0 würde aber in beiden > Sprachen auch gehen. Die Arduino-IDE compiliert anstandslos nullptr. Daher verwende ich das auch. Arduino ist aber wohl sowieso C++ und nicht C. Das hier allerdings geht nicht
1 | Serial.print(nullptr); |
Wieso macht das der Compiler nicht, wenn im endeffekt eh überall 0 drin steht?
Roth schrieb: > Arduino ist aber wohl sowieso C++ und nicht C. Hei! Da ist ein Groschen gefallen! Lange hats gedauert.... Aber dennoch: Glückwunsch! Roth schrieb: > Wieso macht das der Compiler nicht, Weil Print keine Methode hat, welche (so einen) Zeiger ausgeben kann. Und das ist auch gut so. Deswegen haut dir der Compiler das, mit Fug und Recht, um die Ohren. Roth schrieb: > wenn im endeffekt eh überall 0 drin steht? Merke, auch wenn das gleiche drin sein mag, ist es dennoch nicht das gleiche. Mache dich kundig, was nullptr ist. https://en.cppreference.com/w/cpp/language/nullptr Ein modernes C++ Buch wäre empfehlenswert. Es sollte ca 1000 Seiten haben und min C++14, besser C++17 mit abdecken.
Roth schrieb: > Arduino ist aber wohl sowieso C++ und nicht C. Nein, es hängt von der Dateiendung ab wie das Arduino Buildsystem die Datei kompiliert. Wenn du eine .c Quelle hast wird die auch nach C Regeln übersetzt. Insofern ist C/C++ richtig.
Johannes S. schrieb: > es hängt von der Dateiendung ab wie das Arduino Buildsystem die > Datei kompiliert. Nicht ganz: Die Hauptdatei und alle sonstigen *.ino werden immer zu C++ Und Assembler *.S wird nur in Libraries automatisch übersetzt.
Arduino Fanboy D. schrieb: > Mache dich kundig, was nullptr ist. > https://en.cppreference.com/w/cpp/language/nullptr > > Ein modernes C++ Buch wäre empfehlenswert. > Es sollte ca 1000 Seiten haben und min C++14, besser C++17 mit abdecken. AMEN!
Arduino Fanboy D. schrieb: > Ein modernes C++ Buch wäre empfehlenswert. Nachdem er das schon die letzten 50 Male ignoriert hat, glaubt irgendwer dran, dass Roth es dieses Mal beherzigen wird? Ihr leistet hier kostenlosen Support für "ein Projekt", also vermutlich kommerziell. Wäre es ein Spaß-und-Hobby-projekt, spräche nichts gegen "eine Woche lernen, dann weitermachen".
Arduino Fanboy D. schrieb: > Hei! > Da ist ein Groschen gefallen! > Lange hats gedauert.... > Aber dennoch: Glückwunsch! Er wieder. Ich verwende doch gar keine C++ Features. Von daher ist es zu 99% egal. Arduino Fanboy D. schrieb: > Ein modernes C++ Buch wäre empfehlenswert. > Es sollte ca 1000 Seiten haben und min C++14, besser C++17 mit abdecken. Was die Bücher immer? Ich hatte 200, mindestens. Über alles, Hard- und SW, Programmierung, Komplettsamml. TTL u. CMOS, µC usw. usf. Sind alle weg seit dem Umzug. Mindestens 10 Bücher über C/C++ u. OOP waren dabei. Also nix über Bücher erzählen, idst a ein Griff ins Leere und tut mir b weh. Und was ist jetzt hiermit? Roth schrieb: > Das hier allerdings geht nicht >
1 | Serial.print(nullptr); |
> Wieso macht das der Compiler nicht, wenn im endeffekt eh überall 0 drin > steht? PS: NULL compiliert er, nullptr nicht.
Roth schrieb: > Was die Bücher immer? Ich hatte 200, mindestens. Offensichtlich nicht die, die du jetzt bräuchtest.
Beitrag #5605810 wurde von einem Moderator gelöscht.
Roth schrieb im Beitrag #5605810: > Du scheinst dumm zu sein Und du tust mir etwas leid... (aber nicht viel) Roth schrieb: > Und was ist jetzt hiermit? > > Roth schrieb: >> Das hier allerdings geht nicht >>Serial.print(nullptr);> Wieso macht das der Compiler nicht, wenn im endeffekt eh > überall 0 drin >> steht? > > PS: NULL compiliert er, nullptr nicht. Hier sieht man z.B. wie dämlich du dich anstellen kannst. Ein paar Beiträge vorher, habe ich dir das klipp und klar beantwortet. Aber das geht einfach an deiner Wahrnehmung vorbei! Siehe: Arduino Fanboy D. schrieb: > Roth schrieb: >> Wieso macht das der Compiler nicht, > Weil Print keine Methode hat, welche (so einen) Zeiger ausgeben kann. > Und das ist auch gut so. > Deswegen haut dir der Compiler das, mit Fug und Recht, um die Ohren. Es ist schade, dass du meine Antworten nicht verstehst. Aber in der Hinsicht ist dir offensichtlich nicht zu helfen.
Roth schrieb: > Die Arduino-IDE compiliert anstandslos nullptr. Daher verwende ich das > auch. Arduino ist aber wohl sowieso C++ und nicht C. Roth schrieb: > Ich verwende doch gar keine C++ Features. Du solltest dich mal entscheiden. Roth schrieb: > Was die Bücher immer? Ich hatte 200, mindestens. Über alles, Hard- und > SW, Programmierung, Komplettsamml. TTL u. CMOS, µC usw. usf. Sind alle > weg seit dem Umzug. Mindestens 10 Bücher über C/C++ u. OOP waren dabei. > Also nix über Bücher erzählen, idst a ein Griff ins Leere und tut mir b > weh. Es bringt nichts, früher mal irgendwelche Bücher gehabt zu haben. Man muss das richtige Buch zum richtigen Thema haben und auch lesen.
Beitrag #5606498 wurde von einem Moderator gelöscht.
Beitrag #5606542 wurde von einem Moderator gelöscht.
Beitrag #5606750 wurde von einem Moderator gelöscht.
Beitrag #5607922 wurde von einem Moderator gelöscht.
Beitrag #5607939 wurde von einem Moderator gelöscht.
Roth schrieb: > PS: NULL compiliert er, nullptr nicht. Arduino Fanboy D. schrieb: > Hier sieht man z.B. wie dämlich du dich anstellen kannst. > Ein paar Beiträge vorher, habe ich dir das klipp und klar beantwortet. > Aber das geht einfach an deiner Wahrnehmung vorbei! Hey, Roth, Arduino Fanboy D. (ufuf) hat es dir tatsächlich schon gesagt. Und ja, das Lesen von verlinktem Material kann dir keiner abnehmen. Man könnte es dir auf dem Präsentierteller darlegen, aber wo bliebe da der Lerneffekt?
Ich finde ziemlich offensichtlich, dass der Roth mit Arduino programmieren möchte, ohne das Programmieren in dieser Sprache (C/C++) zu erlernen. Einfach etwas zusammenstöpseln ein bisschen klicken und dann läuft das schon. Das ist doch genau die Vorgehensweise, die Arduino überall so lautstark bewirbt. Jetzt merkt der Roth, dass es doch nicht so einfach geht. Als Anfänger sollte man nicht endlos über die Größe von booleans und Pointern diskutieren müssen, denn die sind ausreichend dokumentiert - sogar in der kindlichen Arduino Doku. Außerdem bist doch angeblich Assembler Profi, als guck doch einfach in den erzeugten Assembler code rein (Stichwort: Listing-File). Dass dir immer noch nicht klar ist, welche Programmiersprache Arduino nutzt finde ich mehr als peinlich. Ich meine: so dumm kann man als Erwachsener Mensch doch ernsthaft nicht sein.
@Roth: Anscheinend ist etwas an nullptr besonders. Mache dich doch mal über nullptr schlau und schlussfolgere aus dem gelesenen.
Stefanus F. schrieb: > Außerdem bist doch angeblich Assembler Profi Ich glaube ja eher, dass das die typische Nullaussage eines Teenagers ist, der zufällig in genau diesem Bereich keine Ahnung hat, aber alles andere natürlich sehr gut beherrscht (und sich damit gegenüber jedem blamiert). Für einen Erwachsenen ist das allerdings trotzdem peinlich, da stimme ich dir zu. Vor allem die Lernresistenz: Wenn zu jeder Frage als erste Antwort ein "lerne die absoluten Grundlagen" kommt, dann sollte man sich und seine Fragen mal hinterfragen.
S. R. schrieb: > Stefanus F. schrieb: >> Außerdem bist doch angeblich Assembler Profi > > Ich glaube ja eher, dass das die typische Nullaussage eines Teenagers > ist, der zufällig in genau diesem Bereich keine Ahnung hat, aber alles > andere natürlich sehr gut beherrscht (und sich damit gegenüber jedem > blamiert). > > Für einen Erwachsenen ist das allerdings trotzdem peinlich, da stimme > ich dir zu. Vor allem die Lernresistenz: Wenn zu jeder Frage als erste > Antwort ein "lerne die absoluten Grundlagen" kommt, dann sollte man sich > und seine Fragen mal hinterfragen. Die Sorte Teenager gibt es in jeder Altersklasse. ;-) oder eigentlich eher :-((
Beitrag #5608119 wurde von einem Moderator gelöscht.
Roth schrieb im Beitrag #5608119:
> aber der programiert wenigstens gut.
Es tut mir leid, aber ich kann dieses "Lob"/"Urteil" nicht akzeptieren.
Einerseits verblasst es gegen die Schmähungen, mit denen du mich bisher
überschüttet hast. Du darfst nicht mehr Achtung/Respekt von mir
erwarten, als du, zu bringen, bereit bist.
Andererseits, scheint es mir eher so zu sein, dass deine Kompetenzstufe,
in Sachen C/C++ bzw. Arduino, einfach noch nicht hoch genug ist, um das
beurteilen zu können.
Drittens, finde ich diese Art, Leute gegeneinander auszuspielen, der
Versuch zu polarisieren, völlig daneben. Auf jeden Fall, ist es in der
Sache, nicht hilfreich, irgend wen zu diffamieren und zu beleidigen. Und
dabei ist es völlig egal, ob du gerade den svenska oder mich versuchst
herabzuwürdigen. Es wird deine Position nicht stärken, sondern dich
weiter ins Abseits schieben.
S. R. schrieb: > Wenn zu jeder Frage als erste > Antwort ein "lerne die absoluten Grundlagen" kommt, dann sollte man sich > und seine Fragen mal hinterfragen. ... oder gegen die verlotterten Sitten des Forums wettern. ;-)
Roth schrieb im Beitrag #5608119: > Völlige Orientierungslosigkeit, gepaart mit > großer Klappe (der Kommi siehe unten). Entweder, du machst irgendwas kommerzielles und lehnst "Lernen" ab, weil du keine Zeit hast (das könnte ich nachvollziehen), oder du machst irgendeine private Bastelei lernst das gesamte Konzept "Lernen" ab, weil du nicht weißt, wie man das macht, nicht willens oder einfach nicht fähig dazu bist. Der erste Fall sagt etwas über einen Arbeitgeber aus, der zweite über dich. Choose wisely. :-) Ach nee, hast du ja schon.
Arduino Fanboy D. schrieb: > Einerseits verblasst es gegen die Schmähungen A so. Und wer hat dich gezwungen, auf meine Fragen zu antworten? Oder bist du einsam, kannst gar nicht anders ??? Kommt mir so vor, denn du bist ja rund um die Uhr am schreiben ^^ Ich fand den Code von dir trotzdem gut. NEIN, du musst jetzt nicht antworten. Wenn du mich nicht magst, dann geh, schreib woanders.
Roth schrieb: > Wenn du mich nicht magst Das Urteil habe ich noch nicht gesprochen. Aber du schon! Oder?
Zumal "mögen" als menschliche Eigenschaft in einem technischen, anonymen Forum eher unwesentlich ist. Im Gegensatz zu anderen Eigenschaften. Man muss hier niemanden mögen, um ihm zu helfen. Man sollte nur davon überzeugt sein, dass es (a) nützt und (b) nicht ausartet.
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.