Noobie braucht dringend Hilfe!!! (Zeiger/Zeigerübergabe)
-
aha
also gehoert das zu den freiheiten des c++ programmierers mit falschem code richtige programme zu schreiben.was wuerde denn:
int *pa&;
bewerkstelliegn?
-
Sonja80 schrieb:
ich versteh nicht so recht, wie ich den Durchschnitt zurückgeben soll...
na einfach mit einer zuweisung
durchschnitt = der_durchschnitt;
das ist auch der grund warum durchschnitt ein referenz parameter ist.
Kurt
-
lookias schrieb:
was wuerde denn:
int *pa&;
bewerkstelliegn?Syntax error.
Kurt
-
also:
ich versteh nicht, wieso es im Kopf heisst "float & durchschnitt".
hab ich jetzt damit eine float Variable definiert?
dann rufe ich im Hauptprogramm die Funktion auf, in der dann der Durchschnitt errechnet wird, aber wie kann ich denn dann aus dem Hauptprogramm auf diese Variable der Funktion zugreifen?
-
du hast keine neue variable (bzw. Parameter) definiert, sondern eine Referenz. Eine Referenz arbeitet ähnlich wie ein Zeiger, nur dass man sie nicht dereferenzieren kann, und dass man sie nicht "umlenken" kann, d.h. sie verweisen auf immer dasselbe Objekt, sobald sie einmal zugewiesen wurden.
Bsp:
float& ra; //Referenz auf eine Fließkommazahl { float a; //eine ganz normale Fließkommazahl ra = 4; //FEHLER!! ra ist noch an kein Objekt "gebunden" ra = a; //hiermit bezieht sich ra für immer auf a a = 4; // in ordnung, a ist jetzt 4 (und damit auch ra) ra = 6; // in ordnung, a ist jetzt 6 ... } // gültigkeitsbereich von a wird verlassen... ra = 7 // FEHLER!! a existiert nicht mehr, damit darf auch ra nicht verwendet werden float b; ra = b; //FEHLER!! ra kann nur einmal an ein Objekt "gebunden" werden
Ich hoffe, das verdeutlicht in etwa die Benutzung von Referenzen.
wenn du also deiner Referenz was zuweist, wird die Zahl, die du beim Aufruf der Funktion an die Referenz übergibst, genauso verändert...
-
int get_mean(student * pA, int matrnr, float & durchschnitt) { int gefunden = -1; // student suchen // wen gefunden durchschnitt berechnen ..... durchschnitt = berechneter_durchschnitt; .... return gefunden; } int main() { student * pA; float notendurchschnitt; int nr = 5321; if ( 0 == get_mean( pA, nr, notendurchschnitt ) ) cout << "Notendurchschnitt = " << notendurchschnitt << endl; else cout << "der Student mit der Matrikelnummer " << nr << "existiert nicht" << endl; }
-
ok, und in der Funktion arbeite ich dann mit dem Synonym "durchschnitt", womit auch immer die Variable, die ich an die Funktion übergeben habe, global verändert wird. richtig? wobei ich ja auch gleich in der Funktion mit der globalen Variable arbeiten könnte, oder?
-
Sonja80 schrieb:
ok, und in der Funktion arbeite ich dann mit dem Synonym "durchschnitt", womit auch immer die Variable, die ich an die Funktion übergeben habe, global verändert wird. richtig? wobei ich ja auch gleich in der Funktion mit der globalen Variable arbeiten könnte, oder?
Eigentlich schon aber globale variablen sind bööööööse.
Kurt
-
Ok, dank ZuK hab ichs endgültig kapiert... THX!!!
-
ZuK schrieb:
Eigentlich schon aber globale variablen sind bööööööse.
War das ironisch gemeint?
-
eigentlich nicht. denk nur daran wass passiert wenn du lokale variablen mit dem gleichen namen definierst.
Kurt
-
mit Sicherheit nicht. globale Variablen sind wirklich schrecklich, sobald der Code über 20 Zeilen deutlich hinausgeht
der Clou an den Referenzen als Parameter ist ja, dass du an der Stelle des Aufrufs festlegen kann, in welche Variable deine Funktion den Durchschnitt speichern soll (muss ja nicht immer die selbe sein). Das kann durchaus auch eine sein, die irgendwo ganz versteckt in einem sehr lokalen Gültigkeitsbereich existiert (z.B. in einer anderen Funktion)
-
Kacke. Wollt grad die ganzen Funktionen im Hauptprogramm ausprobieren, und schon scheiterts wieder. Wird die Funktion ausgeführt, erscheint nach eingabe der Matrikelnummer die fehlermeldung, dass das Programm beendet werden musste. Ich hol gleich die Axt!!! Die Fehlersuche erzählt was von Zugriffsverletzung (Segmentation Fault)
Mein verbesserter Quellcode dieser Funktion:int initialize(student *&pA) { int n; cout<<"Wieviel neue Studenten möchten sie zur Liste hinzufügen?"; cin>>n; if (n==0) return 0; else { for (int i=1; i<=n; i++) { student * phelp; phelp = new student; cout << "Nachname: "; cin >> phelp->name; cout << "Vorname: "; cin >> phelp->vorname; cout << "Studienfach: "; cin >> phelp->fach; cout <<"Matrikelnummer: "; cin >> phelp->matrikelnummer; for (int j=0; j<20; j++) phelp->noten[j]=0; phelp->pnext = 0; if ((pA==0) || (strcmp(phelp->name, pA->name)<0)) { phelp->pnext = pA; pA = phelp; } else { student *prun; prun = pA; while((prun->pnext != 0) && (strcmp(prun->pnext->name, phelp->name)<0)) prun = prun->pnext; phelp->pnext = prun->pnext; prun->pnext = phelp; } } } }
Eure geschulten Augen entdecken doch bestimmt gleich den Fehler oder?
-
alles klar, fehler gefunden, pA war nicht initialisiert, da ging der Vergleich schief
-
#include <iostream> using namespace std; struct student { char name[40]; char vorname[20]; char fach[40]; int matrikelnummer; float noten[20]; student * pNext; }; int initialize(student *&pA) { int i=0, d=0, r=0; student *pH, *pNeu, *ptmp, *pPrev; while (i<2) //studenten einlesen { pNeu=new student; //listenelement für übergabe /* EINLESEN */ cout << endl; cout << "Name: "; cin >> pNeu->name; /* cout << "Vorname: "; cin >> pNeu->vorname; cout << "Fach: "; cin >> pNeu->fach; cout << "Matrikelnummer: "; cin >> pNeu->matrikelnummer; */ //noten 0 setzen for(int c=0; c<20; c++) { pNeu->noten[c]=0; } if(!pA) { //cout << "Liste noch nicht vorhanden" << endl; pA=pNeu; pH=pA; pH->pNext=NULL; } else { pH=pA; //immer vorn anfangen //WHILE SCHLEIFE while(( (strcmp(pNeu->name, pH->name)>0) && (pH->pNext!=NULL)) ) //solange eingabe groeÃer & nicht last element { pPrev=pH; pH=pH->pNext; cout << "while - d: " << d << "pNext: " << pH->pNext << endl; d++; } if(pH->pNext==NULL) { if (strcmp(pNeu->name, pH->name)<0) { if(d!=0) { // cout << "schleife" <<endl; pPrev->pNext=pNeu; pNeu->pNext=pH; } else { pNeu->pNext=pH; pA=pNeu; } //pPrev->pNext=pNeu; } else { // cout << "last element" << endl; //neues ele pH->pNext=pNeu; pH=pH->pNext; //pNeu->pNext=NULL müste auch gehen pH->pNext=NULL; //andere sachen auch übertragen // cout << "pH->name von pNeu :" << pH->name << endl; } } if(pH->pNext!=NULL) { // cout << "not last element" << endl; // cout << "pH-pNext :" << pH->pNext << endl; if (pA==pH) { //element kommt vor anfang // cout << "pH==pA" << endl; // cout << "pH :" << pH << endl; // cout << "pA :" << pA << endl; pNeu->pNext=pA; pA=pNeu; } else { pNeu->pNext=pH; pPrev->pNext=pNeu; } } } i++; } r=1; return r; } int output(student *&pA) { student *pP; int i; pP=pA; for(i=0;i<2;i++) { cout << pP->name << "\t" << pP->vorname << "\t" << pP->fach << "\t" << pP->matrikelnummer <<endl; pP=pP->pNext; } } /* //set_marks int set_marks(student *const pA, int matrnr, int index, float note) { int r=0; student *pP; pP=pA; while(pP->matrikelnummer!=matrnr && pP->pNext!=NULL) { pP=pP->pNext; } if (pP->matrikelnummer==matrnr) pP->noten[index]=note; if (pP->matrikelnummer!=matrnr && pP->pNext==NULL) r=-1; return r; } //--- get_mean --- int get_mean(student * pA, int matrnr, float & durchschnitt) { int r=0, anz=0; float sum=0; student *pP; pP=pA; while(pP->matrikelnummer!=matrnr && pP->pNext!=NULL) { pP=pP->pNext; } if (pP->matrikelnummer!=matrnr && pP->pNext==NULL) r=-1; if (pP->matrikelnummer==matrnr) { for(int i=0;i<20;i++) { if (pP->noten[i]!=0) { sum=sum+pP->noten[i]; anz++; } } durchschnitt=sum/anz; cout << durchschnitt; } return r; } */ main () { student *pA; int mat, index; int exit=0; int eng; //float note; //while(exit==0) //{ /*-- MENU -- */ cout << endl << "---------------------------" << endl; cout << "1 - \tListe initilisieren" << endl; cout << "2 - \tNoten bearbeiten" << endl; cout << "3 - \tListe ausgeben " << endl; cout << "4 - \tDurchschnitt berechnen" << endl; cout << "5 - \tExmatrikulieren" << endl; cout << "6 - \tBeenden" << endl; cout << endl << "EINGABE :"; cin >> eng; switch(eng) { case 1: initialize(pA); // if (initialize(pHelp)==0) cout << "FEHLER beim Aufbau der Liste!" << endl; //else cout << "LISTE OK"; break; case 2: /* cout << endl << "Matrikelnummer :"; cin >> mat; cout << "Index :"; cin >> index; cout << "Note :"; cin >> note; // if (set_marks(pA,mat,index,note)==-1) cout << endl << "Matrikelnummer nicht vorhanden!" << endl; break; case 3: output(pA); break; case 4: cout << endl << "Matrikelnummer :"; cin >> mat; // if(get_mean(pA,matrnr,durchschnitt)==-1) cout << endl << "Matrikelnummer nicht vorhanden!" << endl; break; */ case 6: exit=1; break; } //} return 0; }
hi leute ich hab toller weise genau den gleichen beleg zu machen.
ich krieg ein SEGFAULT irgendwas hab ich mit den pointern falsch gemacht.die initializie funktion ging ohne probleme als ich aber die anderen funktionen noch geschrieben hab, kommt ein segfault. ich glaube er kommt an der stelle
if(!pA) ....
ich hab aber absolut keine ahnung warum
BITTE BITTE HELFT!!!!
DANKE martin
-
pH->name ist nicht initialisiert.
Den segmentationfault löst dann while(( (strcmp(pNeu->name, pH->name)>0)...
aus (erstes Drittel von init...)sagt mein Debugger.
Dein Quellcode lädt ja nicht gerade zum Lesen ein.Ich hoffe das hilft dir weiter
-
pH->name ist nicht initialisiert.
Den segmentationfault löst dann while(( (strcmp(pNeu->name, pH->name)>0)...
aus (erstes Drittel von init...)sagt mein Debugger.
Dein Quellcode lädt ja nicht gerade zum Lesen ein.Ich hoffe das hilft dir weiter
-
DANKE,
aber nachdem ich das erste mal einen namen eingegeben hab springt er doch eigentlich inif(!pA) { //cout << "Liste noch nicht vorhanden" << endl; pA=pNeu; pH=pA; pH->pNext=NULL; } else { ....
und da wird doch pH. zugewiesen.
aber dein debugger lügt ja sicher nicht.
wenn ich pA aber nur als pointer deklariert hab sollte
!pA doch true sein oder?Danke!
martin
-
Du mußt einen Zeiger auch initialisieren. Einfach nur Student* pA zu schreiben reicht nicht. Somit erzeugst Du einen Zeiger. Welcher Wert dort steht ist nicht vorhersehbar. Das da allerdings NULL steht, ist mehr als unwahrscheinlich. Somit scheitert die Prüfung !pA. Ergo: Student* pA = NULL;. Dann klappt das auch.
-
gib mal bitte deinen quellcode nochmal mit den entsprechenden Einrückungen etc. So wie er dort steht wird sich das kaum einer antun... (am besten auch noch unwichtige teile auskürzen)