Skip to forum
Benachrichtigungen
Alles löschen

Linux Man Pages + C-Programmierung

10 Beiträge
4 Benutzer
11 Reactions
1,615 Ansichten
Psychobilly1988
Joined: 10.03.2009

Stehe extrem auf dem Schlauch.

Ein Beispiel aus einer kleinen Übungsaufgabe:
Das Kommando "Date", gibt [...] aus. Schreiben Sie ein Programm dass die gleiche Ausgabe mithilfe von time(), gefolgt von ctime() erzeugt.

So, nun schau ich mir die Manpage von ctime an, lese dann:

char *ctime(const time_t *timep);

Geil! :f_love:
Verstehe nur wirklich nicht, was mir das jetzt sagen soll und ich wie das implementieren kann.
Kann mir jemand erklären, wie das alles zu verstehen ist?

scanf z.b hat ja auch sowas
int scanf(const char * restric format, ...);

Komme einfach super durcheinander mit Datentypen und Pointern, wenn ich sowas sehe...


Antwort
Zitat
9 replies
Django3
Joined: 16.10.2009

time() gibt dir die Zeit als time_t zurück. Du brauchst also eine Variable vom Typ time_t in der du das Ergebnis von time() speicherst. Mit Hilfe von ctime kannst du dann dieses time_t in einen char-Pointer (also quasi in Text) umwandeln. Dazu legst du eine Variable vom Typ char* an und speicherst darin das Ergebnis von ctime(). ctime() selbst kriegt als Übergabeparameter einen Pointer auf ein time_t - also einen Pointer auf deine zu Beginn angelegte Variable. Das const in der Argumentliste garantiert dir lediglich, dass die Funktion ctime() mit deinem time_t-Pointer keinen Unfug macht. Also dass ctime den übergebenen Parameter nicht verändert.


Antwort
Zitat
sarc
Joined: 06.06.2008

Verstehst du den Unterschied zwischen einer Pointervariablen und einer "normalen"? Also, wenn du beispielsweise so was hast:

int a;
int *b;

Worin unterscheidet sich das, wie musst du damit umgehen? Nächste Frage wäre, warum man Pointer hat und wofür die eingesetzt werden (dann verstehst du auch das Verhalten und die Definition der Funktionen besser).

Und, wenn du das mal alles drin hast, darfst du dir auch noch mal Gedanken drüber machen, warum die ctime-Funktion dann gar nicht mal so harmlos ist, wie sie aussieht. Ist zumindest nicht selbstverständlich, dass das so geht. Tipp dazu: Code in der Art

char *foo(void) {
  return "test";
}

kann dir ganz fürchterlich um die Ohren fliegen.

Spoiler

C-Spezialisten dürfen mir jetzt gern erklären, dass das in dem Spezialfall tatsächlich funktionieren könnte. Könnte ich mir zumindest vorstellen, dass das möglich wäre, aber wissen tu ichs an der Stelle nicht... Hat da zufällig jemand Ahnung von?


Antwort
Zitat
Django3
Joined: 16.10.2009

Original von sarc
Tipp dazu: Code in der Art

char *foo(void) {
  return "test";
}

kann dir ganz fürchterlich um die Ohren fliegen.

Auf was willst du hinaus? Ich sehe da nichts, was einem irgendwie um die Ohren fliegen könnte. Vielleicht steh ich aber auch einfach nur auf dem Schlauch.


Antwort
Zitat
flowIIpoker
Joined: 14.02.2007

wir sind doch alle hier, um etwas zu lernen

ich bin selbst keiner, der c programmiert (erfolgreich seit 1989 davor gedrueckt) aber ich hab massives interesse etwas zu lernen.

also @sarc hier lauschen mindestens zwei ohren :)


Antwort
Zitat
sarc
Joined: 06.06.2008

Ich wollte auf das generelle Problem hinaus, dass Pointer als Rückgabetypen gefährlich sind. Pointer sind ja bekanntlich Datentypen, in denen Adressen gespeichert sind. ein char * hat also die Adresse für einen Char (und C baut sich daraus dann Strings, indem es aufeinanderfolgende Chars sucht, bis das Ende durch \0 angezeigt wird). Jetzt generierst du dir also in einer Funktion irgendetwas und gibst dann den Zeiger darauf zurück. Wenn das normal programmiert ist ("normal" ist jetzt halt im Sinne von "wie man es aus Java kennt" ;)), dann hast du dein neues Zeug im lokalen Scope der Funktion abgelegt. Sobald du die Funktion verlassen hast, ist aller Speicher, den diese Funktion gebraucht hat, wieder frei verfügbar. Dein Zeiger zeigt aber genau da rein, nur dass da in dem MOment wo du drauf zugreifst theoretisch alles stehen kann. Bei Strings besonders doof, weil die halt keine fixe Länge haben, sondern erst mal bis \0 gelesen wird. Das führt entweder zu unverständlichen Ausgaben oder direkt zum Crash. Du musst also mehr machen als einfach nur die Variable anlegen.

Spoiler

Aber wie gesagt, ich bin kein Experte für C-Compiler. Halte es für nicht ausgeschlossen, dass String-Konstanten (und das haben wir in meinem Beispiel) mal direkt von Anfang an irgendwo angelegt werden, und dann halt doch dauerhaft da liegen...


Antwort
Zitat
flowIIpoker
Joined: 14.02.2007

danke,

mehr oder weniger hab ich genau das vermutet was du ansprichst (garbagecontrol)..
deswegen hab ich ja auch die "angst", oder "respekt" vor der sprache und schreib blos code in meinen heimatsprachen :)
ps: ich wuerde gern unsern newbe begleiten wollen, er hat ja zumindestens die man pages gefunden .. ist ja heute nicht unbediengt selbstverstaendlich


Antwort
Zitat
Django3
Joined: 16.10.2009

Original von sarc
Aber wie gesagt, ich bin kein Experte für C-Compiler. Halte es für nicht ausgeschlossen, dass String-Konstanten (und das haben wir in meinem Beispiel) mal direkt von Anfang an irgendwo angelegt werden, und dann halt doch dauerhaft da liegen...

Volltreffer. Genau das passiert. Beim Kompilieren wird an diese Stringliterale die Nullterminierung drangepackt und dann wird das Ganze statisch abgelegt. In diesem Fall ist es also tatsächlich unproblematisch. Allgemein hast du natürlich Recht, dass beim Zurückgeben von Pointern auf lokale Daten sehr viel Unsinn passieren kann.


Antwort
Zitat
Psychobilly1988
Joined: 10.03.2009

Sorry, hatte die Tage ultra viel zu tun.
Hab aber zwischendurch immer wieder hier reingeschaut...

Ist peinlich zu sagen, aber ich hab einfach auf dem Schlauch gestanden, weil ich nicht gemerkt habe dass ich das als Funktionen (Funktionsprototypen, etc) sehen kann.
Weiß aber ehrlich gesagt auch nicht mehr genau, was ich eigentlich letzte Woche daran nicht kapiert habe.

Finde die Erklärungen in den Manpages aber dennoch recht verwirrend, als "C-Anfänger"...
klar weiß ich was normale Variablen, Pointer, etc sind, verstehe auch wie sich globale, lokale Variablen verhalten usw...
Aber die Anwendung von so billigen Sachen wie Zeit ausgeben, erfordert tatsächlich mehr denken als ich erwartet habe, weil so vieles zusammen kommt...ist wohl ne Übungssache


Antwort
Zitat
sarc
Joined: 06.06.2008

@Django: Dann war das Beispiel doch blöd gewählt... Wollt das nicht zu kompliziert machen und was basteln, wo das Problem auf jeden Fall auftritt, wär dann aber wohl doch geschickter gewesen. Danke!

@flowIIpoker: Ist jetzt zwar fiese Klugscheißerei, aber mit Garbage Control hat das nix zu tun. ;) Garbage Control bedeutet, dass die Sprache selber Speicher freiräumt, der ihrer Meinung nach nicht mehr gebraucht wird. Bei Java beispielsweise werden Objekte generell im Heap abgelegt, der vom Garbage Controller wieder aufgeräumt werden kann. Aber auch bei Java ist es so, dass lokale Variablen (solangs keine Referenztypen sind) auf dem Stack liegen und dort, sobald sie nicht mehr im Scope sind (also beispielsweise die Funktion durchgelaufen ist) direkt wieder entfernt werden. Der einzige Unterschied ist: Dort hast du gar nicht erst die Möglichkeit, mit nem Zeiger auf so ne lokale Variable zu arbeiten. In C ist es nun so, dass erst mal jede lokale Variable auf den Stack kommt. Wenn du das irgendwie anders haben willst, musst du dich da explizit drum kümmern. Das ist einerseits sehr viel mächtiger (und schneller) als Java, aber du kannst dir da auch ganz bös ins Knie schießen.


Antwort
Zitat