Hilfe bei Strukturzuweisungen
-
Hallo,
ich bin noch recht neu bei C und muss für die FH eine Hausübung machen. Konnte auch drei von vier Aufgaben mit ein wenig tüfteln rauskriegen. Komme jetzt aber berhaupt nicht mehr weiter! Habe auch schon mind. 5 Stunden mein Glück versucht, aber komme nicht weiter und wende mich jetzt an euch.
Uns wurden eine Header und eine C Datei vorgegeben aus der wir dann die Lösung bauen sollen.Ich habe mit Aufgabe 3. ein Problem und hoffe den Rest soweit richtig zu haben.
Hier ein Link zur ganzen Aufgabenstellung.
http://homepages.thm.de/christ/Start/01Lehre/07KSP/aktuell/Uebung/KSPU02.pdf
Hier mal das, worums bei mir geht:
Zur Vervollständigung der Funktion (Markierung MORE_STRUCT3) fehlt noch die Speicherplatz-Reservierung und die Zuweisung der Leistungsdaten. Die drei benötigten Leistungen sollen den Studierenden aus der Reihe der gespeicherten Vorlesungen so zugeordnet werden, daß Matr. 1 die Vorlesungen mit den Indizes 0-2 hat, Matr. 2 jene mit Indizes 1-3 etc.. Bei Erreichen der letzten Vorlesung wird die Zuordnung zyklisch wiederholt.
Als Note wird schließlich für jedes Fach eine zwischen 2 und 3 zufällig gewählte Note mit einem ebenfalls zufällig gebildeten Versatz, der 0 oder ±0,3 betragen kann.Konkret weiß ich nicht, wie ich auf die Daten zugreifen kann bzw wie ich das zuweise. Die Strukturen sollen nicht verändert werden und ich habe keinen Schimmer wie ich es hinbekommen kann
Die Struktur:
typedef struct { struct Fach; float FachNote; } Leistg;
aber wie soll ich auf FachName aus Fach/Vorlesung zugreifen!?
Zugriff auf 'FachName' von fast ganz unten Zeile 119:
BS_S[j1].Leist[j2].FachName, BS_S[j1].Leist[j2].FachNote); }
Ob die
/* strucTest.c */ /*Zeiger und Strukturen am Bsp. einer "MNI-Datenbank"*/ #include "strucTest.h" /* *********************************************************************** */ char *namXpath (char *namPath) /* *********************************************************************** */ { /*Extraktion des Programmnamens aus dem uebergebenen Pfad:*/ char *shortPath = strrchr(namPath, '\\')+1; //Aufgabe 1 anstatt '\\' auch Übergabe der Konstanten BSLS mit dem ASCII Wert möglich namPath=NULL; namPath= shortPath; //Aufgabe 1 return namPath; } /* *********************************************************************** */ int randRang(int rangeMin, int rangeMax) /* *********************************************************************** */ { /*Pseudo-Zufallszahlen innerhalb eines Zahlenintervalls (range):*/ int randR=0; randR = rangeMin + ( rand() % (rangeMax-rangeMin+1 )); //Aufgabe 2 return (randR); } /* *********************************************************************** */ int setStud (Stud *defSt, Vorlesg *BS_V) /* *********************************************************************** */ { static int LfdNr=1; int j1=0; sprintf (defSt->Name, "%c.%c.", randRang('A','Z'), CYCLIC(LfdNr,'A','Z')); defSt->Matrikel = LfdNr; defSt->nLeist = 3; defSt->Leist = (Leistg *)calloc (3, sizeof(Leistg)); //Speicherallokation; -> Pfeiloperator weißt //HIERUM GEHT ES defSt->Leist->Fach->FachName =BS_V->FachName; defSt->Leist->FachNote=4; //zum Testen alle Noten=4 //HIERUM GEHT ES LfdNr++; return OK; } /* *********************************************************************** */ int main(int argc, char *argv[]) /* *********************************************************************** */ { Prof BS_P[PROF]; Stud BS_S[STUD]; Vorlesg BS_V[VORL]; int j1=5, j2=8; // Mit (-2)...(3) probieren! #ifdef _DEBUG // _entfernen für VS2010!! /*Groesse beteiligter Strukturen:*/ printf (" sizeof(struct Fach)= %d\n\r", sizeof(struct Fach)); printf (" sizeof(Vorlesg) = %d\n\r", sizeof(Vorlesg)); printf (" sizeof(Prof) = %d\n\r", sizeof(Prof)); printf (" sizeof(Leistg) = %d\n\r", sizeof(Leistg)); printf (" sizeof(Stud) = %d\n\r", sizeof(Stud)); /*Zufallszahlen-Test, bis ESC gedrueckt wird:*/ printf ("\n\r Pseudo-Zufallszahlen zwischen %d und %d:", j1, j2); printf ("\n\r (Bel. Taste / Weiter mit Esc)\n\r"); while (_getch() != ESC) { printf("%6d\n", randRang(j1,j2)); } system("cls"); #else //DEBUG /*Initialisierung der Zufallszahlen fuer diesen Start:*/ srand((unsigned)time(NULL)); #endif//DEBUG /*Eigentlicher Programmstart:*/ printf (" Sie haben das Programm \"%s\" gestartet\n\n\r", namXpath(argv[0])); /*Angebotene Vorlesungen:*/ strcpy (BS_V[0].FachName, "KonzSysProg"); BS_V[0].FachSWS = 4; strcpy (BS_V[1].FachName, "Comp.Grafik"); BS_V[1].FachSWS = 3; strcpy (BS_V[2].FachName, "BildVerarb."); BS_V[2].FachSWS = 2; strcpy (BS_V[3].FachName, "MathematikI"); BS_V[3].FachSWS = 6; strcpy (BS_V[4].FachName, "Th.Physik I"); BS_V[4].FachSWS = 3; /*Professoren:*/ for (j1=0; j1<PROF; j1++) { sprintf (BS_P[j1].Name, "%c.%c.", CYCLIC(j1+1,'A','Z'), CYCLIC(j1+1,'C','Z')); BS_P[j1].nVorl=3; BS_P[j1].Vorl = (Vorlesg *)calloc (BS_P[j1].nVorl, sizeof(Vorlesg)); if (!BS_P[j1].Vorl) { printf("Kein Speicher fuer Prof[%d]!\n", j1); _getch(); exit(1); } printf (" Prof. %s liest z.Z.:\n\r", BS_P[j1].Name); for (j2=0; j2<BS_P[j1].nVorl; j2++) { BS_P[j1].Vorl[j2] = BS_V[(j1+j2)%VORL]; //Strukturzuweisung printf (" %s (%d SWS)\n\r", BS_P[j1].Vorl[j2].FachName, BS_P[j1].Vorl[j2].FachSWS ); } printf ("\n\r"); } /*Stichprobe als Plausibilitaetskontrolle:*/ printf (" Speicheradressen:\n\r"); printf (" BS_P[0].Vorl[1]:%8d\n\r", &BS_P[0].Vorl[1]); printf (" BS_P[0].Vorl[0]:%8d\n\r", &BS_P[0].Vorl[0]); j1 = sizeof(BS_P[0].Vorl[0]); //Aufgabe 4 FUNKTIONIERT printf (" Differenz: %8d\n\n\r", j1); if (j1 != sizeof(Vorlesg)) printf(" Codierungsfehler!\n\n\r"); _getch(); /*Studierende:*/ for (j1=0; j1<STUD; j1++) { if (!setStud (&BS_S[j1], BS_V)) { printf ("Fehler!"); _getch(); exit(0); } printf (" Herr/Frau %s (Matr. %d) bekam: \n\r", BS_S[j1].Name, BS_S[j1].Matrikel); for (j2=0; j2<BS_S[j1].nLeist; j2++) { printf ("\tin %s die Note \"%3.1f\"\n\r", //HIERUM GEHT ES - das ist vorgegeben BS_S[j1].Leist[j2].FachName, BS_S[j1].Leist[j2].FachNote); } printf ("\n\r"); //HIERUM GEHT ES - das ist vorgegeben } printf ("\n\r Ende!\n\r(bel. Taste)"); _getch(); return 1; }
und nun die Header Datei
/* strucTest.h */ #ifndef STRUCTEST_H #define STRUCTEST_H #pragma warning(disable : 4996) // ("veraltet" nicht mehr melden!) #include <conio.h> // _getch() #include <stdio.h> // printf() #include <stdlib.h> // calloc() #include <string.h> // strcpy() #include <time.h> // time() //#define DEBUG //#define MORE_STRUCT1 //#define MORE_STRUCT2 //#define MORE_STRUCT3 //#define MORE_STRUCT4 /*Benoetigte Konstanten:*/ #define ESC 27 #define LANG 20 #define OK 1 #define PROF 3 #define STUD 5 #define VORL 5 /*Typische Begrenzungszeichen in Pfad-Angaben:*/ #define SLSH 47 // ASCII ("/") #define BSLS 92 // ASCII ("\") /*Zyklisches Zaehlen zwischen willkuerlichen Grenzen A und Z (A<Z, Nr=1,...):*/ #define CYCLIC(Nr,A,Z) (((Nr)+(Z)-(A)) % ((Z)-(A)+1) + (A)) //CYCLIC(24,1,12)=12, CYCLIC(0,1,2)=2 /*Daten-Strukturen und -Typen:*/ typedef struct Fach { char FachName[LANG]; //Studiengang, ... int FachSWS; //Praktikum, CreditPoints, ... } Vorlesg; typedef struct { char Name[LANG]; //Vorname, Familienname, Geburtsname, ... int nVorl; //PersoNr., Dienstalter, Geburtsjahr, ... Vorlesg *Vorl; } Prof; typedef struct { struct Fach; float FachNote; } Leistg; typedef struct { char Name[LANG]; //Vorname, Familienname, Heimat-Adresse, ... int Matrikel; //Studienbeginn, ... int nLeist; Leistg *Leist; } Stud; #endif//STRUCTEST_H
Viel zu lesen, ich weiß, aber wäre super, wenn mir jemand helfen könnte! :xmas1:
-
Gude, sitze bei dir im Kurs. Nur das ich das Vergnügen hatte vorher schon mal ein Semester lang ne anständige C-Vorlesung hören durfte. Kann dich schon verstehen wenn du da etwas Probleme hast.
Ich hab die Aufgabe schon fertig und auch korrekt abgegeben. Meine setStud sieht so aus:
int setStud (Stud *defSt, Vorlesg *BS_V) { static int LfdNr=1; int j1=0,k; static int counter=0; sprintf (defSt->Name, "%c.%c.", randRang('A','Z'), CYCLIC(LfdNr,'A','Z')); defSt->Matrikel = LfdNr; defSt->nLeist = 3; defSt->Leist =(Leistg *)calloc(3,sizeof(Leistg)); if (counter == 5) counter = 0; k = counter; for(j1=0; j1 < 3 ; j1++) { if (k==5) k=0; strcpy(defSt->Leist[j1].FachName,BS_V[k].FachName); defSt->Leist[j1].FachSWS = BS_V[k++].FachSWS; defSt->Leist[j1].FachNote = randRang(2,3) + randRang(-1,1)/3.0; } counter++; #ifdef MORE_STRUCT3 #endif//MORE_STRUCT3 LfdNr++; return OK; }
Ich weis jetzt nicht genau wo dein Problem liegt, meinst du etwa das dir die IDE einen Fehler ausgibt:
"class "Leistg"" hat keinen Member ""FachSWS"". ?
Wenn ja kannst du das ignorieren, wenn dus Compilierst klappt alles wunderbar.Hatte auch eine heiden Diskussion darüber weil das einfach meiner Ansicht nach totaler unübersichtlicher humbug ist den keiner mehr überblickt.
Das kommt daher, dass defSt ein Pointer auf ein typedef struct Stud ist.
Die struktur ist hier anonym und besitzt keinen Bezeichner sondern nur eine typedefinition Stud.Innerhalb dieser struktur der typ definition von Stud ist wiederum ein Pointer auf eine anonyme struktur mit einer typ definition Leistg.
So und jetzt kommt der clou da in der anonymen struktur mit der typedefinition Leistg drin steht:
typedef struct { struct Fach; float FachNote; } Leistg;]
Ist das wie als würdest du z.B. nur int schreiben, da das struct und fach zusammengehören.
Dadurch wird zur Compilierzeit der Inhalt der Struktur hineinkopiert. Das würde nach der Compilierung dann so aussehen:
typedef struct { char FachName[LANG]; //Studiengang, ... int FachSWS; //Praktikum, CreditPoints, ... float FachNote; } Leistg;
Das ist meiner Ansicht nach aber totaler Käse so etwas zu Programmieren, da dies meiner Ansicht nach einer erhebliche Verschlechterung der Code Lesbarkeit darstellt.
Würdest du z.B. der Struktur einen Bezeichner spendieren, würde der Fehler ignoriert:
[code="c"] typedef struct { struct Fach f; float FachNote; } Leistg;]
[/code]
Du könntest jetzt über:
defSt->Leist[j1].f.FachName
normal auf die Struktur zugreifen mit der IntelliSense.
Das Problem hierbei ist halt das die IntelliSense keinen Member zum Bearbeitungszeitpunkt sehen kann da dieser erst bei der Compilierung eingefügt wird.
Hab dir hier mal mein src geuploadet: http://ul.to/ixje8oly falls ich dein Fehler missverstanden habe.
Viele Grüße
Vertax und bis morgen
-
Hallo!
Ich hab ein Problem bei der erzeugung der Zufallszahlen.
1. Ich bin mir nicht sicher ob ich die Zahlen richtig generiere.
2. Ich weiß nicht wie man, dass problem mit dem +/- 0,3 versatz realisieren soll.
...
@ Vertax
Du hast die erste Übung hochgeladen .. meinste du kannst Übung 2 hochladen?
oder den code für das genergieren bzw setStud posten?
Daaaanke!
-
2. Ich weiß nicht wie man, dass problem mit dem +/- 0,3 versatz realisieren soll.
Einfach so:
[/code]defSt->Leist[j1].FachNote = randRang(2,3) + randRang(-1,1)/3.0;Sorry, war gestern bissle spät :p Hier die UE2: http://ul.to/fehqdhzp Die Zufallszahlen generiere ich so: [code="c"]/*Pseudo-Zufallszahlen innerhalb eines Zahlenintervalls (range):*/ int randRang(int rangeMin, int rangeMax) { int randR=0; #ifdef MORE_STRUCT2 #else //MORE_STRUCT2 //Modulo operation liefert maximal einen Rest zwischen 0 und rangeMax+1 //Da am Schluss + rangeMin addiert wird um bei einem Rest von 0 den minimal Wert zu generieren //muss dies vorher abgezogen werden, da man ansonsten über rangeMax liegt. randR = rand() % ((rangeMax+1) - rangeMin) + rangeMin; /*Version MSDN-Onlinehilfe (angepasst):*/ // randR = (int)(((double) rand() / RAND_MAX) * rangeMax + rangeMin); #endif//MORE_STRUCT2 return (randR); }
-
ahhh - vielen dank!
hatte das rand() auch so, nur war ich mir nicht sicher ob die zahlen so gleichverteilt sind.bist ein schatz
-
Ist ja sehr lustig das sich hier gleich mehrere aus dem Kurs tummeln.
Das spricht nicht für unseren ProfWie kann der Kerl denn auf die Idee kommen das mit struct so zu machen.. Wenn man noch neu ist und sowas nicht kennt - und in KEINEM Lehrbuch war auch nur annähernd so ein Beispiel - wie soll man das denn hinbekommen?
Hat mich insgesamt bestimmt zehn Stunden meines Lebens gekostet
Naja, zumindest vergessen werde ich es so schnell sicher nicht mehr
Um so größer natürlich der Dank an Vertax
Wenn bei der dritten HÜ Probleme auftauchen kann man hier denke ich auch nochmal reden!? Oder eMails austauschen?!
In Betriebssysteme hockt nicht zufällig auch noch jemand?
Das wird nämlich die nächste Herausforderung.Also nochmal, vielen vielen Dank!
Grüße
Hunter
-
Hallo Leute,
ich hoff ihr seit noch dabei und schaut hier noch rein
bin bei aufgabe 4 und hab keine ahnung wie ich vorgehen soll!
1. Darf man seinen Code nur in KSP.h und KSP.c einfügen?
2. Wieso braucht man einen Callback mit redisplay?
3. Wie bekommt man hin, dass durch drücken von s und d sich die zeilen verschieben?
Vielen Dank