Header Dateien ... wie nutzen ?



  • Hallo,
    ich habe ein kleines Problem mit einem Programm was wir schreiben sollen, mal wieder ... Ja ich habe schon gegoogled und zig Seiten gelesen und mir Header Dateien angeschaut ( math.h , stdio.h etc. ) ich verstehe aber immer noch den Sinn dahinter nicht . Warum soll ich eine Header Datei haben, wenn ich die Schleifen und Berechnungen eh nicht dort einbringe ? Wenn ich mir math.h anschaue, dort sehe ich keine einzige Schleife etc. nur

    double sin(double d) __THROW __attribute__((__const__));
    

    sowas, wo wird denn dann gerechnet ?

    Unser Prof. hat uns folgende Aufgabe gestellt, wir sollen diese 3 Dateien nutzen und am Ende sollen wir addieren, subtrahieren etc. pp. ... wie man dort ja sieht. Aber muss ich die Funktionen nicht sowieso noch in die Main packen ??

    Oh grad noch einen Hinweis gesehen aus der VL, wir sollen eine .c File schreiben mit dem Namen rational.c. Packe ich in die dann alle Funktionen rein ?

    Und laut dem Artikel ist das benutzen von extern in Funktionen sowieso redundant...

    http://www.geeksforgeeks.org/archives/840

    /****************************************************************************************/
    /* rational.h                                                                           */
    /****************************************************************************************/
    
    #ifndef _rational
    #define _rational
    
    #include "globals.h"
    
    typedef struct rational { int numerator ; int denominator ; } rational ;
    
    extern rational load_rational( int numerator, int denominator ) ;
    
    extern void retrieve( rational rational1, int *numerator, int *denominator   ) ;
    
    extern rational add_rational( rational rational1, rational rational2 ) ;
    
    extern rational multiply_rational( rational rational1, rational rational2) ;
    
    extern rational subtract_rational( rational rational1, rational rational2 ) ;
    
    extern bool equal_rational ( rational rational1 , rational rational2 ) ;
    
    extern rational  divide_rational( rational rational1, rational rational2 ) ;
    
    extern void print_rational( rational rational1 ) ;
    
    #endif
    
    /********************************************************************/
    /* globals.h                                                        */
    /*                                                                  */
    /* status           see page 41 in Esakov                           */
    /* bool             see page 41 in Esakov                           */
    /********************************************************************/
    
    #ifndef _globals
    #define _globals
    
    typedef enum { OK, ERROR } status ;
    typedef enum { FALSE=0 , TRUE=1 } bool ;
    
    #endif
    
    /*******************************************************************************/
    /* Programmer:     Jim Canning                                                 */
    /*                                                                             */
    /* Main driver to test rational number module.                                 */
    /*******************************************************************************/
    
    #include <stdio.h>
    #include "globals.h"
    #include "rational.h"
    
    int main( int argc, char *argv[] ) {
    
      rational rational1, rational2, rational3 ;
      int n, d ;
    
      printf( "Rational1: Please enter two integer values:  " ) ;
      scanf("%d", &n) ;  scanf("%d", &d ) ;
    
      rational1 = load_rational( n , d ) ;
    
      printf("\nThe rational number is " );  print_rational( rational1 ) ;
      printf("\n");
    
      printf( "Rational2: Please enter two integer values:  " ) ;
      scanf("%d", &n) ;   scanf("%d", &d ) ;
    
      rational2 = load_rational( n, d ) ;
    
      printf("\nThe rational number is " ); print_rational( rational2 ) ;
      printf("\n");
    
      rational3 = add_rational( rational1, rational2 ) ;
    
      printf("The addition of the two rational numbers is ");   print_rational( rational3 ) ;
      printf("\n") ;
    
      rational3 = subtract_rational( rational1, rational2 ) ;
    
      printf("The subtraction of the two rational numbers is ");  print_rational( rational3 ) ;
      printf("\n") ;
    
      rational3 = multiply_rational( rational1, rational2 ) ;
    
      printf( "The multiplication of the two rational numbers is " );  print_rational( rational3 ) ;
      printf("\n") ;
    
      rational3 = divide_rational(rational1, rational2 ) ;
    
      printf( "The division of the two rational numbers is " );  print_rational( rational3 ) ;
      printf("\n") ;
    
      if ( equal_rational( rational1, rational2 ) )  printf("\nThey are two equal rational numbers.\n");
    
      else printf("\nThe are not equal.\n") ;
    
      return 0 ;
    
    }
    


  • Header-Dateien enthalten keinen Code, sondern nur Definitionen für Typen, Funktionen, und ähnliches - also keine Anweisungen wie Schleifen.
    Der Sinn besteht darin:
    - Einbindung der Deklarationen und Prototypen fremder Libraries und DLLs, z.B. Standardfunktionen.
    - Bereitstellung der Deklarationen und Prototypen eigenen Programmcodes, wenn das Projekt auf mehrere Dateien verteilt wird.
    Verstehe die Header-Dateien als simple Textergänzung für das allernotwendigste. C hat schliesslich Prototypenpflicht! Es wird stets - sonst nötige - Schreibarbeit gespart. Bei einem kleinen Programm mit einer Main und vielleicht einer eigenen Funktion in einer Sourcedatei magst du den Sinn noch nicht voll erkennen. Das ändert sich aber schnell, sobald dein Projekt etwas umfangreicher wird.



  • math.h sagt deinem Compiler lediglich dass es die funktion sin gibt. Dem Compiler ist auch egal was die macht ihn interessiert nur wie sich aufgerufen wird und was sie zurück gibt.

    Die eigentlich sin funktion ist in der C Runtime lib drin. Der Linker fügt dass dann so zusammen, dass tatsächlich dass dan aufgerufen wird.

    Google mal nach compilen und linken. Der Unterschied ist vorallem bei Einsteigern nicht ganz klar zumal die meisten compiler einen linker direkt mitbringen und standardmäßig auch direkt nachdem dem compilen linken. Also bekommst du davon gar nichts mit. Aber zum verständnis ist es ganz geschickt wenn du dir das mal anguckst.

    Auch:

    Wenn jemand jetzt einen fehler in der sin funktion aus der math.h findet wäre es doch ärgerlich wenn man plötzlich alle programme, die die alte math.h benutzt haben neu kompilieren müsste. Da genügts einfach wenn man die C Runtime bibliothek neuinstalliert (sofern man sie dynamisch gelinkt hat).



  • Okay, das habe ich nun endlich verstanden verstanden. Definieren und Deklarieren musste ich mir nochmal durch den Kopf gehen lassen...

    Den Sinn bei so einem kleinen Programm kann ich zwar nicht verstehen, aber vielleicht kommt das spaeter , haha.

    #include <stdio.h>
    #include "globals.h"
    #include "rational.h"
    
    rational load_rational ( int num , int den ) {
    
    num =  rational.numerator;
    den = rational.denominator
    
    }
    
    void print_rational ( rational rat ){
    
    printf ("Your first rational number is: %d  /  %d", rat.numerator, rat.denominator);\
    
    }
    

    Habe heute mal angefangen zu schreiben, ich weiss das ist noch nichts, aber ich habe schon meine ersten Probleme. Wie vorgegeben sollen wir eine Funktion schreiben die die Rationalen Zahlen laedt. Da es sich um ein struct handelt habe ich gedacht ich fuelle es einfach mit X = structname.variable , aber das scheint nicht zu funktionieren . Ich bekomme immer die Fehlermeldung "expected expression before rational " , woran liegt das ?



  • Hab das jetzt versucht zu loesen, aber das Ergebniss spinnt ... mein Numerator ist mein Denominator aus irgendeinem Grund...

    #include <stdio.h>
    #include "globals.h"
    #include "rational.h"
    
    rational load_rational ( int num , int den ) {
    
    rational buffer;
    
    buffer.numerator = num;
    buffer.denominator = den;
    
    return buffer;
    
    }
    
    void print_rational ( rational rat ){
    
    printf (" %d  /  %d", rat.numerator, rat.denominator);\
    
    }
    

    Was ich im Allgemeinen nicht verstehe ist, wie soll ich ein Struct fuellen was ich in main.c definiert habe, wenn ich es nicht an meine Funktion uebergebe ?



  • In C kannst du Strukturvariablen nicht nur als Parameter übergeben, sondern auch als Rückgabewert nutzen, und das nutzt du im deinem Programm aus.
    Den Rückgabewert beim Funktionsaufruf weist du sofort der betreffenden Variable im aufrufenden Kontext zu und fertig.

    rational r = {1,1};
    print_rational( r );
    r = load_rational(2,2); /* hier passiert das o.g., also die Strukturinhaltskopie */
    print_rational( r );
    


  • Ja gut, das habe ich doch oben so gemacht, indem ich wie in main.c steht n und d uebergebe. Und dort dann mit load und print rational nutze. Aber warum ist mein denominator mein numerator ?

    Wenn ich es ausfuehre und drucke ( printf ) , steht dort anstatt eingelesen 5 und 6 zum Beispiel 6 / 5 ...



  • Schreibfehler.

    Zeig deinen Code.



  • DirkB schrieb:

    Schreibfehler.

    Zeig deinen Code.

    #include <stdio.h>
    #include "globals.h"
    #include "rational.h"
    
    rational load_rational ( int num , int den ) {
    
    rational buffer;
    
    buffer.numerator = num;
    buffer.denominator = den;
    
    }
    
    void print_rational ( rational rat ){
    
    printf (" %d   %d", rat.denominator, rat.numerator);
    
    }
    
    rational add_rational( rational rational1, rational rational2 ){
    
    rational buffer;
    
    if ( rational1.denominator == rational2.denominator ){
    
    	buffer.denominator = rational1.denominator;
    	buffer.numerator = rational1.numerator + rational2.numerator;
    	}
    
    }
    

    add_rational kann ignoriert werden , bringt ja nix wenn ich nicht die richtigen den und num Werte bekomme, bzw. diese getauscht werden 😞



  • Dann schau dir noch mal genau Zeile 20 an.



  • Ohhhh nein nein, das habe ich geandert damit dann endlich das richtige Ergebniss steht. Wenn ich es richtig schreibe rat.num..... / rat.den..... , steht es umgekehrt dort.

    Sorry fuer die Verwirrung, ich dachte ich aender es einfach und dann am Ende kommt das richtige raus, aber der "Grader" guckt sich nicht nur den Output an sondern auch den Code 😕

    http://s1.directupload.net/images/111113/mjqkla2w.jpg



  • Dann bitte den kürzesten vollständigen Code in dem der Fehler auftaucht.
    In deinem Beispiel wird print_rational noch nicht mal aufgerufen.

    Den kürzesten und vollständigen Code in dem der Fehler auftaucht.
    Kein "Ich habe gedacht das ist nicht wichtig" und kein "... kann ignoriert werden".
    Wenn es nichts mit dem Fehler zu tun hat, schmeiß es raus. Und compilier es auch.



  • DirkB schrieb:

    Dann bitte den kürzesten vollständigen Code in dem der Fehler auftaucht.
    In deinem Beispiel wird print_rational noch nicht mal aufgerufen.

    Den kürzesten und vollständigen Code in dem der Fehler auftaucht.
    Kein "Ich habe gedacht das ist nicht wichtig" und kein "... kann ignoriert werden".
    Wenn es nichts mit dem Fehler zu tun hat, schmeiß es raus. Und compilier es auch.

    #include <stdio.h>
    #include "globals.h"
    #include "rational.h"
    #include "rational.c"
    
    int main( int argc, char *argv[] ) {
    
      rational rational1, rational2, rational3 ;
      int n, d ;
    
      printf( "Rational1: Please enter two integer values:  " ) ;
      scanf("%d", &n) ;  scanf("%d", &d );
    
      rational1 = load_rational( n , d ) ;
    
      printf("\nThe rational number is " );  print_rational( rational1 ) ;
      printf("\n");
    
      printf( "Rational2: Please enter two integer values:  " ) ;
      scanf("%d", &n) ;   scanf("%d", &d ) ;
    
      rational2 = load_rational( n, d ) ;
    
      printf("\nThe rational number is " ); print_rational( rational2 ) ;
      printf("\n");
    
    }
    
    #include <stdio.h>
    #include "globals.h"
    #include "rational.h"
    
    rational load_rational ( int num , int den ) {
    
    rational buffer;
    
    buffer.numerator = num;
    buffer.denominator = den;
    
    }
    
    void print_rational ( rational rat ){
    
    printf (" %d   %d", rat.numerator, rat.denominator);
    
    }
    


  • Gibt es auch ein return buffer; in load_rational()



  • Jap gab/gibt es. Aendert aber nichts an der Situation leider 😕

    Okay, gefixt. Weiss nicht woran es lag, aber jetzt funkt es 😃

    #include <stdio.h>
    #include "globals.h"
    #include "rational.h"
    
    rational load_rational ( int num , int den ) {
    
    rational buffer;
    
    buffer.numerator = num;
    buffer.denominator = den;
    
    return buffer;
    
    }
    
    void print_rational ( rational rat ){
    
    printf (" %d   %d", rat.numerator, rat.denominator);
    
    }
    
    rational add_rational( rational rational1, rational rational2 ){
    
    rational buffer;
    
    if (rational1.denominator == rational2.denominator){
    
    	buffer.denominator = rational1.denominator;
    	buffer.numerator = rational1.numerator + rational2.numerator;
    }
    
    	else{
    		buffer.denominator = rational1.denominator * rational2.denominator;
    
    		buffer.numerator = ( rational1.numerator * rational2.denominator ) + ( rational2.numerator * rational1.denominator);
    	}
    
    return buffer;
    
    }
    


  • Arbeite an deinem Einrückungsstil
    z.B.:

    rational add_rational( rational rational1, rational rational2 ) {
    
      rational buffer;
    
      if (rational1.denominator == rational2.denominator) {
        buffer.denominator = rational1.denominator;
        buffer.numerator = rational1.numerator + rational2.numerator;
      }
      else {
        buffer.denominator = rational1.denominator * rational2.denominator;
        buffer.numerator = ( rational1.numerator * rational2.denominator ) + ( rational2.numerator * rational1.denominator);
      }
    
      return buffer;
    }
    

    da kann man viel besser den Programmfluß erkennen.
    Das wird dior und auch deinem "Grader" helfen.



  • DirkB schrieb:

    Arbeite an deinem Einrückungsstil
    z.B.:

    rational add_rational( rational rational1, rational rational2 ) {
    
      rational buffer;
    
      if (rational1.denominator == rational2.denominator) {
        buffer.denominator = rational1.denominator;
        buffer.numerator = rational1.numerator + rational2.numerator;
      }
      else {
        buffer.denominator = rational1.denominator * rational2.denominator;
        buffer.numerator = ( rational1.numerator * rational2.denominator ) + ( rational2.numerator * rational1.denominator);
      }
    
      return buffer;
    }
    

    da kann man viel besser den Programmfluß erkennen.
    Das wird dior und auch deinem "Grader" helfen.

    Okay, vielen Dank 🙂



  • Ich habe meine letzte Funktion gereda geschrieben.

    bool equal_rational( rational rational1, rational rational2 ) {
    
    	bool buffer;
    
    	if( rational1.numerator == rational2.numerator ) {
    
    	     if ( rational1.denominator * rational2.denominator){
    
    	     buffer = 1;
    
    	     }
    
    	}
    
    	else buffer = 0;
    
    	return buffer;
    }
    

    aufgerufen wird sie durch main und zwar ...

    if ( equal_rational( rational1, rational2 ) )  printf("\nThey are two equal rational numbers.\n");
    
      else printf("\nThe are not equal.\n") ;
    

    Leider gibt es mir aus das 5 / 5 und 5 / 5 ungleich sind und umgekehrt, was mache ich hire falsch ? Habe auch extra noch stdbol.h eingefuegt 😕


Anmelden zum Antworten