Ich frage mich gerade warum bei der Arraylänge nicht 5 raus kommt anstatt 6. Seit wann wird da /0 dazugezaehlt?
:
Sizeof kennt keine Sonderbehandlung einer 0. Strlen hingegen hört vor einer 0 auf.
Beitrag #5678830 wurde von einem Moderator gelöscht.
Glücklich ohne Grund schrieb im Beitrag #5678830:
> Ich meine es aber nicht böse.
Ich auch nicht..
Aber trotzdem sagt sizeof(t) von char t[]="Hello" eine Länge von 6 und
strlen(t) eine Länge von 5
Da kannst du mit den Füßen auf dem Boden stampfen, wie du willst.
Blamierst dich nur ganz elendig.
Beitrag #5678832 wurde von einem Moderator gelöscht.
Noch krasser ist der Unterschied, wenn du ein globales uninitialisiertes Array hast. Dann liefert strlen 0 Und sizeof den reservierten Speicher in Bytes.
Beitrag #5678834 wurde von einem Moderator gelöscht.
Beitrag #5678837 wurde von einem Moderator gelöscht.
Glücklich ohne Grund schrieb im Beitrag #5678837: > Von einem uninitialisierten Speicherbereich hätte ich jetzt auch nichts > anderes erwartet. Man muss halt wissen, wer was zurück liefert. Ich behaupten sogar: Solange ein globalen Array uninitialisiert ist, ist die Rückgabe von strlen unspezifiziert denn im Speicherbereich des uninitialisierten Arrays könnte ja auch "doof" drin stehen oder "Anton" oder sonstwas. Bei uninitialisierten Speicher sollte man nicht davon ausgehen, dass da überall "0" drin steht. ;)
Beitrag #5678844 wurde von einem Moderator gelöscht.
M. K. schrieb: > Glücklich ohne Grund schrieb: >> Von einem uninitialisierten Speicherbereich hätte ich jetzt auch nichts >> anderes erwartet. > > Man muss halt wissen, wer was zurück liefert. Ich behaupten sogar: > Solange ein globalen Array uninitialisiert ist, ist die Rückgabe von > strlen unspezifiziert denn im Speicherbereich des uninitialisierten > Arrays könnte ja auch "doof" drin stehen oder "Anton" oder sonstwas. Bei > uninitialisierten Speicher sollte man nicht davon ausgehen, dass da > überall "0" drin steht. ;) Der Knackpunkt ist, dass es in C eigentlich keine uninitialisierten globalen Variablen gibt. Wenn man sie nicht explizit initialisiert, werden sie implizit mit 0 initialisiert. Damit bringt strlen() immer 0 zurück. Glücklich ohne Grund schrieb im Beitrag #5678844: > Das Problem an C ist halt die Nullterminierung. Mit einem Stringdeskriptor > wäre das wieder ein ganz anderes Verhalten. Und was soll da nun besser sein, wenn dort irgendein Zufallswert drin steht?
:
Bearbeitet durch User
M. K. schrieb: > Ich behaupten sogar: > Solange ein globalen Array uninitialisiert ist, ist die Rückgabe von > strlen unspezifiziert In C werden globale Variablen automatisch mit 0 initialisiert, solange nichts anderes angegeben ist. Daher liefert strlen in diesem Fall 0.
Rolf M. schrieb: > Und was soll da nun besser sein, wenn dort irgendein Zufallswert drin > steht? Mit besser oder schlechter lässt sich das nicht ausdrücken. Als Programmierer muss ich wissen, was ich zu welcher Zeit an welchem Ort abfrage, und ob die Bedingungen einer Abfrage valide sind. Wenn ein String Array bzw. ein Array von char angelegt wird, und mit 0 initialisiert wird, dann wird die Stringlänge immer 0 sein. Vorausgesetzt strlen geht nach dem Nullbyte. Wenn keine 0 initialisiert wurde, ist es undefiniert. Ich traue keiner Auto-Initialisierung in C. Dazu gibt es zu viele Unklarheiten. Wenn das Programm davon abhängig ist, dass bestimmte Werte initialisiert werden, dann tue ich das per Software, im setup(). Für nicht genutzten Speicher gibts kein Geld zurück. Einfache for-Schleife, wo ist das Problem?
Glücklich ohne Grund schrieb: > Wenn ein String Array bzw. ein Array von char angelegt wird, und mit 0 > initialisiert wird, dann wird die Stringlänge immer 0 sein. > Vorausgesetzt strlen geht nach dem Nullbyte. Wenn keine 0 initialisiert > wurde, ist es undefiniert. Wenn du stattdessen irgendwo die Länge abspeicherst, hast du aber genau das gleiche Problem. Wenn das mit 0 initialisiert wurde, kommt auch eine Stringlänge von 0 raus, und wenn nicht, irgendein Blödsinn. Macht also keinen Unterschied. > Ich traue keiner Auto-Initialisierung in C. Dazu gibt es zu viele > Unklarheiten. Welche? Die Regel ist einfach: Globale Variablen werden automatisch mit 0 initialisiert, alles andere nicht.
Rolf M. schrieb: > Welche? Die Regel ist einfach: Globale Variablen werden automatisch mit > 0 initialisiert, alles andere nicht. Oh täusche dich mal nicht. Gerade im Bereich Soft-Reset warten zuweilen Überraschungen, wo man keine erwartet hat.
Rolf M. schrieb: > Wenn du stattdessen irgendwo die Länge abspeicherst, hast du aber genau > das gleiche Problem. Wenn das mit 0 initialisiert wurde, kommt auch eine > Stringlänge von 0 raus, und wenn nicht, irgendein Blödsinn. Macht also > keinen Unterschied. ja und nein. Bei VB kann ich z.B. sicher sein, dass jede Variable initialisiert ist. Bei C habe ich gelernt, das ist aber schon lange her, dass ICH die Variable initialisieren muss, ansonsten steht Zufall drin. Wenn sich das geändert hat, so viel habe ich mit C nicht zu tun, hängt es m.E. immer noch am Compiler, an der Version, am alter. Die selben Sourcen, unterschiedliches Verhalten. Bei anderen Sprachen kann ich es ausschließen, bei C aber nicht zu 100%. Und Programme mit Unsicherheitsfaktor erstelle ich nicht. Ich gehe davon aus, dass wir alle nbur von Arrays, struct & Co reden. "Normale" Variablen kann man mit =0 initialisieren, und das wird man normalerweise auch tun.
Beitrag #5678860 wurde von einem Moderator gelöscht.
Glücklich ohne Grund schrieb: > Bei C habe ich gelernt, das ist aber schon lange her, > dass ICH die Variable initialisieren muss, ansonsten steht Zufall drin. Da muss man dann noch drüber nachdenken, ob zB ein Array global angelegt wurde. Dann landet es - zumindest beim GCC - in der .bss Section, die beim Programmstart mit 0 initialisiert wird.
Glücklich ohne Grund schrieb: > Bei VB kann ich z.B. sicher sein, dass jede Variable > initialisiert ist. Bei C habe ich gelernt, das ist aber schon lange her, > dass ICH die Variable initialisieren muss, ansonsten steht Zufall drin. > Wenn sich das geändert hat, so viel habe ich mit C nicht zu tun, Die von mir beschriebene Regel gab es schon 1989, als C genormt wurde. > hängt es m.E. immer noch am Compiler, an der Version, am alter. Die > selben Sourcen, unterschiedliches Verhalten. Bei anderen Sprachen kann > ich es ausschließen, bei C aber nicht zu 100%. Wenn globale Variablen nicht implizit mit 0 initialisiert werden, hat der Compiler bzw. die Laufzeitumgebung einen Fehler. Kann man natürlich nicht ausschließen, aber das kann dir in anderen Sprachen dann genauso passieren.
:
Bearbeitet durch User
Also ich hänge jede neue Struktur sofort in den Initialisierungslauf im setup(). Das ist mir in Fleisch und blut übergegangen und ich muss mir vor allem keine Gedanken machen. Bisher bin ich damit sehr gut gefahren. Lasst euch doch mal die millis() anzeigen. Das Compilieren dauert 35 S. Der Initialisierungslauf im aktuellen Programm läuft 800.92 mS. Bei über 100 S. Quellcode. Da überlege ich nicht, ob ich initialisieren soll, sondern tus.
Rolf M. schrieb: > Die von mir beschriebene Regel gab es schon 1989, als C genormt wurde. Kann es sein, dass das vom OS abhängig ist? Ich habe damals auf UNIX gearbeitet.
Der Pointer zeiger zeigt nicht auf ein anonymes Array - sondern auf ein compound literal
Walter K. schrieb: > Der Pointer zeiger zeigt nicht auf ein anonymes Array - sondern auf ein > compound literal Nein, er zeigt auf ein string literal, welches ein anonymes Array darstellt. Ein compound literal wäre so:
1 | char* zeiger = (char[]){ 'W', 'e', 'l', 't', '\0'}; |
Aber auch das wäre ein anonymes Array.
Zum Thema Standard helfen vielleicht die Verweise hier weiter: http://c-faq.com/decl/initval.html Glücklich ohne Grund schrieb: > Der Initialisierungslauf im aktuellen Programm läuft 800.92 mS. Wenn man maximal 250ms für die Initialisierung zur Verfügung hat, ist man damit leider nicht mehr innerhalb der Spezifikation.
Ein Gast schrieb: > Wenn man maximal 250ms für die Initialisierung zur Verfügung hat, ist > man damit leider nicht mehr innerhalb der Spezifikation. Wenn man nur 250 mS "zur Verfügung" hat, dann hat man auch kein Riesenprogramm vor sich. So etwas gibt es nicht. Walter K. schrieb: > Der Pointer zeiger zeigt nicht auf ein anonymes Array - sondern auf ein > compound literal Ein compound literal. Aha. Sowas musste ja noch kommen. Ohne so einen Mist aus der hohen Theorie geht es hier nicht, oder? Ich bin dann weg.
Glücklich ohne Grund schrieb: > Also ich hänge jede neue Struktur sofort in den > Initialisierungslauf im setup(). Das ist mir in Fleisch und blut > übergegangen und ich muss mir vor allem keine Gedanken machen. Bisher > bin ich damit sehr gut gefahren. Lasst euch doch mal die millis() > anzeigen. Das Compilieren dauert 35 S. Der Initialisierungslauf im > aktuellen Programm läuft 800.92 mS. Bei über 100 S. Quellcode. Da > überlege ich nicht, ob ich initialisieren soll, sondern tus. Arduino (danach klingt es) ist C++ und nicht C und das hat immer eine automatische Initialisierung, sonst würde da gar nichts funktionieren... C hat diese per Standard auch, aber es könnte irgendwo Umgebungen geben wo diese weggelassen wird - das wäre bei C++ halt komplett verkehrt. Alle globalen/statischen Variablen werden auf 0 initialisiert falls nicht anders per = angegeben. Auch Initialisierung per = wird effizient vom Startup Code durchgeführt (constant initialization). Daher ist das in setup() komplett redundant. So einen popeligen AVR kann man in unter 1ms hochfahren. Wer da so viel Zeit verschwendet darf sich auch nicht beschweren wenn das Smartphone 5 Minuten zum Starten brauchen...
Glücklich ohne Grund schrieb: > Ein Gast schrieb: > >> Wenn man maximal 250ms für die Initialisierung zur Verfügung hat, ist >> man damit leider nicht mehr innerhalb der Spezifikation. > > Wenn man nur 250 mS "zur Verfügung" hat, dann hat man auch kein > Riesenprogramm vor sich. So etwas gibt es nicht. Das ist z.B. im Automotive-Bereich eine ganz normale Forderung für ein Steuergerät. Übrigens sind es ms, nicht mS. S ist das Symbol für die Einheit für den Leitwert "Siemens".
Rolf M. schrieb: > Walter K. schrieb: > Der Pointer zeiger zeigt nicht auf ein anonymes Array - sondern auf ein > compound literal > > Nein, er zeigt auf ein string literal, welches ein anonymes Array > darstellt. > Ein compound literal wäre so:char* zeiger = (char[]){ 'W', 'e', 'l', > 't', '\0'}; > > Aber auch das wäre ein anonymes Array. Selbstverständlich zeigt Zeiger in char *zeiger = “Blah Blah”; auf ein compount literal Daran ändert Deine andere Schreibweise auch nix Und ob man an dieser Stelle von einem anonymen Array sprechen kann, halte ich für gewagt!
Walter K. schrieb: > Selbstverständlich zeigt Zeiger in > char *zeiger = “Blah Blah”; > auf ein compount literal > > Daran ändert Deine andere Schreibweise auch nix Die "andere Schreibweise" ist eine andere Art von literal. Eben kein compound literal, sondern ein string literal. > Und ob man an dieser Stelle von einem anonymen Array sprechen kann, > halte ich für gewagt! Was soll es denn sonst sein? Es ist ein namenloses Objekt vom Typ "Array aus const char". Hier mal der passende Aussschnitt aus ISO C (§6.5.2.5 Abschnitt 4): "A postfix expression that consists of a parenthesized type name followed by a brace-enclosed list of initializers is a compound literal. It provides an unnamed object whose value is given by the initializer list." Wo siehst du in "Blah Blah" einen parenthesized type name followed by a brace-enclosed list of initializers?
:
Bearbeitet durch User
Rolf M. schrieb: > ...sondern ein string literal. > > ... > Wo siehst du in "Blah Blah" einen parenthesized type name followed by a > brace-enclosed list of initializers? Du gibst die Antwort Doch selbst: String Literal !
Beitrag #5679504 wurde von einem Moderator gelöscht.
Glücklich ohne Grund schrieb: > Also ich hänge jede neue Struktur sofort in den Initialisierungslauf im > setup(). Das ist mir in Fleisch und blut übergegangen und ich muss mir > vor allem keine Gedanken machen. Das Funktioniert bei Anfängern recht zuverlässig. Sobald Du mehrere C-Dateien hast und über ints hinaus gehst, gibt es unter anderem folgende Probleme: * Die Variablen müssen global sein, oder es muss mehrere Setups geben * Das gleiche gilt auch analog für modul-Scope vs. Block-Scope * in Libraries gehen globale in einer Setup gar nicht (zumindest nicht in C, da dann immer alle Module dazugelinkt werden!) * Bei nicht trivialen Arrays oder Strukturen/Unions musst Du praktisch mit memcpy arbeiten. Ganz schlimm wird es, wenn Du den globalen Wust dann auch mit anderen Dingen als mit 0 initialisierst. Dann kann niemand mehr Deinen Code nutzen.
Beitrag #5679640 wurde von einem Moderator gelöscht.
Ein Gast schrieb: > Zum Thema Standard helfen vielleicht die Verweise hier weiter: > http://c-faq.com/decl/initval.html Genau so hab ich das auch gelernt. Nur wenn ein static davor steht werden nicht explizit initialisierte Variablen mit 0 initialisiert. Sind die Variablen nicht mit static gekennzeichnet und nicht initialisiert kann/darf man nicht sicher sein, dass sie mit 0 initialisiert werden. Ich möchte aber nicht ausschließen, dass sich das inzwischen geändert hat, ist bei mir ja jetzt schon über 30 Jahre her.
Beitrag #5679707 wurde von einem Moderator gelöscht.
Beitrag #5679714 wurde von einem Moderator gelöscht.
M. K. schrieb: > Ein Gast schrieb: >> Zum Thema Standard helfen vielleicht die Verweise hier weiter: >> http://c-faq.com/decl/initval.html > > Genau so hab ich das auch gelernt. Nur wenn ein static davor steht > werden nicht explizit initialisierte Variablen mit 0 initialisiert. > Sind die Variablen nicht mit static gekennzeichnet und nicht > initialisiert kann/darf man nicht sicher sein, dass sie mit 0 > initialisiert werden. "static duration" bedeutet Variable, die nicht auf dem Stack liegt. Mit dem Keyword "static" kann man das innerhalb von Funktionen erzwingen. Außerhalb bedeutet "static" nur, daß die Variable nicht vom Linker aus anderen Compilation-Units aus referenziert werden kann ("nicht sichtbar"). Und "static duration" uninitialisiert kommt, soweit nicht durch Attribute anders gewünscht, in das .bss-Segment, das die Runtime bei jedem Start nullt. > Ich möchte aber nicht ausschließen, dass sich das inzwischen geändert > hat, ist bei mir ja jetzt schon über 30 Jahre her. Das ist eher ein "static" Problem bei dir. ;-)
:
Bearbeitet durch User
Beitrag #5679758 wurde von einem Moderator gelöscht.
A. S. schrieb: > Glücklich ohne Grund schrieb: >> Also ich hänge jede neue Struktur sofort in den Initialisierungslauf im >> setup(). Das ist mir in Fleisch und blut übergegangen und ich muss mir >> vor allem keine Gedanken machen. > > Das Funktioniert bei Anfängern recht zuverlässig. Sobald Du mehrere > C-Dateien hast und über ints hinaus gehst, gibt es unter anderem > folgende Probleme: > > * Die Variablen müssen global sein, oder es muss mehrere Setups geben > * Das gleiche gilt auch analog für modul-Scope vs. Block-Scope > * in Libraries gehen globale in einer Setup gar nicht (zumindest nicht > in C, da dann immer alle Module dazugelinkt werden!) > * Bei nicht trivialen Arrays oder Strukturen/Unions musst Du praktisch > mit memcpy arbeiten. > > Ganz schlimm wird es, wenn Du den globalen Wust dann auch mit anderen > Dingen als mit 0 initialisierst. Dann kann niemand mehr Deinen Code > nutzen. Also nur "Anfänger" initialisieren Structs und Arrays im Setup. Ah ja, habe ich auch noch nicht gewusst. Hast du überhaup schon mal im Projekt gearbeitet? Variablen können da genau so gut in einen Initialisierungslauf eingebunden werden. Das wird eben zum Schluss gejoint, zusammengefügt, wo ist das Problem? Oder ging es dir nur darum, das Wort "Anfänger" öffentlich plazieren zu können ;-)
Beitrag #5679780 wurde von einem Moderator gelöscht.
Beitrag #5679820 wurde von einem Moderator gelöscht.
Beitrag #5679858 wurde von einem Moderator gelöscht.
Beitrag #5679863 wurde von einem Moderator gelöscht.
Beitrag #5679869 wurde von einem Moderator gelöscht.
Beitrag #5679908 wurde von einem Moderator gelöscht.
Beitrag #5679973 wurde von einem Moderator gelöscht.
Beitrag #5680045 wurde von einem Moderator gelöscht.
Beitrag #5680063 wurde von einem Moderator gelöscht.
Beitrag #5680136 wurde von einem Moderator gelöscht.
Beitrag #5680148 wurde von einem Moderator gelöscht.
Beitrag #5680150 wurde von einem Moderator gelöscht.
Glücklich ohne Grund schrieb: > Also nur "Anfänger" initialisieren Structs und Arrays im Setup. Ah ja, Nein.das sollte jeder tun aber nur für die Variablen, deren Startwert zur Linkzeit unbekannt ist sondern erst zur Laufzeit > Hast du überhaup schon mal im Projekt gearbeitet? Ja. Und auch in Projekten mit pre-ANSI-C Compiler, wo dein Vorgehen notwendig war. Oder Compiler für kleinste uC, deren Startup man selber schreiben musste das Nullen fehlte. Aber der Pfeil geht Richtung standardkonformen Compiler. Und wenn eine Variable explizit mit 0 initialisiert wird, obwohl sie es auch implizit ist, dann kann das aus vielen Gründen OK sein. Das aber vorsorglich und mit den von mir aufgezählten Klimmzügen zu machen, weil der Compiler einen Bug habe könnte oder weil der Programmierer den Unterschied zwischen statischen Variablen und Stack nicht kennt, belastet den Code.
Beitrag #5681388 wurde von einem Moderator gelöscht.
Beitrag #5681405 wurde von einem Moderator gelöscht.
Beitrag #5681437 wurde von einem Moderator gelöscht.
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.