Verständnisfrage: Datentypen in C



  • Vielen Dank für die vielen Antworten!

    "Adressierbare Einheiten", das kommt soweit ich mich erinnere hierher:

    https://www.youtube.com/watch?v=naXqxJ95myw&list=PL5eolwFmTdvj6uEwatR3NrPLDtGV3Qln6&index=4

    Bei 53:22 min (Die Bezeichnung kommt aber so 53:50 oder so)

    Ich fasse das was ihr gesagt habt, mal zusammen:
    Es ist also zumindest möglich, im Arbeitsspeicher einzelne Bytes zu adressieren. Ein char ist ein Byte groß. Die Zahl, die der sizeof-Operator zurückgibt, ist die Anzahl der Bytes, die der Operand im Speicher verbraucht.



  • @joshuah sagte in Verständnisfrage: Datentypen in C:

    Die Fragen, die ich mir jetzt stelle sind "Wenn Binärfolge A an Adresse X abgelegt ist, wo ist dann die Information abgelegt, wie A zu interpretieren ist, also als int, double etc?"

    Im Source-Code, beim deklarieren der Variablen.
    C ist eine typisierte Sprache, du kannst den Typ einer Variable nicht nachträglich ändern.

    @joshuah sagte in Verständnisfrage: Datentypen in C:

    Ein char ist ein Byte groß.

    Ein Byte muss (in C) aber nicht 8 Bit groß sein.
    Das können auch 9 Bit oder auch 16 oder 24 Bit (z.B auf DSP) sein



  • Zusätzlich zu dem was DirkB gesagt hat, ich finde, du versteifst dich etwas zu sehr auf Details und deine eigenen Formulierungen sind deswegen auch etwas zu umständlich. Lern doch einfach C, fang an zu programmieren, dann wird das alles einfach klar sein und dann kannst du dir auch die ganzen Details aneignen. Die wären dann auch nicht mehr verwirrend, weil ich kann mir nicht vorstellen, dass es dir im Moment irgendwie weiterhilft, wie groß ein char ist oder sein kann.



  • @dirkb sagte in Verständnisfrage: Datentypen in C:

    @joshuah sagte in Verständnisfrage: Datentypen in C:

    Ein char ist ein Byte groß.

    Ein Byte muss (in C) aber nicht 8 Bit groß sein.
    Das können auch 9 Bit oder auch 16 oder 24 Bit (z.B auf DSP) sein

    Garantiert ist nur, daß die Anzahl an Bits in einem char (CHAR_BIT) größer oder gleich 8 ist.



  • Okay, ich glaube ich weiß jetzt ein wenig mehr, vielen Dank euch allen .

    @Mechanics
    Ich glaube es ist kein Fehler, Dinge die unklar sind, hartnäckig zu hinterfragen. Aber natürlich hast du absolut nicht unrecht wenn du sagst, dass man eine Programmiersprache nur lernen kann, wenn man darin programmiert.



  • @joshuah sagte in Verständnisfrage: Datentypen in C

    @Mechanics
    Ich glaube es ist kein Fehler, Dinge die unklar sind, hartnäckig zu hinterfragen.

    Nein, das sicher nicht, versteh mich nicht falsch. Nur hörte sich deine Zusammenfassung für mich z.B. zu steif an. Nicht so, als ob du das wirklich grundlegend verstanden hättest, eher, als hättest du versucht, etwas auswendig zu lernen. Dabei sind es noch eher triviale Sachverhalte, die würdest du wahrscheinlich wirklich gleich verstehen, wenn du ein bisschen damit arbeiten würdest.



  • Da sprichst du mir aus der Seele @Mechanics ^^ Ob ich das Ganze wirklich verstanden habe - wessen ich mir jetzt gerade relativ sicher bin, aber das ist nur mein subjektives Empfinden - wird die Zukunft zeigen.


  • Mod

    Mir tat beim Lernen die Vorstellung ganz gut, einem Programm wirklich bei der Arbeit in den Speicher zu gucken, und den Speicher dabei als lineare Abfolge von Speicherstellen zu visualisieren (wo jede Speicherstelle ganz neutral ein Byte aufnehmen kann, und keine Ahnung von der höheren logischen Organisation der Daten hat). In einem Programmierlehrbuch für Kinder war da eine Bilderserie mit einer Reihe Schließfächern. In der Schule hatten wir einen Lerndebugger, wo man ein Programm (Assembler-)Schritt für Schritt ausführen konnte mit einer übersichtlichen Darstellung, was zu jedem Zeitpunkt wo im Speicher steht.

    Leider ist das ein bisschen zu groß, für einen Forenbeitrag. Und echte Debugger mit echten Programmen haben im Hintergrund viel zu viel Rauschen (alleiene schon, was es ein Aufwand ist, ein Zeichen auszugeben!) und viel zu viele Verkomplizierungen durch technische Details (Register, ...). Aber vielleicht kennt jemand irgendeine gute Seite mit einer Darstellung dieser Art?



  • @seppj Das hört sich mega interessant an o.O Ich werde mich mal nach tools/Büchern etc. umschauen, die sowas in der Richtung machen.

    Abgesehen davon war ja eine meiner Eingangsfragen, wie ein Programm zur Laufzeit Datentypen memorisiert. Tut es das überhaupt, oder ist das mehr eine Erscheinung, die nur im Quellcode vorkommt, und die auf Assemblerebene keine Rolle mehr spielt? Vielleicht weil der Compiler Operationen nur auf für sie sinnvolle Operanden anwendet, wäre jetzt mein Gedanke dazu.



  • @joshuah sagte in Verständnisfrage: Datentypen in C:

    Tut es das überhaupt, oder ist das mehr eine Erscheinung, die nur im Quellcode vorkommt, und die auf Assemblerebene keine Rolle mehr spielt?

    Hier kannst Du ganz deutlich sehen, daß für verschiedene Datentypen unterschiedlicher Assemblercode erzeugt wird.

    Genau wie @Mechanics schon gesagt hat:

    @mechanics sagte in Verständnisfrage: Datentypen in C:

    Wenn du in C Code schreibst und Variablen referenzierst, dann wird entsprechener Maschinencode generiert, der die Daten eben so interpretieren will, wie du das geschrieben hast.


  • Mod

    Variablen im C-Programm sind streng genommen nur ein abstraktes Hilfsmittel für den Programmierer. Die müssen später kein direktes Äquivalent im Maschinencode haben. Es ist nur garantiert, dass sich das fertige Programm später so verhält, "als ob" da wirklich mit Variablen im Hintergrund gearbeitet wird.

    Eine der Möglichkeiten für ein Maschinenprogramm, sich so zu verhalten, als ob es mit einer echten 1:1 Abbildung von Variablen zu Speicherstellen arbeitet, ist offensichtlicherweise eben genau das zu tun: Jeder Variablen irgendwie eine Stelle im Arbeitsspeicher zuzuordnen. Muss es aber nicht. Es gibt auch viele andere Möglichkeiten und oft sind diese anderen Möglichkeiten viel effizienter. Ein Beispiel wäre:

    for(int i=0; i<5; ++i)
      tu_was();
    

    Eine Möglichkeit für äquivalenten Maschinencode wäre, tatsächlich irgendwo eine Speicherstelle für i anzulegen, ihr den Wert 0 zuzuweisen, diesen wieder und wieder um 1 zu erhöhen, und danach stets die Bedingung zu prüfen. Eine andere Möglichkeit, das gleiche Programm in Maschinencode auszudrücken wäre aber, einfach nur die Funktion tu_was fünf Mal nacheinander aufzurufen. Die beiden fertigen Programme sind dann äquivalent, beides sind gültige Maschinenprogramme zu diesem C-Quellcode. Aber bei letzterem gibt es auf Maschinenebene nichts mehr, was der Variable i auch nur irgendwie ähnlich sieht.

    Häufig werden Compiler, wenn sie angewiesen werden, keine Optimierungen durchzuführen, eher Maschinencode erzeugen, der eher der klassischen Vorstellung mit Variablen entspricht. Hochoptimierter Code ist hingegen oft eher von der Art, dass man eigentlich nicht mehr wirklich erkennen kann, was das mit den Variablen im C-Code zu tun hat. Bloß das letztlich sichtbare Ergebnis wird bei all diesen verschiedenen Möglichkeiten das gleiche sein.

    PS: Wie du siehst, hat Swordfish aus diesem Grund bei seinem Beispiel aus den von mir beschriebenen Gründen extra die Compileroption -O0 gewählt, das heißt er hat alle Optimierungen ausgeschaltet. Wenn du Optimierungen wieder anschaltest, siehst du, dass von den Variablen und Datentypen nichts mehr übrig bleibt:
    https://godbolt.org/z/MWQ3Nj



  • Ha, wunderbar . Tatsächlich, ich konnte zwar den Link nicht öffnen, aber diese Seite zeigt das trotzdem sehr klar, ich hab mal ein bisschen rumprobiert. Vielen Dank euch auch für eure Mühen. Ich glaube, ich kann mir jetzt sehr viel selbst erschließen! .



  • @joshuah sagte in Verständnisfrage: Datentypen in C:

    Abgesehen davon war ja eine meiner Eingangsfragen, wie ein Programm zur Laufzeit Datentypen memorisiert. Tut es das überhaupt, oder ist das mehr eine Erscheinung, die nur im Quellcode vorkommt, und die auf Assemblerebene keine Rolle mehr spielt? Vielleicht weil der Compiler Operationen nur auf für sie sinnvolle Operanden anwendet,

    Du (als Programmierer) teilst dem Compiler mit der Deklaration der Variablen mit, wie er sie behandeln soll.

    Mit double a; weiß der Compiler, dass er entsprechenden Code für Fließkommaoperationen einbauen muss, wenn er diese Variable a behandelt.
    Da diese Information schon zur Compilezeit festgelegt wird, braucht auch nur der Compiler wissen, was a ist.
    Im fertigen Programm ist dieses Verhalten dann fest eingebaut.
    Der Bezeichner a taucht da auch nicht mehr auf. Eher sowas wie "die Adresse Stackpointer+8"


  • Mod

    @dirkb sagte in Verständnisfrage: Datentypen in C:

    Der Bezeichner a taucht da auch nicht mehr auf. Eher sowas wie "die Adresse Stackpointer+8"

    Und ganz wichtig (da ich irgendwie das Gefühl habe, das ist beim TE noch nicht angekommen), es steht auch nirgendwo "an der Adresse liegt ein double". Das Maschinenprogramm hat halt Anweisungen fest eingebaut, die diese Adresse stets in Fließkommaregister schieben und Fließkommabefehle darauf ausführen.



  • Hi(gh)!

    @swordfish sagte in Verständnisfrage: Datentypen in C:

    Hier kannst Du ganz deutlich sehen, daß für verschiedene Datentypen unterschiedlicher Assemblercode erzeugt wird.

    Also, ich bekomme nur eine Fehlerseite mit der Textausgabe "Cannot GET /z/NzJmN2"...

    Bis bald im Khyberspace!

    Yadgar



  • @yadgar keine Ahnung, was godbolt.org da für nen Mist baut. Neuer Link: di dub di dub

    //edit: die bauen z. Zt. mit allen ihren Links mist. abwarten, teetrinken.


Anmelden zum Antworten