Habe ich das mit den Makros verstanden?



  • Hi, hi

    ich bin mir nicht sicher ob ich das mit den Makros verstanden habe.

    Makros kommen in eine .h Datei und Symbolische Konstanten sind z.B.

    #define PI 3.14 //gehören diese auch in eine .h Datei?);
    

    Am Anfang einer Makro-Header-Datei kommt:

    #ifndef _MYMAKROS_ //Name der Header mymakros.h, für was ist '_'?
    #define _MYMAKROS_
    

    Das macht man damit der Compiler diese Header Datei nicht immer compilieren muss, oder?

    Stimmt das alles so 😕



  • FUNPAQ schrieb:

    #define PI 3.14 //gehören diese auch in eine .h Datei?);
    

    Ja

    FUNPAQ schrieb:

    für was ist '_'?

    Das kann man auch weglassen, theoretisch könntest du auch den Namen "MeineHe_a_de_r_DATEI" oder "Computer" benutzen (allerdings ist es sinnvoll, immer den Dateinamen zu verwenden).
    Den Nutzen von _MYMAKROS_ kannst du dir so vorstellen:
    Wenn der Compiler zum ersten Mal durch

    #include "mymakros.h"
    

    auf diese Header-Datei verlinkt wird, ist _MYMAKROS_ noch nicht definiert. Also gibt

    #ifndef _MYMAKROS_    // ifndef = if not define
    

    den Wert true zurück und alles bis zu "#endif" (das setzt du ans Ende der Datei) wird kompiliert.

    Wenn der Compiler ein zweites Mal die Header-Datei kompilieren soll, ist _MYMAKROS_ definiert. Also ergibt die Anfrage am Anfang den Wert "false" zurück und alles bis zum "#endif" wird nicht ausgeführt. Wenn "#endif" ganz am Ende steht, wird nichts von der Header-Datei kompiliert.
    So wird zum Beispiel verhindert, dass Funktionen zwei mal definiert werden.



  • statt #define PI 3.1415
    verwendet man
    float const PI = 3.1415
    sofern wir hier von C++ reden. bei C ist das #define OK

    Namen die mit Unterstrich und Grossbuchstabe beginnen, gehören dem Compiler.
    Namen die 2 Unterstriche beinhalten, gehören dem Compiler.

    es empfiehlt sich zB folgendes zu nehmen:
    #ifndef LIBNAME_HEADERNAME_INCLUDED
    #define LIBNAME_HEADERNAME_INCLUDED



  • So müsste das dann richtig aussehen

    #ifndefine _MAMAKROS_
    #define MAX(a,b) ((a)>=(b)?(a):(b))
    #define MIN(a,b) ((a)<=(b)?(a):(b))
    #endif
    

    und eine wichtige frage, die ich vergessen hatte:
    Shade Of Mine du hast es ja bereis angesprochen mit dem PI.
    Was ist denn genau der unterschied zwischen const und #define. Ist #define bloss für so "Formeln" und const einfach für konstante Werte? Außerdem dachte ich bei const müsste man keine datentypen anhängen, oder ist das auch der Grund warum ich die "1" als float deklarieren muss?

    //Variablen
    	int endwert;
    	double ergebnis=0;
    
    	cout<<"Geben Sie den Endwert fuer die harmonische Reihe ein: ";
    	cin>>endwert;
    
    	for(int i=1;i<=endwert;i++)
    	{
    		ergebnis+=(float)1/i;
    		cout<<"1/"<<i<<" ";
    	}
    
    	cout<<"\n= "<<ergebnis<<endl;
    


  • FUNPAQ schrieb:

    Shade Of Mine du hast es ja bereis angesprochen mit dem PI.
    Was ist denn genau der unterschied zwischen const und #define. Ist #define bloss für so "Formeln" und const einfach für konstante Werte? Außerdem dachte ich bei const müsste man keine datentypen anhängen, oder ist das auch der Grund warum ich die "1" als float deklarieren muss?

    #define ist eine Textersetzung.

    Wenn du

    #define x foo
    int main()
    {
      int x;
    }
    

    dann bekommt der compiler folgenden code

    int main()
    {
      int foo;
    }
    

    also reine textersetzung.

    bei
    #define MAX(a,b) ((a)>=(b)?(a):(b))
    wird
    MAX(1,2)
    einfach durch
    ((1)>=(2)?(1):(2))
    ersetzt.

    deshalb empfiehlt sich hier ja eine template funktion (sofern wir von c++ reden - in C muss man das #define verwenden)

    template<typename T>
    inline T max(T a, T b)
    {
      return a>b?a:b;
    }
    

    bei const wird einfach eine variable angelegt, deren wert nicht geändert werden kann.

    in C (vor C99) gibt es ein implizites int.
    dh:
    const i=3;
    wird als
    int const i=3;
    gelesen.

    deshalb war damals auch

    main()
    {
      return 0;
    }
    

    vollkommen legal.

    dein problem bei
    1/i
    ist folgendes:
    1 ist ein int
    i ist ein int
    und wenn du int durch int dividierst, kommt ein int heraus
    sprich: er schneidet brutal die nachkommastellen ab.

    bei int und float, ist das ergebnis ein float (also immer der Typ, der 'größer' ist)

    eine elegante Lösung für dich wäre

    1.0f / i

    1.0 ist ein double -> durch das f wird es zu einem float
    folglich wird float durch int dividiert und das ergebnis ist ein float 🙂



  • FUNPAQ schrieb:

    So müsste das dann richtig aussehen

    #ifndefine _MAMAKROS_
    #define MAX(a,b) ((a)>=(b)?(a):(b))
    #define MIN(a,b) ((a)<=(b)?(a):(b))
    #endif
    

    Da hast du mich falsch verstanden. Richtig heißt es "#ifndef". Ich hab "if not defined" nur in meinen Kommentar geschrieben, damit du weißt woher es kommt. Dann kann man es sich leichter merken.



  • thx, dann habe ich es jetzt verstanden 😃

    CME386 schrieb:

    Da hast du mich falsch verstanden. Richtig heißt es "#ifndef". Ich hab "if not defined" nur in meinen Kommentar geschrieben, damit du weißt woher es kommt. Dann kann man es sich leichter merken.

    Sorry, das war nur ein kleiner Rechtschreibfehler.


Anmelden zum Antworten