"We are back" « oc.at

[C] return - zeiger

lama007 08.02.2009 - 19:31 6766 52 Thread rating
Posts

lama007

OC Addicted
Avatar
Registered: Mar 2002
Location: Austria
Posts: 851
@DirtyHarry: Ja, das ist es.

gcc rufe ich so auf: gcc file.c -o file.o

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).

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
Avatar
Registered: Mar 2000
Location: MeidLing
Posts: 11342
Zitat von lama007
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).

Zitat
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)

Zitat
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. :) 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:

Code:
warning: format '%p' expects type 'void *', but argument 2 has type 'int'
Bearbeitet von that am 10.02.2009, 20:15

watchout

Legend
undead
Avatar
Registered: Nov 2000
Location: Off the grid.
Posts: 6845
Zitat von lama007
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_Programming
bzw. http://de.wikibooks.org/wiki/C-Programmierung

Ich 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
Code:
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
Avatar
Registered: Mar 2002
Location: Austria
Posts: 851
Ok, mal schauen, ob ich mir das alles merken kann.

man gcc :eek:

watchout

Legend
undead
Avatar
Registered: Nov 2000
Location: Off the grid.
Posts: 6845
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":
Code:
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
Avatar
Registered: Oct 2002
Location: Pre
Posts: 14699
Zitat von watchout
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
Avatar
Registered: Dec 2004
Location: Graz
Posts: 177
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 ;)

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
Avatar
Registered: Oct 2002
Location: Pre
Posts: 14699
Zitat von Blair
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 ;)

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 ;)
gott (und das /GS flag) schütze dich, wenn für ptr weniger als 9 (+1 Terminierung) Zeichen reserviert wurden ;) 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 ;))

prinzipiell is das aber gut und richtig, so wie du das schreibst :)

ob wir denen von openbook den link zum thread schickn sollen hier?

DirtyHarry

aka robobimbo
Avatar
Registered: Apr 2001
Location: outer space
Posts: 464
hehe, das wär ein gag :)

Ringding

Pilot
Avatar
Registered: Jan 2002
Location: Perchtoldsdorf/W..
Posts: 4300
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
Avatar
Registered: Oct 2002
Location: Pre
Posts: 14699
Zitat von Ringding
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
Avatar
Registered: Mar 2002
Location: Austria
Posts: 851
Diese zwei sind nach meinem Verständnis auch nicht korrekt:

Code:
/* 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; 
}

Code:
/* 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 .:D

Ringding

Pilot
Avatar
Registered: Jan 2002
Location: Perchtoldsdorf/W..
Posts: 4300
Zitat von semteX
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
Avatar
Registered: Oct 2002
Location: Pre
Posts: 14699
Zitat von lama007
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
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
Avatar
Registered: Mar 2006
Location: 2482
Posts: 708
Zitat von semteX
ein float ist nix für fließkommazahlen

sondern? das mixed wird allerdings zu klein initialisiert

Zitat
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 :()
Kontakt | Unser Forum | Über overclockers.at | Impressum | Datenschutz