bla schrieb:> Oder die klassiche for-Schleife. Poor man's memcpy.
Wobei memcpy auf den meisten RISC Architekturen auch einfach als Scheife
umgesetzt ist. Wie auch sonst?
> Wobei memcpy auf den meisten RISC Architekturen auch einfach als Scheife
umgesetzt ist. Wie auch sonst?
Naja. Eine CPU kann das von selbst, ohne Schleife.
Da jetzt der Vergleich zwischen for() und memcpy() angesprochen wurde:
Axel S. schrieb:> Compiler können das mittlerweile auch ganz gut optimieren.
Betrifft evtl. nur memcpy? (siehe weiter unten)
Cyblord -. schrieb:> Wobei memcpy auf den meisten RISC Architekturen auch einfach als Scheife> umgesetzt ist. Wie auch sonst?
Bei ARM Cortex-M4 mit gcc scheint es jedoch bei der strchr() ein
Unterschied zu geben.
Gestern habe ich einige Funktionen bei mir optimiert und mal einen Test
durchgeführt:
"Suche ein Zeichen im String und breche dann die weitere Suche ab"
1 Version: for-Schleife
2 Version: strchr()
Kompiliert wurde im Release Modus mit (-O1), (-O3) sowie (-Os).
Ergebnis: for-Variante war immer um den Faktor 1,5 bis 3 langsamer.
Da neige ich dann doch eher dazu, Funktionen zu nutzen, falls es sie
bereits gibt und es nicht selbst neu zu programmieren.
Adam P. schrieb:> Da neige ich dann doch eher dazu, Funktionen zu nutzen, falls es sie> bereits gibt und es nicht selbst neu zu programmieren.
Ich neige eher dazu, sowas selber zu programmieren, weil ich so alles
kontrollieren kann oder zumindest das Gefühl habe.
Allerdings muss man realistisch doch sagen, dass die, die
Standardfunktionen schreiben sich wahrscheinlich besser mit der
Architektur und dem Compiler auskennen und sich mehr Gedanken gemacht
haben als jemand, der während der Programmierung mal auf so ein Problem
stößt.
Zitronen F. schrieb:>> Wobei memcpy auf den meisten RISC Architekturen auch einfach als> Scheife> umgesetzt ist. Wie auch sonst?>> Naja. Eine CPU kann das von selbst, ohne Schleife.
So ist es (Cortex-M, braucht 4-Byte-Alignment):
Dulfried W. schrieb:> So geht das nicht, da \n kein char ist
Es geht trotzdem genau so. In C ist '\n' zwar ein int, passt aber in den
Wertebereich von char. In C++ ist es ein char. strchr() nimmt einen
"int", sodass hier auch keine Compiler-Warnung kommt.
1) single-byte integer character constant, e.g. 'a' or '\n' or '\13'. Such constant has type int and a value equal to the representation of c-char in the execution character set as a value of type char mapped to int.
Harry L. schrieb:> Es geht aber nicht um um CPP und in C ist auch ein> Escape-Character ein> char.
Leseverständnis nicht vorhanden? Mein Beitrag bezieht sich auf C. Der
Link verweist auf die C-Dokumentation. Der C-Präprozessor "CPP" kennt
kein "char" oder "int". In C++ sind Literale der Form 'x' char, in C
sind alle Literale der Form 'x' oder '\n' int, egal ob escaped oder
nicht.
a character from the basic source character set minus single-quote ('), backslash (\), or the newline character.
3
escape sequence: one of special character escapes \' \" \? \\ \a \b \f \n \r \t \v, hex escapes \x... or octal escapes \... as defined in escape sequences.
Adam P. schrieb:> printf("ptr_base = 0x%08X\n", ptr_base);> printf("ptr_find = 0x%08X\n", ptr_find);
Pointer gibt man mit %p aus. Auf 64bit-Plattformen fehlen sonst 8
Ziffern...
Mike B. schrieb:> Geht das in C(++/#) nicht?
C kann sehr vieles nicht, dennoch bestehen mysteriöserweise viele Leute
partout immer noch darauf. In C++ geht's:
Dr. Sommer schrieb:Dr. Sommer schrieb:> std::array<char, 16> array2, array1;> array1 = array2;> Oder:> std::vector<char> array2 (16), array1;> array1 = array2;
Dr. Sommer schrieb:> Pointer gibt man mit %p aus. Auf 64bit-Plattformen fehlen sonst 8> Ziffern...
Danke für die Info,
jedoch bin ich davon ausgegangen dass es sich z.B. um ein maximal 32-bit
Mikrocontroller handelt.
OK, um den Source portabel zu halten, ist %p natürlich optimal -
ich habe es immer Anwendungsfall bezogen mit 0x%02X, 0x%04X oder 0x%08X
gelöst (natürlich nicht auf die Adressen bezogen, das ginge ja so auch
nicht), aber da ich wusste, ok, ich hab ein 32bit system, also brauch
ich 0x%08X - ja, umständlich, nu wurde ich eines besseren belehrt ;)
Aber man lernt ja nie aus...zum glück :)
edit:
Gibt es überhaupt 64-bit µC?
Adam P. schrieb:> OK, um den Source portabel zu halten, ist %p natürlich optimal
%p ist nicht nur optimal - sondern eher zwingend
Denn manchmal ist sogar:
sizeof(int*) != sizeof(char*)
Hunsbuckel schrieb:> Denn manchmal ist sogar:>> sizeof(int*) != sizeof(char*)
Das leuchtet mir jetzt aber irgendwie nicht ein...
Wenn ich ein 32-bit Adressraum habe,
in diesem kann ich char sowie int ablegen -
Wenn sizeof(char*) nun 2 wäre...dann wären ja alle adressen oberhalb
dieser grenze gar nicht möglich.
Wo gibt es denn diesen Fall?
Oder ich versteh nicht ganz was du meinst...
"sizeof(int*) != sizeof(char*)"
Soll dies nu bedeuten, dass ein Zeiger auf "int" ungleich einem Zeiger
auf "char" sein kann, sprich in der Größe des Zeigers?
Ein Zeiger beinhaltet doch die Adresse auf die er zeigt...
„...Soll dies nu bedeuten, dass ein Zeiger auf "int" ungleich einem
Zeiger auf "char" sein kann, sprich in der Größe des Zeigers?..“
Selbstverständlich können die unterschiedlich groß sein!
Auch in der PC Welt gab es schon mal schräge Memory-Modelle mit Offsets
usw.
Adam P. schrieb:> Soll dies nu bedeuten, dass ein Zeiger auf "int" ungleich einem Zeiger> auf "char" sein kann, sprich in der Größe des Zeigers?
Genau. Für Beispiele, siehe die FAQ von comp.lang.c:
http://c-faq.com/null/machexamp.html
Leider sieht die Sprache C(99) oft nur einfach aus: manche Annahmen, die
man aus ihrer Einfachheit ableiten mag, sind einfach falsch. Leider.
In diesem Thread sind zwei "schöne" Beispiele genannt worden (Typ von
character-constants und sizeof(<pointer>)). Man könnte weiter machen mit
_Bool ...
Daher rate ich jedem C-Programmierer, sich mal die C-FAQ anzusehen:
http://c-faq.com/charstring/sizeofchar.htmlhttp://c-faq.com/ptrs/generic.html
Wilhelm M. schrieb:> In diesem Thread sind zwei "schöne" Beispiele genannt worden (Typ von> character-constants und sizeof(<pointer>)). Man könnte weiter machen mit> _Bool ...
Diese Sachen finde ich verständlich, wenn man sie sich mal angesehen
hat. Wirklich bizarr ist es bei Funktionen wie z.B. toupper. Das bekommt
auch einen int für das zu konvertierende Zeichen übergeben. Aber man
darf nicht einfach sein Zeichen übergeben, denn der erlaubte
Wertebereich ist der von unsigned char und EOF. Jeder andere Wert ergibt
undefiniertes Verhalten. Wenn man also eine Plattform hat, auf der char
signed ist, muss sichgergestellt sein, dass das erstmal nach unsigned
char gecastet wird.
Also falsch:
1
intc=getchar();
2
intC=toupper(c);
Richtig:
1
intc=getchar();
2
intC;
3
if(c!=EOF)
4
C=toupper((unsignedchar)c);
5
else
6
C=EOF;
Obwohl c ein int ist und toupper auch einen int erwartet, muss erst noch
nach unsigned char gecastet werden. Und dann muss EOF auch separat
behandelt werden, obwohl toupper es auch behandelt. Es geht aber durch
den Cast nach unsigned char verloren.
Rolf M. schrieb:> Wenn man also eine Plattform hat, auf der char> signed ist
In C ist char immer signed
(solange Du nicht explizit sagst, dass die Char-Variable vorzeichenlos
sei soll)
- das hat nix mit der Plattform zu tun
Walter K. schrieb:> Rolf M. schrieb:>> Wenn man also eine Plattform hat, auf der char>> signed ist>> In C ist char immer signed
Nein, ist es nicht.
> - das hat nix mit der Plattform zu tun
Die signedness von char ist in C implementation-defined.
Walter K. schrieb:> Rolf M. schrieb:>>....>> Es geht aber durch>> den Cast nach unsigned char verloren.>> Das ist alles Unfug!
Lies doch bitte in ISO C nach, bevor du hier losplärrst. Dein Halbwissen
reicht nicht, um da mitdiskutieren zu können.
Walter K. schrieb im Beitrag #5367834:
> Habe ich was von ISO C geschrieben?
Auf welche Programmiersprache, die wie C aussieht, aber nicht ISO C ist,
beziehen sich denn deine Posts? Falls du es nicht mitbekommen hast, alle
anderen Teilnehmer hier im Thread gehen von ISO C aus.
Rolf M. schrieb:> schlicht und ergreifend falsch. Was du stattdessen mit "C" meinst,> solltest du dann schon erwähnen.
ja o.k. ...
(war nicht so gemeint, das mit Kaffee etc. ..sorry )
Rolf M. schrieb:> Und, hast du das auch gelesen, oder nur das Cover angeschaut? Meine> Aussagen sind nämlich auch für das (schon lange veraltete) ANSI C> gültig.
das stimmt jetzt nicht, denn char ist signed! ..auch wenn Dir das nicht
gefällt
Rolf M. schrieb:> Wilhelm M. schrieb:>> In diesem Thread sind zwei "schöne" Beispiele genannt worden (Typ von>> character-constants und sizeof(<pointer>)). Man könnte weiter machen mit>> _Bool ...>> Diese Sachen finde ich verständlich, wenn man sie sich mal angesehen> hat.
Ja, wenn man sie sich angesehen hat ...
Walter K. schrieb:> Rolf M. schrieb:>> Und, hast du das auch gelesen, oder nur das Cover angeschaut? Meine>> Aussagen sind nämlich auch für das (schon lange veraltete) ANSI C>> gültig.>> das stimmt jetzt nicht, denn char ist signed! ..auch wenn Dir das nicht> gefällt
Schau doch mal tatsächlich nach, bevor du so etwas Falsches behauptest:
C11: 6.2.5/15
"The three types char, signed char, and unsigned char are collectively
called
the character types. The implementation shall define char to have the
same range,
representation, and behavior as either signed char or unsigned char."
Whether plain chars are signed or unsigned is machine-dependent,
2
> but printable characters are always positive.
Und wo steht da nun, dass char nicht signed ist?
'.. but printable characters are always positive.'
vom typ char kann ja mehr als 'printable chracters' sein
Walter K. schrieb:> Und wo steht da nun, dass char nicht signed ist?Walter K. schrieb:> Whether plain chars are signed or unsigned is machine-dependent,
Walter K. schrieb:> Und wo steht da nun, dass char nicht signed ist?
nirgends. Das wäre genauso falsch wie:
Walter K. schrieb:> In C ist char immer signed
Rolf M. schrieb:> Also falsch:> int c = getchar();> int C = toupper(c);>> Richtig:int c = getchar();> int C;> if (c != EOF)> C = toupper((unsigned char)c);> else> C = EOF;
Auch das erste Beispiel ist korrekt und liefert exakt dassselbe Ergebnis
wie das zweite Beispiel, da getchar() alle Zeichen (einschließlich EOF)
in der Darstellung liefert, wie toupper() sie erwartet.
Die Casterei ist nur dann notwendig, wenn das Zeichen als (signed-)
char-Variable vorliegt.
Yalu X. schrieb:> Auch das erste Beispiel ist korrekt und liefert exakt dassselbe Ergebnis> wie das zweite Beispiel, da getchar() alle Zeichen (einschließlich EOF)> in der Darstellung liefert, wie toupper() sie erwartet.
Da hast du recht. Ich hatte getchar() nur verwendet, um irgendwoher das
Zeichen zu bekommen und gar nicht darauf geachtet, dass das auch schon
diese Repräsentation nutzt.
> Die Casterei ist nur dann notwendig, wenn das Zeichen als (signed-)> char-Variable vorliegt.
Also wäre es so falsch: