Zeiger, Adressen und time.h



  • Hallo,
    hab ich das richtig verstanden?

    time_t now;     //erstelle var. im time_t format(long int)
    time(&now);     //rufe time auf, welche die sek. seit 1970 in now-adresse speichert
    struct tm *myTm;     //erstelle zeiger auf struct tm
    myTm = localtime(&now);       //fülle struct tm über localtime und speichere ergebnis in myTm
    printf("%s\n", asctime(myTm));
    

    ABER:
    wieso time(&now) und nicht time(now)
    und
    wieso localtime(&now) und nicht localtime(now)
    warum wird hier immer mit den adressen hantiert - was passiert innerhalb von time() und localtime()?

    Grüße 😃



  • Der Inhalt der struct soll doch mit den aktuellen Daten gefüllt werden.
    Da muss die Funktion schon wissen wo die Daten hin sollen.

    (Bei scanf wundert dich das nicht?)



  • wieso, wenn eine funktion irgendwas in eine variable schreiben soll, schreib ich ja auch nicht &var... 😕



  • scanf ist eine Funktion und da schreibst du &var
    Und bei modf wird es auch genutzt.

    Und das sind nur Beispiele aus der Standard Library.

    Ganz früher, noch vor C89, gab es in den Urzeiten von C (also im letzten Jahrtausend) Compiler, die konnten stucts noch nicht direkt zuweisen oder als Rückgabewert von Funktionen nutzen.*

    time() und localtime() stammen noch aus der Zeit.

    *So steht es zumindest im K&R 1.Ausgabe deutsch von 1983



  • thx 👍
    hmmm...vllt. find ich iwo den aufbau der funktionen 🙂



  • S3raph1m. schrieb:

    wieso, wenn eine funktion irgendwas in eine variable schreiben soll, schreib ich ja auch nicht &var... 😕

    Doch, eigentlich immer.

    Zwar können Funktionen auch ein Rückgabewert haben, aber wenn die Funktion mehrere Informationen zurückgibt oder verändern soll, wird mit Zeigern gearbeitet.
    Das Prinzip nennt sich call by reference http://de.wikipedia.org/wiki/Referenzparameter.

    void funktion(irgendeintyp *hier_reinschreiben);
    

    Schließlich muss der Speicher für die Information ja irgendwo her kommen, in den die Unterroutine schreibt. Und da ist es sinnvoller, dass sich die aufrufende Routine um die Bereitstellung kümmert.
    Ist zwar für den Programmierer etwas komplexer, aber dafür muss auch nicht zur Laufzeit groß was hin- und her kopiert werden.

    Müssen Funktionen nur zwei, vier, acht Byte eines Standardstyps zurückgeben, ist die klassische Variante über Rückgabewerte für den Programmierer einfacher und auch meist effizienter, da der Compiler dann mit CPU-Registern arbeitet.

    Ciao, Allesquatsch



  • Allesquatsch schrieb:

    Müssen Funktionen nur zwei, vier, acht Byte eines Standardstyps zurückgeben, ist die klassische Variante über Rückgabewerte für den Programmierer einfacher und auch meist effizienter, da der Compiler dann mit CPU-Registern arbeitet.

    Quatsch.
    "Einfacher" für den Programmierer ist es immer, sich ausschließlich definierte Systemumgebungen (hier C Standard) zu verlassen und eben nicht irgendwelche Annahmen zu treffen, was der Compiler wohl macht bzw. optimiert.
    Und für die Rückgabe von mehreren (Einzel)Werten aus Funktionen gibt es schon lange struct, und die ist oftmals eben "breiter" als irgendwelche angenommenen oder tatsächlichen Registerbreiten.



  • Wutz schrieb:

    Allesquatsch schrieb:

    Müssen Funktionen nur zwei, vier, acht Byte eines Standardstyps zurückgeben, ist die klassische Variante über Rückgabewerte für den Programmierer einfacher und auch meist effizienter, da der Compiler dann mit CPU-Registern arbeitet.

    Quatsch.
    "Einfacher" für den Programmierer ist es immer, sich ausschließlich definierte Systemumgebungen (hier C Standard) zu verlassen und eben nicht irgendwelche Annahmen zu treffen, was der Compiler wohl macht bzw. optimiert.

    Ein klares JEIN.
    Wenn man "richtig" programmiert, muss man ein Verständnis davon haben, was Stack und Heap sind. Mangelndes Verständnis führt dann dazu, dass man plötzlich auf's Nirvana referenziert. Oder dass man nicht versteht, wieso viele Bibliotheken eben keinen struct als Rückgabewert liefern sondern einen Pointer als Parameter nutzen.
    Erst mit diesem Verständnis wird klar, wieso es (mindestens) zwei verschiedene Wege gibt, wie Funktionen ihre Ergebnisse zurückliefern.

    Darüber, wie ob der Compiler jetzt Parameterübergaben über Register oder Stack macht, braucht man sich natürlich nicht den Kopf zerbrechen. Zumindest bei den meisten Entwicklungsaufgaben.

    Ciao, Allesquatsch



  • Allesquatsch schrieb:

    Wenn man "richtig" programmiert, muss man ein Verständnis davon haben, was Stack und Heap sind.

    Quatsch. Im C-Standard steht nichts von Stack,Heap usw. und genau diese Abstrahierung übernimmt nämlich der Compiler und gießt sie in konkreten Code, dessen Ausprägung eben sinnvollerweise nicht von Entwicklern angenommen werden darf, u.U. (meistens) ist nämlich der Compiler sehr viel schlauer als derjenige vor dem Bildschirm und entscheidet selbständig, was performant und sinnvoll für das Compilat ist oder nicht.
    Stack/Heap usw. sind nur Hilfskrücken der Entwickler, um etwas auszudrücken, und daraus schlussfolgernde "Annahmen" der Entwickler, "Stack ist schneller als Heap" und Sonstiges sind immer nur subjektiv, und Überraschungen vorprogrammiert (im wahrsten Sinne des Wortes).
    Das alles kennzeichnet eben eine Hochsprache, die C trotz alledem darstellt.


Anmelden zum Antworten