1. Dashboard
  2. Forum
    1. Unerledigte Themen
  3. Mitglieder
    1. Letzte Aktivitäten
    2. Benutzer online
    3. Team-Mitglieder
    4. Trophäen
    5. Mitgliedersuche
  4. Tutorial Bereich
  • Anmelden
  • Registrieren
  • Suche
Alles
  • Alles
  • Seiten
  • Forum
  • Lexikon
  • Erweiterte Suche
  1. Informatik Forum
  2. Mitglieder
  3. Vevusio

Beiträge von Vevusio

  • c++ variable in 2 Klassen aktualisieren

    • Vevusio
    • 17. November 2006 um 18:36

    also so wie ich das verstehe

    du hast eine klasse mit einer variabel und du hast 2 weitere klassen die diese variable verändern

    du möchtest wenn sich die variable in einer der 2 klassen verändert sie sich auch in der anderen ändert

    hier mal ein kleines beispiel wie man es machen kann, die erklärung dazu schreibe ich darunter

    C
    //classes.h
    #ifndef CLASSES_H
    #define CLASSES_H
    
    
    #include <iostream>
    using std::cout;
    
    
    class Manager
    {
        //Variables
    private:
        int m_detector;
    
    
        //Get & Set
    public:
        int GetDetector()
        {
            return m_detector;
        }
    
    
        //Constructors & Destructors
    public:
        Manager()
        {
            m_detector = 0;
        }
        ~Manager()
        {
        }
    
    
        //Methods
    public:
        void AssociateDetector(int** p2DetectorAssociation)
        {
            *p2DetectorAssociation = &m_detector;
        }
    };
    
    
    /*abstract*/ class Visualizer
    {
        //Constructors & Destructors
    public:
        Visualizer()=0;
    
    
            //Methods
    public:
        static void Visualize(int value)
        {
            cout << "Integer value: " << value << std::endl;
        }
    };
    
    
    class ProcessorA
    {
        //Variables
    private:
        int* m_pDetector;
    
    
        //Get & Set
    public:
        void SetPDetector(int* pDetector)
        {
            m_pDetector = pDetector;
        }
    
    
        //Constructors & Destructors
    public:
        ProcessorA()
        {
            m_pDetector = NULL;
        }
        ~ProcessorA()
        {
        }
    
    
        //Methods
    public:
        void ChangeValue(int newValue)
        {
            *m_pDetector = newValue * newValue;
        }
    };
    
    
    class ProcessorB
    {
        //Variables
    private:
        int* m_pDetector;
    
    
        //Get & Set
    public:
        void SetPDetector(int* pDetector)
        {
            m_pDetector = pDetector;
        }
    
    
        //Constructors & Destructors
    public:
        ProcessorB()
        {
            m_pDetector = NULL;
        }
        ~ProcessorB()
        {
        }
    
    
        //Methods
    public:
        void ChangeValue(int newValue)
        {
            *m_pDetector = newValue + newValue;
        }
    };
    
    
    #endif
    
    
    ////////////////////////////////////////////////////////////////////////////
    //main.cpp
    #include "classes.h"
    
    
    void main()
    {
        int** detector = new int*;
        Manager manager;
        ProcessorA processorA;
        ProcessorB processorB;
    
    
        manager.AssociateDetector(detector);
        processorA.SetPDetector(*detector);
        processorB.SetPDetector(*detector);
    
        processorA.ChangeValue(5);
        Visualizer::Visualize(manager.GetDetector());
    }
    Alles anzeigen


    erstmals, wegen der übersicht hab ich nicht jede klasse in eine h und cpp datei unterteilt und nichtmal die implementierung von der deklarierung getrennt sondern alle funktionen sind gleich in den methodendeklarationen der klassen auch definiert, aber das spielt jetzt keine rolle

    anstatt die klassen ABC.. zu nennen hab ich es halt logisch gemacht dass deine A klasse Manager heißt, da sie die variable detector enthält

    dann gibt es B und C welche durch ProcessorA und ProcessorB repräsentiert werden und deine klasse D habe ich als eine abstrakte klasse Visualizer implementiert, bevor ich mit der erklärung anfange, ich schätze das wird schon so verwirrend genug für dich sein, also habe ich auf die verwendung von referenzen verzichtet und nur pointer benutzt, was referenzen sind hat man eh sofort kapiert wenn man das pointer konzept mal richtig begriffen hat also würden sie jetzt nur alles komplizierter machen

    das ganze sieht jetzt so aus, die Manager klasse hat einfach eine int variable

    ich weiß nicht ob du überhaupt schon mit pointern vertraut bist also versuche ich es von 0 weg zu erklären

    wenn ich

    Code
    int x;


    schreibe erstelle ich eine variable x vom typ integer, verändere ich x zb mit x = 4 dann nimmt x den wert 4 an, klar

    ein pointer ist wie der name schon sagt nichts anderes als ein zeiger auf eine variable, ein pointer wird mit * gekennzeichnet

    es kommen zwei neue operatoren hinzu wenn man mit pointern arbeitet und zwar * und &

    wobei * der dereferenzierungsoperator ist und & (ich hab ehrlich gesagt ka wie der operator heißt) operator holt dir die adresse/referenz/pointer von einer variable

    also

    Code
    //ich erstelle einen integer x
    int x = 5;
    //ich erstelle ein pointer auf einen integer
    int* pointerToX;
    
    
    //da der pointer die adresse auf einen integer enthält hole ich mir mit &
    //die adresse auf x und weise sie pointerToX zu
    pointerToX = &x;
    
    
    //das würde mir die adresse von x ausgeben also irgend so
    //ne zahl wie 6362732
    cout << pointerToX;
    
    
    //wenn ich aber den wert von x will muss ich den pointer dereferenzieren
    //das gibt mir jetzt den wert 5 aus
    cout << *pointerToX;
    Alles anzeigen


    diese pointer sind deswegen da weil wenn ich einen pointerToX1 habe und einen pointerToX2 und beide zeigen auf x und ich x ändere (entweder über x = 4; oder über *pointerToX1 = 4; oder *pointerToX2 = 4) dann naja.. ändere ich halt x und weil die beiden pointer auf x zeigen ändert sie sich demnach für beide pointer

    und so machen wir das

    die manager klasse hat ne detector variable, processora und processorb haben jeweils einen pointer auf die detector variable der manager klasse

    alles was jetzt noch zu tun ist, ist den beiden pointern die adresse der detector variable zuzuteilen, weil data encapsulation ein grundprinzip der oop ist das nicht verletzt werden sollte machen wir die variablen also nicht public sondern erstellen get und set methoden und das ganze läuft jetzt so ab

    die manager klasse hat eine associate funktion die einen pointer auf einen pointer bekommt... also ein zeiger auf einen zeiger auf einen integer (ich schreibe pointer im code immer mit einem p davor, ein pointer auf einen pointer mit p2, pointer auf pointer auf pointer mit p3 usw...)
    dieser pointer auf den pointer auf den integer wird dereferenziert

    also wenn wir int** dereferenzieren bekommen wir ein int* und diesem int* weisen wir jetzt die adresse von detector zu über &detector

    aber wieso zur hölle wird ein int** übergeben? die antwort darauf ist: damit ich den pointer verändern kann.... wenn ich blos einen int* übergeben würde als parameter, wir erinnern uns ein parameter wird als value type übergeben und somit das objekt kopiert, und dann weise ich int* etwas zu dann hätte ich blos die kopie des parameters geändert

    so ähnlich als wenn ich habe

    int x;

    fkt(int x)
    x = 4;

    und ich rufe fkt auf und gebe nach dem aufruf x aus dann ist es nicht 4, weil in der funktion eine kopie von x angefertigt wurde lediglich

    wenn ich also x verändern will müsste ich einen pointer auf x übergeben und den dereferenzierten wert von x ändern dann wäre x auch nach dem funktionsaufruf 4

    int x;

    fkt(int* x)
    *x = 4;

    genauso ist es mit pointern, wenn ich den pointer selbst ändern will muss ich einen pointer auf den intpointer übergeben und diesen dereferenzieren und den intpointer ändern... naja das muss man mal verdauen um es zu verstehen

    jedenfalls erstellen wir in der main einen int** detector, assoziieren den intpointer über die associate methode der manager klasse und dann weisen wir den pointer processora und processorb zu

    das war auch die ganze zauberei dahinter (als wenn das nicht genug wäre *g*).. jedenfalls wenn jetzt detector entweder in manager oder processorA oder processorB geändert wird wird er halt überall geändert

    und ja.. diese visualisierungsklasse hat einfach eine statische methode um ihn auszugeben und nur die manager klasse hat eine get funktion für detector, aber natürlich kannst du detector jetzt einfach in processora oder processorb verwenden, du musst ihn nur einmal dereferenzieren so wie in der changevalue methode

    *m_pDetector = newValue * newValue;

    das ist genauso wie mit dem *x = 4;.. am ja und.. lass dich jetzt nicht von dem * zwischen den newValues verwirren :) das ist einfach nur ein mal zeichen, processorA tut bei change value das quadrat von der überegeben zahl detector zuweisen und processorb 2 * die übergeben zahl

  • Thermometer -.-

    • Vevusio
    • 16. November 2006 um 23:16

    hm... hör ich zum ersten mal, ich habs grad getestet und unter c# geht das garnicht mehr, man bekommt eine invalid term exception wenn man das komma so verwendet, würde mich auch überraschen wenn es das in java gibt

    da mir die verwendung von dem auch nie untergekommen ist in irgend einem beispielprogramm oder so nehm ich mal an dass das ding sich irgendwo in der goto grauzone bewegt und sowieso nicht verwendet werden soll

  • größter gemeinsamer teiler

    • Vevusio
    • 16. November 2006 um 22:32

    achja genau, 2 sachen noch

    1)

    int a, b, erg; <- man sollte keine globalen variablen verwenden, wenn man mehr als eine cpp file hat sind die dann unbekannt in den anderen files, man muss sich mit extern herumplagen, und es verursacht alles in allem nur probleme, wenn schon würde ich wenn ich unbedingt globale variablen in einem größeren projekt brauche eine abstrakte klasse erstellen und die variablen + helferfunktionen static machen aber so ist es jedenfalls schlecht

    2)

    Code
    int ggt(int a, int b);
    
    
    int ggt (int a, int b){
    ...
    }

    wenn du die funktion schon vor der main definierst dann brauchst du nicht zuerst eine deklaration und dann die definition zu schreiben sondern du kannst es gleich in einem machen also blos

    Code
    int ggt (int a, int b){
     ...
     }

    diese unterteilung in definition - deklaration macht man wenn man die funktionen in .h files deklariert und sie in cpp files definiert bzw vor der main in der cpp deklariert und nach der main definiert (wenn man kleine programme hat die nur aus ein paar funktionen bestehen)

  • Thermometer -.-

    • Vevusio
    • 16. November 2006 um 22:24

    hm.. wieso spuckt der compiler bei
    Label1->Caption=IntToStr(TrackBar1->Max),(TrackBar1->Position=TrackBar1->Min);


    denn keinen fehler aus?
    das ist syntaktisch doch falsch oder?!


    bzw lässt sich so nicht einfach sagen wieso der regler sich nicht verschieben lässt, das kommt auf die GUI an in der du das programmierst, schau dir doch einfach ein paar tutorials an die du bei google raussuchst, zu MFC beispielsweise gibts da hunderte davon wo alles gut erklärt ist

    wenn du eigentlich nicht weißt was du da für code schreibst ist es überhaupt keine so tolle idee zu versuchen fenster, regler und all das zeug einzubinden weil du nichts dabei lernst wenn du nicht die gedankengänge dahinter verstehst, dass ein regler attribute hat und funktionen die die pos ändern etc etc

  • größter gemeinsamer teiler

    • Vevusio
    • 16. November 2006 um 22:09

    das b wird einfach als parameter übergeben... mehr ist das nicht und mehr macht es auch nicht

    die funktion selbst ist rekursiv, ruft sich also selbst immer wieder auf, wieso man auf die art den größten gemeinsamen teiler ermitteln kann musst du dir halt überlegen oder auf dem geposteten link durchlesen, aber wenn dich deine neugier nicht gerade umbringt.... würd ich das einfach so hinnehmen da rekursion wenn man mit programmieren anfängt erstmal nicht so wichtig ist, man kann es einfach mal hinnehmen "aha ja die funktion ruft sich selbst auf, das ist rekursion"

  • Stack

    • Vevusio
    • 10. November 2006 um 21:34

    du musst um stack zu benutzen java.util.Stack; oder sowas importieren

  • PrologExperten?

    • Vevusio
    • 8. November 2006 um 22:35

    ja und was ist dabei die frage bzw die aufgabenstellung?

    bzw verstehe ich nicht was bei sum() das % Use the built-in relation plus(X,Y,Z), e.g. plus(1,2,3).

    bedeuten soll, soll zu dem ersten element der liste L x, zu dem zweiten y, zu dem dritten Z addiert werden oder sollen die elemente x, y, z hinten angehängt werden an die liste oder wie

  • Hashing

    • Vevusio
    • 7. November 2006 um 12:09
    Zitat von Wings-of-Glory


    ein hash-wert ist nicht eindeutig, sondern mehrdeutig. es gibt mehrere inputs, die sich auf ein und denselben hash-wert abbilden lassen. daher kann man einen string, ein file oder einen anderen input nicht an seinem hash-wert identifizieren.

    hash-werte können dazu genutzt werden die suche nach werten zu beschleunigen, oder datenübertragungsfehler aufzuspüren oder passwörter mehr oder weniger sicher abzuspeichern.

    äh.. ist nicht genau das der punkt bei hashes, dass es keine 2 inputs gibt die denselben hash ergeben, das ist ja der sinn davon

    "daher kann man einen string etc nicht an seinem hash wert identifizieren" und nen absatz darauf steht da dass passwörter so sicher abgespeichert werden können

    wozu sollte ich ein passwort als hash abspeichern wenn ich
    a) ein zweites passwort oder mehrere passwörter hätte die denselben hash ergeben
    b) ich das referenzpasswort nicht identifizieren könnte am hash

    drum geht es doch überhaupt zb beim CHAP protokoll, der server hat die passworter abgespeichert, er schickt mir ne challenge die ich zum hashen meines pws verwende, verschicke das gehashte pw und der server hasht das pw was er in der datenbank hat ebenfalls mit der challenge und vergleich die hashes
    wenn jemand die challenge und den hash mitgesnifft haben sollte nützt ihm das nix weil er den hash nicht rückgängig machen kann

    also inwiefern kann man eine datenmenge nicht am hash identifizieren? man hasht sie einfach nochmal und vergleicht die 2 hashes und hat sie identifiziert, man muss nur wissen mit welchem hash algorithmus

    ---

    ich verstehe nicht wieso man an der normalen uni c++ macht und an der tu java.. was ist da der hintergrundgedanke dabei wenn es sowieso derselbe stoff ist ca?

  • Hashing

    • Vevusio
    • 7. November 2006 um 02:16

    hallo, ich hab mal das erste beispiel gemacht in c++.. oder eigentlich c... naja c ist es aber nicht weil die std verwendet wird und das ist c++ aber egal..

    jedenfalls hab ich keine klassen gemacht oder so sondern nur funktionen und alles in eine .cpp datei reingetan auch ohne .h dateien weil ich nicht wiess wie weit ihr seit

    das ganze ist überfüllt mit kommtentaren die wirklich fast jeden mist erklären sollten

    ka allerdings wie das zweite beispiel gehen soll weil ich ka hab was dieses siebdings sein soll und auch keine lust, aber

    wenn ihr rausfinden wollt ob eine zahl eine primzahl ist geht das eigentlich ganz einfach so, vielleicht ist das ja eh gemeint

    also irgendwas in die richtig

    Code
    for(int i=0; i<n; i++)
    {
           bool primZahl = true;
    
    
           for(int j=2; j<zahl; j++)
           {
              if(zahl % j == 0)
             {
                 primZahl = false;
                 break;
             }
         }
         if(primZahl == true)
         {
              cout << "Primzahl: " << i << "\n";
         }
         else
         {
              cout << "Keine Primzahl: " << i << "\n";
         }
     }
    Alles anzeigen


    irgendwie so müsste das gehen, falls ihr es nicht versteht dann lest euch beispiel #1 durch danach sollte das klar sein

    Code
    #include <iostream>
      #include <windows.h>
      #include <math.h>
    
      //wir verwenden cout und cin für ein und ausgabe, das sind 2 funktionen in der std
      //was eine standardbibliothek mit klassen und funktionen ist für c++, damit wir
      //wenn wir schreiben dass wir std::cout verwenden können wir einfach etwas mit
      //cout << "text"; ausgeben im programm, ansonstne müssten wir immer dem compiler
      //sagen dass cout in der std ist und über std::cout << "text"; was ausgeben
      using std::cout;
      using std::cin;
    
      //bevor wir irgendwas machen werden wir mal 3 funktionen deklarieren
      //die benutzt werden um den druchschnitt, median und stdabweichung
      //auszurechnen, sie geben alle einen float, also gleitkommazahl zurück
      //die eben den zb bei der median fkt den median zurückliefert und alle 3
      //bekommen erstmal das array mit den zahlen mit und dann einen integer
      //der angibt wie viele zahlen in dem array stehen die uns interessieren
      //die funktionen werden hier erstmal nur deklarieren, wir sagen dem compiler also
      //hey es gibt sie, damit er nicht verwirrt ist wenn er sie in der main() findet,
      //was drinsteht, also die definition machen wir erst nach der main(), wir könnten
      //sie aber auch gleich jetzt definieren.... ist egal
      //oh ja, und wir wollen auch nicht dass die funktionen unsere paramter verpfuschen
      //indem sie die werte ändern da wir sie ja nach dem aufruf von average noch für median
      //usw brauchen also sagen wir dass die parameter const also konstant sind, sie können
      //also nicht verändert werden, so, was das soll? wir schreiben die funktionen ja selber
      //und wenn wir die parameter nicht verändern wollen dann machen wir es nicht wozu also
      //so ein const davorschreiben... tja.. so ne programmiereigenart, ich machs eigentich nie
      //aber hier mal um das konzept zu zeigen, man sollte es machen, oh und noch etwas
      //funktionsnamen bitte immer mit großem anfangsbuchstaben und variablennamen mit kleinem
      //anfangsbuchstaben, ich tu immer ein kleines a am anfang bei funktionsparametern hin was
      //für attribute steht, also aDasIstEinParameter, und da sieht man gleich noch ne stildings
      //keinsolchenvariablenoderfunktionsnamenschreiben wenn dann SolcheFunktionsNamenZumBeispiel
      //oder dasIstEineVariablenName variablennamen -.-
      float Average(const int aNumbers[], const int aNumbersToProcess);
      float Median(const int aNumbers[], const int aNumbersToProcess);
      float Deviation(const int aNumbers[], const int aNumbersToProcess);
    
      void main()
      {
          //erstmal brauchen wir ein array das 50 zahlen halten kann
          //wir erstellen dafür zuerst mal ne variable der wir sagen
          //wie groß unser array wird, wenn wir die größe nämlich auf
          //60 ändern möchten müssen wir nicht überall im ganzen programm
          //50 auf 60 ändern sondern nur einmal die zuweisung von numbersLength
          //die länge bleibt auch immer gleich also ist es eine const variable
          //einmal zugewiesen behält sie immer denselben wert
          const int numbersLength = 50;
    
          //jetzt erstellen wir ein int array mit der größe von numbersLength
          //nachdem wir das array erstellt haben steht in jedem element 0 drin
          //das ist bei c++ default mäßig so bei "normalen" variablen wie int
          int numbers[numbersLength];
    
          //und alles was zu tun bleibt ist zahlen einzulesen, falls ihr nicht
          //mit for schleifen vertraut seit, die schleife setzt eine variable i
          //und weist ihr ganz am anfang 0 zu, wie in einer while schleife wird
          //zuerst geschaut ob die bedingung stimmt und nachdem die schleife einmal
          //durchlaufen wurde wird i++ ausgeführt, also i um 1 erhöht, im prinzip
          //ist es eine kurzschreibweise für
          /*
          int i=0;
          while(i < numbersLength)
          {
              //TODO
    
              i = i + 1;
          }
          */
    
          int i;
          for(i=0; i<numbersLength; i++)
          {
              cout << "Zahl " << i << " eingeben - ";
              cin >> numbers[i];
              //wenn die zahl an der stelle an der wir gerade eben eingelesen haben eine 0
              //ist kommen wir in das if rein
              if(numbers[i] == 0)
              {
                  //und hier ist etwas das ihr vielleicht nicht kennen werdet, ein break ist
                  //nen sehr praktisches keyword welches bedingungslos wenn es erreicht wird
                  //die schleife in der es gerade ist beendet, wird das break also ausgeführt
                  //sind wir an der mit dem X markierten stelle weiter unten
                  break;
              }
          }
    
          // - X - und hier kommen wir hin wenn das break ausgeführt wurde oder die maximale
          // anzahl an zahlen eingelesen wurde, ok, da unser zähler (i) immer schön mitgezählt
          // hat steht jetzt in i drinnen wieviele zahlen das array enthält, alles was jetzt noch zu tun ist
          // ist die 3 funktionen aufzurufen die uns unseren median und all den mist ausrechnen
    
          //bevor wir das tun schauen wir aber überhaupt erst ob der benutzer nicht gleich am anfang eine 0
          //eingegeben hat, dann ist der zähler nämlich auf 0 und über 0 elemente können wir keinen durchschnitt
          //oder so bilden, sollte das der fall sein sagen wir dass wir keine eingabedaten haben und mit return
          //beenden wir die main() funktion und somit das programm
          if(i == 0)
          {
              cout << "Keine Zahlen eingegeben";
              return;
          }
    
          //und wenn wir hier sind dann ist i mindestens 1
    
          float average;
          float median;
          float deviation;
    
          average = Average(numbers, i);
          median = Median(numbers, i);
          deviation = Deviation(numbers, i);
    
          cout << "\n\nDurchschnitt: " << average << "\nMedian: " << median << "\nStandardabweichung: " << deviation << "\n";
      }
    
      //so und da definieren wir erstmal die durchschnittsfunktion
      float Average(const int aNumbers[], const int aNumbersToProcess)
      {
          float average = 0;
    
          //was die for schleife hier macht sollte jetzt klar sein
          //aber halt nochmal zur wiederholung, wir fangen bei 0 an
          //machen solange weiter bis wir den wert erreicht haben der
          //in aNumbersToProcess drin steht und i wird _nach_ jedem
          //schleifendurchlauf um 1 erhöht, was noch anzumerken ist
          //vorher haben wir int i; deklariert und in der schleife
          //geschrieben for(i = 0; ...) jetzt schreiben wir direkt
          //for(int i = 0; ...) das heißt wir definieren i in der for
          //schleife, der clou dabei ist dass sobald die for schleife
          //aus ist, der compiler das i nicht mehr kennt, es ist wenn
          //wir es in dem for mit for(int i = 0; ..) definieren nur innerhlab
          //der for schleife gültig.. k
          for(int i=0; i<aNumbersToProcess; i++)
          {
              //wir missbrauchen die variable für den durchschnitt erstmal um
              //die summe über alle elemente aus aNumbers zu bilden, falls ihr
              //+= nicht kennt, es ist eine kurzschreibweise, wenn ich hab
              //x += y; heißt das x = x + y; ähnlich wie i++; gleich i = i + 1; ist
              //ich könnte natürlich auch schreiben i += 1; das ganze geht auch mit
              // -= *= und /= für minusrechnen, multiplizieren und das vierte, es gibt auch
              // ein -- für i--; also i = i - 1; nur zur ergänzung, allerdings gibt es kein **
              //für i**; irgendwie... i = i²;... ok vergessen wir das mal, also hier bilden
              //wir die summe über alle elemente in aNumbers indem wir es in der schleife durchlaufen
              //und immer den wert drin drinsteht zu average dazuaddieren
              average += aNumbers[i];
          }
    
          //jetzt wo wir fertig sind haben wir unsere summe über alle elemente die in average drin steht
          //so, angenommen unser array enthielt die elemente 1, 2, 3, 4, 5, 0, 0, 0, ... 0
          //wieso sind da so viele nullen hinten dran?, wir dürfen nicht vergessen, das array ist immer
          //noch 50 integer lang, wir haben nach der 5 die eingabe mit 0 beendet aber dahinter stehen
          //trotzdem immer noch lauter 0llen, allerdings sagt uns aNumbersToProcess das wir als parameter
          //übergeben haben dass uns nur die ersten 5 elemente interessieren, also bilden wir einfach den
          //durchschnitt mit unserer kurzschreibweise average /= aNumbersToProcess; was heißt
          // average = average / aNumbersToProcess;
          average /= aNumbersToProcess;
    
          //ganz zum schluss geben wir den durchschnitt als rückgabewert der funktion zurück
          return average;
      }
    
      //und dann kommt der median, ich hab in wikipedia nageschaut da steht der median ist von nem
      //sortierten array einfach das mittlere element, und in eurer angabe steht es wird sortiert sein
      //also müssen wir einfach nur mehr die mitte rausfinden, so einfach? nein der haken ist bei
      // "1, 2, 3" ist es klar was die mitte ist und zwar 2, aber bei "1, 2, 3, 4" ist der median
      // (2 + 3) / 2 also der durchschnitt der mittleren beiden elemente, aber es ist trotzdem leicht
      float Median(const int aNumbers[], const int aNumbersToProcess)
      {
          //so und hier lernen wir nen neuen operator kennen falls ihr den nicht eh schon kennt %
          //der % (modulo) operator schaut wieviel rest zurückbleibt wenn ich eine zahl durch x teile
          //also 10 % 3 ergibt 1 (3*3 ist 9 und 1 rest auf 10), oder 50 % 26 ergibt 24 (26 geht in 50 1 mal
          //und es bleibt 24 rest, mit dem operator können wir also ganz einfach rausfinden ob wir ne richtige
          //mitte haben oder den druchschnitt über die 2 mittleren elemente bilden müssen, wenn ich nämlich
          //5 elemente habe und 5%2 rechne kommt 1 raus, dh die zahl ist ungerade, und bei 10%2 kommt 0 raus
          //also ist sie gerade
    
          //ist unsere zahl ungerade?
          if(aNumbersToProcess % 2 == 1)
          {
              //wenn ja dann sagen wir mal es sind 9 elemente, wir rechnen einfach 9 / 2, das ergibt 4.5, wir
              //lassen das 0.5 wegfallen und 4 ist unsere element in der mitte, hier das ganze grafisch untermalt
              //dabei nicht vergessen das ein array von 0 - n durchnumeriert wird und nicht von 1 bis n, und a-i
              //sind unsere elemente
              // 0 1 2 3 4 5 6 7 8
              // a b d c e f g h i
              //wie lasse ich den rest wegfallen? ein int kann nur ganze zahlen speichern, wenn ich 9/2 rechne
              //wird nicht gerundet sondern die nachkommastelle fällt immer weg
    
              //das hier kann vielleicht etwas verwirrend sein, also man könnte es in einzelschritte aufteilen
              /*
              int middle;
    
              middle = (int)(aNumbersToProcess/2);
    
              return aNumbers[middle];
              */
              //oder wir hauen es einfach gleich in das return statement rein, falls ihr das (int) nicht kennt, das
              //ist ein cast, ein cast wandelt einen variabentyp in einen anderen um, wenn wir 9 / 2 rechnen zb kommt
              //ein double dabei raus (nicht float, wenn ihr 5.323 schreibt ist es für den compiler ein double außer
              //ihr sagt was anderes), in c++ ist es egal weil der compiler das eh automatisch sieht dass ihr die 4.5
              //einem int zuweist und er lässt die .5 wegfallen aber andere programmiersprachen wie c# meckern da zb
              //herum also hab ichs drin gelassen wegen typensicherheit blabla... schöner programmierstil, und da wir
              //integer in aNumbers haben casten wir auch auf nen float da der rückgabewert float ist
              return (float)aNumbers[(int)(aNumbersToProcess/2)];
          }
          else
          {
              //und wenn wir eine gerade anzahl an elementen haben zb 4 ist das "zweite mittlere element" 4/2, also
              //element 2, das c, und das erste mittlere element 4/2 - 1, also das b
              // 0 1 2 3
              // a b c d
              //wenn wir uns das überlegen geht das auch immer, 6 elemente, das erste mittlere ist 6/2 - 1 = 2 und das
              //zweite 6/2 = 3, also in dem fall wäre element 2 die 4 und element 3 die 6, und der median ist (4+6) / 2
              // 0 1 2 3 4 5
              // 1 2 4 6 9 9
    
              //weil wir nicht das nicht wieder in 10 zeilen schreiben wollen packen wir alles gleich in eine
              //aber zur veranschaulichung, es ist im prinzip das
              /*int middleElement1Position = aNumbersToProcess/2 - 1;
                int middleElement2Position = aNumbersToProcess/2;
    
                int middleElement1 = aNumbers[middleElement1Position];
                int middleElement2 = aNumbers[middleElement2Position];
    
                float median = (float) ( (middleElement1 + middleElement2) / 2 );
                return median;
              */
              return (float)( (aNumbers[aNumbersToProcess/2 - 1] + aNumbers[aNumbersToProcess/2]) / 2 );
          }
      }
    
      //ok und als aller letztes die standardabweichung... ja... ok google sagt
      //"standardabweichung: die summe aller quadrierten abweichungen der einzelnen
      //messerwerte vom mittelwert, dividiert durch die anzahl der messwerte, ergibt
      //die variaz (aha die variaz.. ok), die standardabweichung ist die pos wurzel der
      //variaz
      //so toll, da brauchen wir also wurzeln und so, aber es ist trotzdem nicht schwer
      float Deviation(const int aNumbers[], const int aNumbersToProcess)
      {
          float variance = 0;
    
          //so, zuerst müssen wir die summe aller quadrierten abweichungen bilden, also bevor
          //wir anfangen kurz n beispiel so wie ich das verstanden habe, wenn unsere elemente
          //1, 2, 3, 4, 5 sind dann ist der durchschnitt (1+2+3+4+5)/5 = 3, die varianz ist
          // ( (1-3)² + (2-3)² + (3-3)² + (4-3)³ + (5-3)² ) / 5, und die standardabweichung ist
          //dann die wurzel aus der varianz, also zuerst rechnen wir uns den durchschnitt aus
          //was wir ja von unserer durchschnittfunktion übernehmen lassen können
    
          //wir definieren einfach ne neue variable wo wir den durchschnitt reinspeichern, der
          //rückgabe wert von Average ist einfach ein float mit dem durchschnitt deswegen können
          //wir das einfach so schreiben als wenn die funktion ein wert wäre, in wirklichkeit
          //wird die funktion ausgeführt und der rückgabewert wird dann average zugewiesen
          float average = Average(aNumbers, aNumbersToProcess);
    
          //jetzt wo wir den durchschnitt haben bilden wir die varianz
          for(int i=0; i<aNumbersToProcess; i++)
          {
              //so, das ganze += und for zeug kennen wir bereits, pow ist jetzt eine funktion
              //die in der math.h drin ist und wir verwenden sie genauso wie printf zb, der
              //erste parameter ist die zahl selbst, und der zweite die potenz, wir wollen
              //(aNumbers[i] - average) also die abweichung quadrieren also ist das der erste
              //parameter, der zweite ist 2 weil wir es hoch 2 nehmen wollen, wir könnten natürlich
              //auch schreiben variance += (aNumbers[i] - average) * (aNumbers[i] - average); aber
              //wenn sich schon jemand anders die mühe gemacht hat die pow funktion zu schreiben
              //benutzen wir sie gleich, und wir casten den ersten parameter der fkt auf einen float
              //da wenn wir aNumbers[i] (ist ein int) - average (ist ein float) rechnen kommt glaube ich
              //dabei ein double raus, bin mir aber nicht sicher und pow gibt wenn es (double, int)
              //reinbekommt nen double zurück, wir könenn also entweder
              //variance += (float)pow((aNumbers[i] - average), 2); schreiben wo wir den double rückgabe
              //wert auf float zurückcasten oder wir casten gleich den ersten parameter auf nen float
              //ich hoffe ich erzähle hir keinen mist weil ich mir nicht sicher bin ob ein int - float nen
              //double ergibt... aber wie gesagt ist es eigentlich egal weil das in c++ sowieso alles
              //automatisch geht, aber trotzdem, typensicherheit, hoffe das mit dem casten verwirrt nicht so
              variance += pow((float)(aNumbers[i] - average), 2);
          }
    
          //jetzt müssen wir wie in der angabe von dem varianz zeug den durchschnitt über die abweichungen
          //bilden also dividieren wir die summe der abweichungen durch die anzahl der elemente
          variance /= aNumbersToProcess;
    
          //und am ende hepp, geben wir die wurzel aus der varianz zurück, casten den rückgabewert hier nicht
          //weil die qrt funktion wenn sie nen float reinbekommt und variance ist ja ein float auch nen float
          //rausspuckt, bei pow haben wir als ersten parameter double übergeben und als zweiten einen int, weil
          //wir gerechnet haben (aNumbers[i] - average) numbers ist ein int und average ein float aber wenn 
          return sqrt(variance);
      }
    Alles anzeigen


    achja, und ich wollte euch noch fragen in welchem semester ihr seid und was ihr studiert
    wir machen nämlich in eprog 1 semester wo es ja für alle informatik studien gleich ist java und ich würde eigentlich
    auch viel lieber c++ machen und das ist ja das informatik studien forum für eprog etc oder bin ich hier falsch?!

  • float to string

    • Vevusio
    • 6. November 2006 um 23:53

    genau, du machst es entweder so wie kub geschrieben hat und verwendest die std, dabei musst du übrigens einige std includes machen, dann geht das ganze recht einfach

    C
    #include <string>
    #include <iostream>
    #include <sstream>
    
    
    void StringToFloatMethod1()
    {
        //Methode 1
        float aFloat = 20.4324;
        std::ostringstream floatStringHelper;
    
        floatStringHelper << aFloat;
    
    
        std::string floatString = floatStringHelper.str();
        std::cout << floatString;
    }
    Alles anzeigen


    oder wenn du lieber bei c bleiben möchtest dann geht das auch ganz einfach mit

    Code
    void StringToFloatMethod2()
    {
        //Methode 2
        float aFloat = 20.4324;
        char floatStringBuffer[256];
    
    
        sprintf(floatStringBuffer, "%f\n", aFloat);
    
    
        printf("%f", aFloat);
    }
    Alles anzeigen


    der vorteil bei der zweiten methode ist dass du deinen string wenn du dich mit diesen ganzen formatierungszeichen auskennst so formatieren kannst wie du willst, zb immer auf 5 nachkomma stellen ausgeben

    wenn du übrigens den std::string nimmst und irgendwie an ein char[] rankommen willst wieder dann machst du das mit der .c_str() methode

  • Hashing

    • Vevusio
    • 6. November 2006 um 15:21

    ein hash ist ein code der bestimmte daten eindeutig identifizieren soll

    es gibt etwas das heißt hashalgorithmen von denen MD5 zb ein ganz bekannter ist, diese generieren über eine meist große datenfolge (zb ein bild, eine zeichenkette usw) einen viel kleineren hash der trotzdem die eigenschaft hat dass er einzigartig ist

    wenn ich zb den string "das ist ein test!" hashe kommt dabei raus -1100477139
    wenn ich nur einen buchstaben änder, zb "das ist kein test!" wird der hash so: -2018157948

    das ist noch eine eigenschaft von hashes, kleine änderungen im der datenmenge über die er gebildet wird bewirken dass sich der hash überhaupt ganz ändert

    wofür werden hashes jetzt vernwendet?
    wenn du beispielsweise auf manchen seiten exe files zum runterladen hast sieht du manchmal daneben so nen komischen langen string mit zahlen und buchstaben, das ist ein hash der über die exe gebildet wurde, wenn du die exe file von einem mirror runterladest kannst du selbst einen hash drüberlaufen lassen und wenn der nicht mit dem referenzhash auf der anbieterseite übereinstimmt dann ist es nicht dieselbe exe file (andere version, jemand hat nen virus reingetan etc)

    eine weitere verwendungsmöglichkeit von hashes währe beispielsweise wenn du ein programm hast das bilder in den speicher ladet, jedesmal wenn du ein bild reinladest hashst du den inhalt und vergleichst den hash mit allen hashes der schon geladenen bilder, wenn es bereits einen hash gibt der gleich ist wie der mit dem du vergleichst weisst du dass das bild schon im speicher ist und ladest es nicht mehr neu rein

    es gibt auch etwas das sich hash table nennt, das ist mehr oder weniger ein array dessen elemente immer wertepaare sind, ein paar enthält einen hash (id) und den wert mit dem der hash assoziiert wird dabei müssen nich zwangsläufig wirklich die hashes über den wert gebildet werden sondern als hash/id kann auch einfach eine zahl genommen werden die immer erhöht wird

    also ganz kurz gefasst, hash = relativ kleine zahl (bei md5 128 bit) die eine beliebig große datenmenge (beispielsweise eine 10mb große bitmap) eindeutig identifiziert

    hashalgorithmus -> wird verwendet um über die datenmenge einen hash zu erzeugen

    wenn du das in c# machst gibts beispielsweise für jedes objekt einfach ne methode .GetHashCode() die dir den hash holt, in c/cpp würde ich mal in der std schauen obs da nicht sowas gibt ansonsten gibt es sicher genügend libs die du einfach inkludieren kannst und über ne funktion nen md5 hash über einen char* buffer an daten bilden kannst

    alleine würd ich sowas nicht implementieren.. wozu auch wenns das schon tausendfach besser ausgeführt gibt

Rechtliches

Impressum

Datenschutzerklärung