Für printf und andere String-Fkt. würde ich einen String auch imemr mit
'\0' abschliessen.
Würde mich wundern wenn genau der Source aufm µC läuft.
FEHLER beim Copy&Paste ? ;-)
Versuch das:
Adam P. schrieb:> Für printf und andere String-Fkt. würde ich einen String auch imemr mit> '\0' abschliessen.
hat doch
> callocSinus T. schrieb:> Denk daran, dass ein String mit /0 abgeschlossen werden muss
hat er
Tipp am Rande: Bei der Inkrementierungs-Dereferenzierungs-Geschichte
Klammern setzen. Dann ist auf Anhieb klar was deine Intention war und
was der Code macht wenn man die C Operator Precedence gerade nicht parat
hat ;)
Mit dem Verändern von Parametern innerhalb einer Funktion kann man sich
wie man hier sieht sehr elegant und effizient selbst hereinlegen.
1
voidausgabe(char*str)
2
{
3
char*write_cursor=str;
4
*write_cursor++='A';
5
*write_cursor++='B';
6
*write_cursor++='C';
7
8
printf(write_cursor);
9
}
In dieser Version wäre der Fehler offensichtlich gewesen. 'str' ist im
Hinterkopf als "der String, in den ich schreibe" abgelegt. Wenn man den
String am Ende der Funktion ausgeben will, liegt 'printf(str)' nahe;
dass man 'str' vorher verändert hat, hat man an der Stelle leicht schon
wieder vergessen.
Tom schrieb:> In dieser Version wäre der Fehler offensichtlich gewesen.
Aber wer nutzt ein temp. Arbeitszeiger um etwas zu verändern und
übergibt printf dann nicht das Original?
Peter II schrieb:> Adam P. schrieb:>> printf(str);>> oder ganz böse> printf(str-3);
:-D Ja, wer drauf steht!
Jan H. schrieb:> char *buff = (char*)calloc(11,sizeof(char));
sizeof(char) ist per Definition immer 1. Du kannst also einfach
calloc(11,1) oder noch einfacher malloc(11) schreiben. Der Grund ist,
dass sizeof die Größe des Typs als Vielfache von der Größe von "char"
zurückgibt, und "char" ist nunmal genau 1 char groß, also ist es immer
1. (Siehe z.B. http://en.cppreference.com/w/c/language/sizeof )
Der Cast nach char* ist übrigens in C nicht nötig, nur in C++ - aber da
würde man onehin lieber "new" nutzen.
Dr. Sommer schrieb:> Der Cast nach char* ist übrigens in C nicht nötig, nur in C++ - aber da> würde man onehin lieber "new" nutzen.
bei new müsst man aber wieder die 0 reinschreiben.
Dr. Sommer schrieb:> Welche 0? Ich hätte jetzt so gesagt in C++:
er hat aber calloc verwenden das initialisiert den Speicher mit 0, das
macht new und malloc nicht.
Jan H. schrieb:> Habe das gerade mal ausprobiert.> Da stürzt die .exe ab.
ja, weil du versucht einen kontante, die im nicht schreibbaren Speicher
steht zu überschreiben. Das würde auf einen µC funktionieren, auf den
meisten PCs nicht mehr.
Peter II schrieb:> Jan H. schrieb:>> Habe das gerade mal ausprobiert.>> Da stürzt die .exe ab.>> ja, weil du versucht einen kontante, die im nicht schreibbaren Speicher> steht zu überschreiben. Das würde auf einen µC funktionieren, auf den> meisten PCs nicht mehr.
Wenn ich jetzt mit calloc(), den Speicher "freigebe", klappt es!
Jan H. schrieb:> Wenn ich jetzt mit calloc(), den Speicher "freigebe", klappt es!
mit calloc kann man keinen Speicher freigeben. Keine Ahnung was du
gemacht hast und was dann klappt.
Es ist doch immer wieder Interessant, wie viele Fehler man in so wenig
Zeilen machen kann.
Interessant ist auch, dass das ganze auf 'nem Mega32 geklappt haben
soll.
Da war doch irgendwo eine uralte Schwarte mit den Grundlagen zu "C".
Oder kann es sein, dass man so etwas heute nicht mehr braucht?
Also ich würde sagen man kann den Ansatz: "Learning by doing" auch
übertreiben.
In der Praxis würde ich jeweils noch die Länge des reservierten
Speichers für die Zeichenkette mitgeben und beachten. Ansonsten kann es
bei späteren Anpassungen und Unachtsamkeit durch einen selbst oder
andere Entwickler schnell mal passieren, dass man über den reservierten
Speicher hinaus schreibt und es dann zu nicht gewolltem Verhalten führen
kann, welches nur sehr mühsam aufzuspüren ist.
Jan H. schrieb:> *str++ = 'A';
Wie ist denn da die Reihenfolge?
Zuerst pointer erhöhen (str++) dann dereferenzieren (*(str++)) und dann
'A' zuweisen? Dann würde aber an der ersten übergebenen Adresse nichts
stehen.
Johnny B. schrieb:> In der Praxis würde ich...
Ich habe lediglich seine "fehlerhafte" Fkt. korrigiert, selbst würde ich
so nicht programmieren.
edit:
Die Fkt. ist ansich schon "sinnfrei", wenn eine Fkt. "ausgabe" heißt,
dann soll deren Aufgabe die Ausgabe sein und nicht String-Manipulation
:-D
xxx schrieb:> Wie ist denn da die Reihenfolge?> Zuerst pointer erhöhen (str++) dann dereferenzieren (*(str++)) und dann
nein.
str++ ist post Inkrement also nach dem ;
Reinhold schrieb:> Tipp am Rande: Bei der Inkrementierungs-Dereferenzierungs-Geschichte> Klammern setzen.
Der Ausdruck *str++ ist derart grundlegend für C, dass ich geradezu
davon abraten würde, dort Klammern zu setzen. Sondern raten würde, zu
verstehen, warum das so funktioniert.
An dieser Stelle Klammern zu setzen sorgt eher für Erheiterung
erfahreneren Publikums als für Verständnis beim Lesen.
Es gibt gute Gründe dafür, solche Seiteneffekt-Operationen abzulehnen,
unbeschadet des intuitiven oder unintuitiven Vorrangs der Operatoren.
Aber dann richtig. Also
*str = 'A'; str += 1;
*str = 'B'; str += 1;
um Diskussionen zu vermeiden, was bei
*str++ = *str++ = *str++ = 0;
alles rauskommen kann. ;-)
Reinhold schrieb:> Tipp am Rande: Bei der Inkrementierungs-Dereferenzierungs-Geschichte> Klammern setzen. Dann ist auf Anhieb klar was deine Intention war und> was der Code macht wenn man die C Operator Precedence gerade nicht parat> hat ;)
wir würdest du denn die Klammern setzen wollen?