lama007
OC Addicted
|
@DirtyHarry: Ja, das ist es. gcc rufe ich so auf: gcc file.c -o file.o http://openbook.galileocomputing.de...40028C21F04A198um Abbildung 14.19: Wenn ich mir dies anschaue und nichts übersehen habe, dann war das kein einmaliger Ausrutscher des Autors (*string). Diese Buch zu kübeln würde mir weh tun - erstens gibt es es als Openbook, und zweitens gefällt es mir von der Aufmachung her.
|
that
Hoffnungsloser Optimist
|
http://openbook.galileocomputing.de...40028C21F04A198
um Abbildung 14.19: Wenn ich mir dies anschaue und nichts übersehen habe, dann war das kein einmaliger Ausrutscher des Autors (*string). Zeiger auf Zeiger ist ein recht schwieriges Thema, aber es zu verstehen, lohnt sich. Ja, vor allem wenn man ein Buch über C schreibt... (und dabei ist das Thema gar nicht *so* schwierig) Bei den ersten drei Ausgaben
printf("%p = %c\n", **sort, **sort); printf("%p = %c\n", *sort[0], *sort[0]); printf("%p = %c\n", *(sort[0]+0), *(sort[0]+0));
wurden immer die (Anfangs-)Adressen und Inhalte verwendet, auf die der zweite Zeiger zeigt. Was die Ausgabe auch bestätigt. Die Ausgabe bestätigt, dass das Unsinn ist: Vor dem "=" steht da keine Adresse, sondern der Ascii-Code von 'Z'. Wenn sich der Autor die Ausgabe einmal angeschaut hätte, wäre es ihm vielleicht sogar aufgefallen. ![:)](/images/smilies/smile.gif) Auf einer Plattform, wo auf dem Stack nicht zufällig ein char gleich groß ist wie ein Zeiger, hätte das Programm besonders interessante Effekte. gcc -Wall ist da sogar recht hilfreich: warning: format '%p' expects type 'void *', but argument 2 has type 'int'
Bearbeitet von that am 10.02.2009, 20:15
|
watchout
Legendundead
|
Diese Buch zu kübeln würde mir weh tun - erstens gibt es es als Openbook, und zweitens gefällt es mir von der Aufmachung her. Bei einem Roman oder einem Bilderbuch würde ich dir vielleicht zustimmen, bei einem Sachbuch... nicht. Probier' mal http://en.wikibooks.org/wiki/C_Programmingbzw. http://de.wikibooks.org/wiki/C-ProgrammierungIch hab recht gute Erfahrungen mit Wikibooks was Programmiersprachen angeht, obwohl ich das über C nicht gebraucht hab. Ich möcht auch nochmal herausheben, dass es gerade als Einsteiger sinnvoll ist gcc mit gcc -ansi -pedantic -Wall ...
aufzurufen. Das -ansi kann zwar manchmal etwas nervig sein, aber hilft trotzdem schon alleine dadurch dass man lernt was eigentlich im Standard steht und was nicht.
|
lama007
OC Addicted
|
Ok, mal schauen, ob ich mir das alles merken kann. man gcc
|
watchout
Legendundead
|
Ich hab mir gerade das Kapitel "14.6.1 Zeiger als Rückgabewert" ( http://openbook.galileocomputing.de...40028BF1F0331A3) in dem Buch in der überarbeiteten Version nochmal angeschaut und bin etwas irritiert über den Text, der ist meiner Meinung nach Falsch, und das Beispiel auch wieder. Da wird das alte Beispiel als Negativbeispiel angeführt (Haha sehr witzig), das Neue unterscheidet sich aber nur in der Zeile der Rückgabe und warum das so gemacht wird im "Positivbeispiel" wird nirgendwo erwähnt. Also da mal das "Positivbeispiel": char *eingabe(char *str) {
char input[MAX];
printf("Bitte \"%s\" eingeben: ",str);
fgets(input, MAX, stdin);
return strtok(input, "\n");
}
Also strtok legt scheinbar zwar eigene Strings an, aber doch sicher auch wieder nur am Stack und nicht am Heap oder? Warum sollte das dann so funktionieren? Klar der Compiler meckert nicht, denn er kann nicht erkennen ob strtok eine Adresse vom Stack oder vom Heap zurückgeben wird, aber mehr kann ich mir auch nicht vorstellen. Der Autor meint sogar beim Negativbeispiel darunter dass eben die Daten am Stack liegen etc. sagt aber dass da auf jeden Fall nur "Datenmüll" rauskommen würde, was imho aber genau bei diesen Minimalbeispielen oft gar nicht der Fall ist, weil ja der Stack nicht gelöscht wird und oft die Adressen sogar noch stimmen und dann vielleicht sogar noch die richtigen Daten dort stehen - nur halt eher durch Zufall und Glück als sonstwas (...schmerzhafte Erfahrung...). Oder bin ich da jetzt am Holzweg?
|
semteX
begehrt die rostschaufel
|
So viel text... nein, ist der selbe mist, again. Funktioniert auch nicht. tja, enttäuschend ist das edit: Holy moly /* Möglichkeit3: Einen Zeiger als Argument übergeben */ char *test4(char *ptr){ char buffer[10]; ptr = buffer; strcpy(buffer, "testwert"); return ptr; } kann ma wer erklärn, was das bringen soll? die adresse, wo ptr hin zeigt is ja trotzdem nur am stack... offenbar hat der author ned mal im ansatz verstanden, was scopes sind.. und wieso überhaupt bitte zeiger als argument? wah
Bearbeitet von semteX am 16.02.2009, 12:35
|
Blair
Big d00d
|
bei dem codeschnippsel da kommt einem sowieso das speibn :P der ptr als parameter muß eh ned schlecht sein - wenn er richtig verwendet werden tät ![;)](/images/smilies/wink.gif) void blablubb( char* ptr ) { char buf[10]; //buf irgendwie anschreiben von stdin zb strcpy(ptr, buf); } da brauchst dann garkeinen returnvalue mehr ansich, der steht dann an der adresse vom parameter drin, mit ginge das natürlich auch, weil ja einfach nur die adresse vom parameter zurückgegeben werden würde. mal jetzt so ohne bufferüberlaufkontrolle und sonstigem zeug. das funktioniert sehrwohl. der übergebene parameter kann da sowohl am stack, als auch am heap sein. wundert mich nicht wenn soviel buggy software im umlauf is, wenn die alle das openbook von denen gelesen haben
|
semteX
begehrt die rostschaufel
|
bei dem codeschnippsel da kommt einem sowieso das speibn :P
der ptr als parameter muß eh ned schlecht sein - wenn er richtig verwendet werden tät ![;)](/images/smilies/wink.gif)
void blablubb( char* ptr ) { char buf[10]; //buf irgendwie anschreiben von stdin zb strcpy(ptr, buf); }
da brauchst dann garkeinen returnvalue mehr ansich, der steht dann an der adresse vom parameter drin, mit ginge das natürlich auch, weil ja einfach nur die adresse vom parameter zurückgegeben werden würde.
mal jetzt so ohne bufferüberlaufkontrolle und sonstigem zeug. das funktioniert sehrwohl.
der übergebene parameter kann da sowohl am stack, als auch am heap sein.
wundert mich nicht wenn soviel buggy software im umlauf is, wenn die alle das openbook von denen gelesen haben ![;)](/images/smilies/wink.gif) gott (und das /GS flag) schütze dich, wenn für ptr weniger als 9 (+1 Terminierung) Zeichen reserviert wurden ![;)](/images/smilies/wink.gif) aber das nur am rande (ja ich weiß, dass ma bei so nem schnipsel sicher ned drauf gschaut hat, ich möchts dennoch erwähnen ![;)](/images/smilies/wink.gif) ) prinzipiell is das aber gut und richtig, so wie du das schreibst ![:)](/images/smilies/smile.gif) ob wir denen von openbook den link zum thread schickn sollen hier?
|
DirtyHarry
aka robobimbo
|
hehe, das wär ein gag
|
Ringding
Pilot
|
strtok verwendet einen statischen Puffer. Das würde also sogar funktionieren, außer in Multi-Thread-Situationen. Aber dafür gibt's ja strtok_r.
|
semteX
begehrt die rostschaufel
|
strtok verwendet einen statischen Puffer. Das würde also sogar funktionieren, außer in Multi-Thread-Situationen. Aber dafür gibt's ja strtok_r. ganz sicher? Mein VS2008 is nämlich ziemlich unglücklich damit (im sinne von: Es liest nur mist ausm speicher) edit: ich seh da nix von wegen statischem puffer. bin ich blind? http://www.koders.com/c/fid9E7961E1...82726B3FCD.aspx
Bearbeitet von semteX am 16.02.2009, 18:39
|
lama007
OC Addicted
|
Diese zwei sind nach meinem Verständnis auch nicht korrekt: /* union2.c */
#include <stdio.h>
#include <stdlib.h>
union number {
float x;
int y;
};
int main(void) {
union number mixed[2];
mixed[0].x = 1.123;
mixed[1].y = 123;
mixed[2].x = 2.345;
printf("%.2f\t%d\t%.2f\n", mixed[0].x, mixed[1].y, mixed[2].x);
return EXIT_SUCCESS;
}
/* count_char.c */
#include <stdio.h>
#include <stdlib.h>
int main (void) {
int c,counter=0;
printf("Bitte Eingabe machen:");
/* Eingabe machen bis mit Return beendet wird */
while((c=getchar()) != '\n') {
/* Leerzeichen und Tabulatorzeichen nicht mitzählen */
if( (c != ' ') && (c != '\t') )
counter++; /* counter erhöhen */
}
/* Gibt die Anzahl eingegeb. Zeichen von 0 bis counter-1 aus
* mit counter-1 wird das Zeichen '\0' nicht mitgezählt */
printf("Anzahl der Zeichen beträgt %d Zeichen\n", counter-1);
return EXIT_SUCCESS;
}
Aber das Buch passt mir recht gut; vielleicht gehören die Fehler zum pädagogischen Konzept des Buches .
|
Ringding
Pilot
|
ganz sicher? Mein VS2008 is nämlich ziemlich unglücklich damit (im sinne von: Es liest nur mist ausm speicher)
edit: ich seh da nix von wegen statischem puffer. bin ich blind? http://www.koders.com/c/fid9E7961E1...82726B3FCD.aspx Ah sorry, nein du bist nicht blind. Den statischen Puffer verwendet es nur intern. Aber es gibt ein paar solche lustigen Funktionen, die so einen Puffer returnen.
|
semteX
begehrt die rostschaufel
|
Diese zwei sind nach meinem Verständnis auch nicht korrekt:
Aber das Buch passt mir recht gut; vielleicht gehören die Fehler zum pädagogischen Konzept des Buches .![:D](/images/smilies/biggrin.gif) beides richtig (du) bzw falsch(das buch), zum ersten: ein float ist nix für fließkommazahlen zum zweiten: jein... getchar speichert alle tasteneingaben zwischen und liefert die dann zeichenweise wieder raus... so weit so gut. c ist zwar in dem beispiel ein integer, macht aber eigentlich auch nix, jedes character zeichn wird ja sowieso als zahl repräsentiert. is halt der falsche datentyp, aber solang der gewählte zu groß und ned zu klein ist, ned viel passiert was ich mich grad aber frag ist: wieso sagt mein debugger in der while (...) zeile, dass c den wert 'a' hat (bei abcd als eingabe). wenn ich dann nen single step runter mach zu den IFs, hat c auf einmal den wert 'b'... da passt was ned...
Bearbeitet von semteX am 16.02.2009, 23:20
|
Luzandro
Here to stay
|
ein float ist nix für fließkommazahlen sondern? das mixed wird allerdings zu klein initialisiert c ist zwar in dem beispiel ein integer, macht aber eigentlich auch nix, jedes character zeichn wird ja sowieso als zahl repräsentiert. is halt der falsche datentyp, aber solang der gewählte zu groß und ned zu klein ist, ned viel passiert getchar liefert tatsächlich einen int zurück (iirc ist EOF ein int)
Bearbeitet von that am 17.02.2009, 21:42 (sorry, falscher Button )
|