SUCHE MIT Google
Web virtualuniversity.ch
HOME DIDAKTIK ECDL ELEKTRONIK GUIDES HR MANAGEMENT MATHEMATIK SOFTWARE TELEKOM
DIENSTE
Anmeldung
Newsletter abonnieren
Sag's einem Freund!
VirtualUniversity als Startseite
Zu den Favoriten hinzufügen
Feedback Formular
e-Learning für Lehrer
Spenden
Autoren login
KURSE SUCHEN
Kurse veröffentlichen

Suche nach Datum:

Suche mit Schlüsselwort:

Suche nach Land:

Suche nach Kategorie:
PARTNER
ausbildung24.ch - Ausbildungsportal, Seminare, Kursen... 

 
HTMLopen.de - Alles was ein Webmaster braucht

 
PCopen.de - PC LAN Netze und Netzwerke - alles was ein IT Profi und Systemtechnicker braucht

SOFTWARE

Bei dynamischer Allokation geht man folgendermaßen vor:

  • Es wird also zuerst eine Zeigervariable entsprechenden Typs definiert, die aber noch keinen sinnvollen Wert besitzt.
  • Dann wird für das Objekt, auf das die Zeigervariable verweisen soll, ausreichend Speicher allokiert und nun der Zeigervariablen die Adresse dieses Speichers zugewiesen.

Es ist wichtig, sich den Unterschied zum äquivalenten statischen Array klarzumachen. Während dyn eine Variable ist, deren Speicherplatz sich aus &dyn ergibt, ist stat eine konstante Adresse. Interessant ist die Frage, was denn dann &stat ist. Intern und formal wird dazu folgender Trick verwendet: &stat entspricht stat, die Adressen sind also identisch.

Die dynamische Speicherbelegung erfolgt mittels spezieller, in der Standardbibliothek enthaltenen, Speicherallokationsfunktionen. size_t ist dabei ein maschinenabhängig definierter Datentyp unsigned int, definiert in <stdlib.h>, <stdio.h.h>, <stddef.h>, etc.).

  • void *malloc(size_t size)
    belegt einen size Bytes großen zusammenhängenden Bereich und liefert die Anfangsadresse davon zurück.

  • void *calloc(size_t nobj, size_t size)
    liefert die Anfangsadresse zu nobj*size Bytes großem Bereich zurück; der Inhalt dieses Bereiches ist mit dem Wert 0 initialisiert.

  • void * realloc(void *ptr, size_t size)
    Veränderung der Größe eines allokierten Speicherblocks.

  • void free(void *)
    wird schließlich verwendet, um nicht mehr benötigten dynamisch belegten Speicherplatz wieder freizugeben.

  • size_t sizeof(something)
    ist ein Operator, wobei something nicht nur eine einfache oder strukturierte Variable sein kann, sondern auch ein Datentyp. Der Operator liefert die Länge des vom Argument belegten Arguments). Es ist ratsam, statt einer konstanten Größe eine Datenelementes anzugeben, die Größe mit sizeof() zu bestimmen. Erstens kann man sich nicht vertun und zweites sind soche Programme portabler. Also z. B. statt calloc(2,100) besser calloc(sizeof(int),100) verwenden.
Die Speicherallokations-Funktionen liefern die Anfangsadresse des allokierten Blocks als void-Pointer (void *) es ist daher kein Type-Cast bei Zuweisung an Pointer-Variable erforderlich. Um dem Programm mehr Klarheit zu geben, schadet es aber auch nicht, Type-Cast zu verwenden.

Die Funktionen malloc und calloc liefern bei Fehler (z. B. wenn der angeforderte Speicherplatz nicht zur Verfügung steht) den Nullpointer NULL zurück. Nach jedem Aufruf sollte deshalb deren Rückgabewert getestet werden! Dies kann mit void assert(int) geschehen. assert() ist ein Makro und benötigt das Headerfile <assert.h> und u. U. <stdio.h>. Ist das Argument NULL, wird das Programm abgebrochen, der Modulname und die Programmzeilennummer des assert-Aufrufs ausgegeben.

Für malloc, calloc und free wird das Headerfile <stdlib.h> oder <alloc.h> benötigt.

Der für die dynamische Speicherverwaltung zur Verfügung stehende Speicherbereich wird als Heap bezeichnet. Die Lebensdauer dynamisch allokierten Speichers ist nicht an die Ausführungszeit eines Blocks gebunden. Nicht mehr benötigter dynamisch allokierter Speicher ist explizit freizugeben (free()). Ein erstes Beispiel:

    
                                         int *ip;
                                         ip = (int *) malloc(n*sizeof(int));
                                       
ip zeigt hier auf n Speicherplätze vom Datentyp int. Mit
                                         free(ip);
                                       
kann der bereitgestellte Speicherplatz wieder freigegeben werden.

Im folgenden Beispielprogramm wird dynamisch Speicherplatz für Objekte bereitgestellt, die einfachen Variablen der Datentypen int, float und double entsprechen. Nach dem Ablegen von eingelesenen Zahlenwerten auf diesen Objekten und dem anschließenden Ausdrucken wird der zugeteilte Speicherplatz wieder freigegeben.

                                       #include <stdio.h>
                                       #include <stdlib.h>
                                       main()
                                         {
                                         int *ip; float *fp; double *dp;
                                       
                                         /* Speicher anfordern */
                                         ip = (int *) malloc (sizeof(int));
                                         fp = (float *) malloc (sizeof(float));
                                         dp = (double *) malloc (sizeof(double)); 
                                       
                                         printf("Drei Zahlen eingeben:\n");
                                         scanf("%d %f %lf", ip, fp, dp);
                                         printf("%d, %f, %f\n", *ip, *fp, *dp);
                                       
                                         /* Speicher freigeben */
                                         free(ip);
                                         free(fp);
                                         free(dp);
                                         }
                                       

Das folgende Demonstrationsprogramm zur Verwendung der Bibliotheksfunktionen zur dynamischen Speicherverwaltung liest eine beliebige Anzahl von double-Werten vom Terminal und gibt sie dann wieder aus. Beachten Sie die Verwendung von sizeof() und die Fehlerprüfung.

                                       #include <stdio.h>
                                       #include <stdlib.h>
                                       
                                       void main(void)
                                         {
                                         int i, anz;
                                         double *dfeld;
                                       
                                         printf("\nAnzahl der double-Werte ? ");
                                         scanf("%d", &anz);
                                       
                                         if (anz <= 0) 
                                           {
                                           printf("\nAnzahl muß >0 sein !\n");
                                           exit(1);
                                           }
                                       
                                         if ((dfeld = malloc(anz*sizeof(double))) == NULL)
                                           { 
                                           printf("\nSpeicherplatz reicht nicht aus !\n"); 
                                           exit(1);
                                           }
                                       
                                         /* Einlesen der double-Werte */
                                       
                                         for (i = 0; i < anz ; i++) 
                                           {
                                           printf (" Doublewert Nr. %d bitte:",i);
                                           scanf ("%f",dfeld+i);
                                           }
                                       
                                         printf ("\n");
                                       
                                         /* Ausgabe der double-Werte */
                                       
                                         for (i = 0; i < anz ; i++) 
                                           printf (" Doublewert Nr. %d  = %f:\n",i, dfeld[i]);
                                       
                                         free(dfeld);
                                         }
                                       
                                       

Funktion zum Aneinanderhängen zweier Strings in einem neu bereitzustellenden Speicherbereich. Im Gegensatz zur Bibliotheksfunktion strcat ist hier sichergestellt, daß genügend Speicherplatz bereitsteht.

                                       #include <stdlib.h>
                                       #include <string.h>
                                       
                                       char *addstring(char *s1, char *s2)
                                         {
                                         char *as;
                                           if ((as=malloc(strlen(s1)+strlen(s2)+1)) != NULL)
                                             { 
                                             strcpy(as, s1);
                                             strcat(as, s2);
                                             }
                                         return as;
                                         }
                                       

Die folgende Funktion split teilt eine Zeichenkette an einer vorzugebenden Stelle in zwei Teilstrings. im Beispiel wird auch der Aufruf in main gezeigt.

                                       #include <stdio.h> 
                                       #include <string.h>
                                       
                                       char *strchr(char *string_ptr, char find)
                                         /* Suche Positeon des Zeichens find im String, falls
                                            gefunden, Zeiger auf die Positeon von find, falls
                                            nicht return(NULL) */
                                         {
                                         while (*string_ptr != find)
                                           {
                                           if (*string_ptr == '\0')
                                             return (NULL);          /* nicht gefunden */
                                           string_ptr++;
                                           }
                                         return(string_ptr); 
                                         }
                                       
                                       char * split(char *line, char find)
                                         {
                                         char *ptr1; /* Pointer auf den ersten Teil */
                                         char *ptr2; /* Pointer auf den zweiten Teil */
                                       
                                         ptr1 = line; /* Zeilenanfang */
                                         ptr2 = strchr(line,find); /* suche Zeichen */
                                       
                                         if (ptr2 == NULL) 
                                           return(NULL);
                                         ptr2++;        /* Erstes Zeichen von Teil 2 */
                                         return(ptr2);
                                         }
                                           
                                       int main(void)
                                         {
                                         char line[80];  /* Eingabezeile */ 
                                         char *ptr;      /* Pointer auf den zweiten Teil */
                                       
                                         gets(line, sizeof(line), stdin);
                                         ptr = split(line,',');
                                       
                                         *(ptr-1) = '\0'; /* Komma auf Zeilenende setzen */
                                         if (ptr == NULL)
                                           {
                                           fprintf(stderr, "FEHLER: Kein Komma in %s\n", line);
                                           exit (8);
                                           }
                                        
                                         printf("Erster: %s Zweiter: %s\n", line, ptr);
                                         return (0);
                                         }
                                       

Unterprogramm zum Umwandeln deutscher Umlaute in ihre Ersatzdarstellung:

                                       char* umlaut(char* eingabe)
                                         {
                                         int i = 0, j = 0;
                                         char *tmp1 = NULL;
                                         char *tmp2 = NULL;
                                       
                                         /* Wir sparen uns das Ermitteln der Laenge des     */
                                         /* Eingabestrings und nehmen mal den worst case an */
                                         tmp1= malloc(2*strlen(eingabe) + 1);
                                         if(tmp1 == NULL) return(NULL);
                                       
                                         /*Kopieren und Ersetzen */
                                         while(eingabe[i] != '\0')
                                           {
                                           switch (eingabe[i])
                                             {
                                             case 'ä': tmp1[j++] = 'a'; tmp1[j++]='e'; break;
                                             case 'ö': tmp1[j++] = 'o'; tmp1[j++]='e'; break;
                                             case 'ü': tmp1[j++] = 'u'; tmp1[j++]='e'; break;
                                             case 'Ä': tmp1[j++] = 'A'; tmp1[j++]='e'; break;
                                             case 'Ö': tmp1[j++] = 'O'; tmp1[j++]='e'; break;
                                             case 'Ü': tmp1[j++] = 'U'; tmp1[j++]='e'; break;
                                             case 'ß': tmp1[j++] = 's'; tmp1[j++]='s'; break;
                                             default: tmp1[j++] = eingabe[i];
                                             }
                                            i++;
                                           }
                                         tmp1[j] = '\0';
                                         /* Nun den String genau passend zurueckgeben */
                                         tmp2 = malloc(strlen(tmp1) + 1);
                                         if(tmp2 == NULL) return(NULL);
                                         strcpy(tmp2,tmp1);
                                         free(tmp1);
                                         return(tmp2);
                                         }
                                       

Einlesen einer unbekannten Anzahl von Zeilen (max. Anzahl 100). Nach Abschluss der Eingabe erfolgt Ausgabe der Zeilen in umgekehrter Reihenfolge (letzte Zeile zuerst).

                                       #include <stdio.h>
                                       #include <stdlib.h>
                                       #include <string.h>
                                       
                                       #define MAXANZ  100
                                       #define MAXLEN  136
                                       
                                       int ZeilenEin(char *ZeilFeld[], int Max)
                                         {
                                         char *Next, Zeile[MAXLEN];
                                         int Laenge, ZeilZahl=0;
                                       
                                         while (gets(Zeile) != NULL)
                                           {
                                           Laenge = strlen(Zeile);
                                           if ((ZeilZahl < MAXANZ) && (Next=malloc(Laenge+1)) != NULL)
                                             { 
                                             strcpy(Next, Zeile);
                                             ZeilFeld[ZeilZahl++] = Next;
                                             }
                                           else
                                             return ZeilZahl;
                                           }
                                         return ZeilZahl;
                                         }
                                       
                                       void ZeilenAus(char *ZeilFeld[], int Anz)
                                         { 
                                         int i;
                                         for (i = Anz; i > 0; )
                                           { 
                                           printf("%s\n",ZeilFeld[--i]);
                                           free(ZeilFeld[i]);
                                           }
                                         }
                                       
                                       int main(void)
                                         { 
                                         char *Zeilen[MAXANZ];
                                         int Anz;
                                         
                                         Anz=ZeilenEin(Zeilen,MAXANZ);
                                         printf("\n\n%d Zeilen gelesen\n\n",Anz);
                                         ZeilenAus(Zeilen,Anz);
                                        
                                         return(0);
                                         }
                                       

Das folgende Programmfragment zeigt, wie man Zeichenketten speichersparend verwalten kann. Es wird zunächst nur ein Array von Zeigern definiert. Beim Einlesen der Strings wird jeweils genügend Speicher allokiert und die Zeichenkette an einem Array-Element "aufgehängt".

                                       #include <stdio.h>
                                       #include <string.h>
                                       
                                       #define MAX 1000                       /* Maximalzahl Feldelemente */
                                       
                                       char *string_feld[MAX];                /* Feld mit String-Zeigern */
                                       int count;                             /* Anzahl der eingeg. Strings */
                                       
                                       int  einlesen(char *feld[]);           /* Eingabefunktion */
                                       void ausgabe(int anzahl,char *feld[]); /* Ausgabefunktion */
                                       
                                       int main(void)
                                         {
                                         count = einlesen(string_feld);
                                         ausgabe(count,string_feld);
                                         }
                                       
                                       int einlesen(char *feld[])
                                         /* Liest Strings auf die Variable feld ein, liefert Anzahl zurueck */
                                         {
                                         int anz;	                           /* Zaehler fuer Strings */
                                         char *ptr;                           /* Zeiger zum Pruefen auf EOF */
                                         char puffer[2000];                   /* Puffer fuer akt. String */
                                         anz = 0;
                                         do
                                           {
                                           ptr = gets(puffer);                /* String einlesen */
                                           if (ptr != NULL)                   /* EOF == (ptr == NULL) */
                                             {                                /* Platz reservieren */
                                             feld[anz] = (char *) malloc(strlen(puffer) + 1);
                                                                              /* einschl. '\0' am Ende */
                                             strcpy(feld[anz],puffer);          /* String in feld kopieren */
                                             anz++;                           /* Zaehler erhoehen */
                                             }
                                           }
                                         while (ptr != NULL);                 /* lesen bis EOF */
                                         return(anz);
                                         }
                                       
                                       void ausgabe(int anzahl,char *feld[])
                                         /* Ausgabe der Strings in feld, der Parameter gbt die Anzahl an */
                                         {
                                         int i;
                                         puts("\n");                          /* Leerzeile */
                                         for (i=0; i<anzahl; i++)
                                           puts(feld[i]);                     /* haengt \n automatisch an */
                                         }
                                       

Im letzten Beispiel wird dynamisch Speicherplatz für Objekte bereitgestellt, die den Datentyp double besitzen und die Form von ein- und zweidimensionalen Feldern haben. Die Größe der Felder, d. h. Zeilenzahl und Spaltenzahl der Matrix und Anzahl der Komponenten des Arrays werden erst zur Laufzeit des Programms eingelesen. Anschließend werden die eingelesenen Zahlenwerte als Matrixelemente, bzw. Arraykomponenten abgelegt und wieder ausgedruckt. Am Ende wird der bereitgestellte Speicherplatz wieder freigegeben.

   
                                       #include <stdio.h>
                                       #include <stdlib.h> 
                                       main()
                                         {
                                         double **a,    /* Eingabematrix */
                                                  *u;    /* Eingabevektor */
                                         int i,j,n,m;
                                       
                                         printf("Zeilenzahl m und Spaltenzahl n eingeben: ");
                                         scanf("%d %d", &m, &n);
                                        
                                         /*   Speicherplatz bereitstellen   */
                                         a = (double **) malloc (m*sizeof(double *));
                                         for (i=0; i<m; i++)
                                           a[i] = (double *) malloc (n*sizeof(double)); 
                                         u = (double *) malloc (n*sizeof(double));
                                       
                                         printf("%dx%d Matrix A eingeben\n", m, n);
                                         for(i=0; i<m; i++) 
                                           for(j=0; j<n; j++)
                                             scanf("%lf", &a[i][j]);
                                       
                                         printf("%d Vektor u eingeben\n", n);
                                         for(j=0; j<n; j++)
                                           scanf("%lf", &u[j]);
                                       
                                         printf("Eingabedaten: Matrix A\n");
                                         for(i=0; i<m; i++) 
                                           {
                                           for(j=0; j<n; j++)   
                                             printf("%f ", a[i][j]);
                                           printf("\n");
                                           }
                                       
                                         printf("Eingabedaten: Vektor u\n");
                                         for(j=0; j<n; j++)
                                           printf("%f ", u[j]);
                                         printf("\n");
                                        
                                         /*   Speicherplatz freigeben   */
                                         for (i=0; i<m; i++)
                                           free (a[i]);
                                         free (a);
                                         free (u);
                                         }
                                       
Hier zeigt a auf m Speicherplätze vom Datentyp (double *). Jeder dieser Speicherplätze a[i] ist selbst Zeiger auf n Speicherplätze vom Datentyp double. Ebenso zeigt u auf n Speicherplätze vom Datentyp double.

Zeiger und Strukturen

Im folgenden Beispiel wird eine Struktur für eine Adresse verwendet:
                                       struct kunde
                                         {
                                         int kundennr;
                                         char vorname[15];
                                         char nachname[20];
                                         char strasse [25];
                                         char plz[5];
                                         char ort[25];
                                         };
                                       
Im folgenden Programmbeispiel geht es darum, eine beliebige Zahl von Adressen einzulesen. Zur Speicherung wird kein Array verwendet, sondern ein zusammenhängender Speicherbereich, der dynamisch allokiert wird und über einen Pointer angesprochen werden kann. Dazu wird zuerst gefragt, wieviele Adressen eingegeben werden sollen und dementsprechnde Speicherplatz mit malloc() belegt.

Bei der Verwendung von Zeigern im Zusammenhang mit Strukturen wird häufig folgender Ausdruck benötigt, um auf eine einzelne Komponente zuzugreifen:

                                       (*zeiger).strukturkomponente
                                       
Dafür gibt es folgende abgekürzte Schreibweise:
                                       zeiger -> strukturkomponente
                                       
Die Zeichen - und > bilden einen Pfeil und bringen so sehr anschaulich das Zeigerkonzept zum Ausdruck.

Da wir nicht nur eine Strukturvariable haben, sondern (implizit) ein ganzes Feld, benötigen wir Schleifen zum Einlesen und Ausdrucken. Der Schleifenindex i beginnt bei 0 und wird so lange erhöht, bis die Anzahl der Kunden erreicht ist. Dieser Index muß zum Wert des Zeigers addiert werden, so daß Ausdrücke der Form

                                       (zeiger + i) -> strukturkomponente
                                       
entstehen. Hat i beispielsweise den Wert 3, dann wird der Wert 3 * sizeof(struct kunde) zum Zeiger addiert. Der Zeiger zeigt dadurch auf das drittnächste Element.
                                       int main(void)
                                         {
                                         struct kunde
                                           {
                                           int kundennr;
                                           char vorname[15];
                                           char nachname[20];
                                           char strasse [25];
                                           char plz[5];
                                           char ort[25];
                                           };
                                       
                                         char antwort,hilf[5];
                                         int i, anzahl;
                                         struct kunde *person;
                                       
                                         printf("Wie viele Kunden wollen Sie eintragen? ");
                                         scanf("%d",&anzahl); 
                                         gets(hilf); /* Liest RETURN-Zeichen, alternativ fflush(stdin) */
                                       
                                         /* Platz fuer anzahl kunden reservieren */
                                         person = (struct kunde *) malloc(anzahl * (sizeof(struct kunde)));
                                       
                                         printf("Geben Sie die Kundendaten ein:\n");
                                         for (i = 0; i < anzahl; i++)
                                           {
                                           printf("\nKundennummer: "); gets(hilf);
                                           (person+i)->kundennr = atoi(hilf);
                                           printf("\nVorname.....: "); gets((person+i)->vorname);
                                           printf("\nNachname....: "); gets((person+i)->nachname);
                                           printf("\nStraße: "); gets((person+i)->strasse);
                                           printf("\nPostleitzahl: "); gets((person+i)->plz);
                                           printf("\nWohnort.....: "); gets((person+i)->ort);
                                           }
                                       
                                         printf("\n\nSie haben folgende Daten eingegeben:\n");
                                         for (i = O; i < anzahl; i++)
                                           {
                                           printf("\nKundennummer: %d\n",(person+i)->kundennr);
                                           printf("%s %s\n",(person+i)->vorname,(person+i)->nachname);
                                           printf("%s\n",(person+i)->strasse);
                                           printf("%s %s\n",(person+i)->plz,(person+i)->ort);
                                           }
                                       
                                         return(0);
                                         }
                                       

Beispiel: Anwendung von Bibliotheksfunktionen. In time.h sind Funktionen und Strukturen zur Ermittlung von Datum und Uhrzeit enthalten. Für die Ausgabe braucht man einn Zeiger tp, der auf eine in time.h definierte Struktur tm zeigt.

                                       #include <stdio.h>
                                       #include <time.h>
                                       
                                       time_t zeitpunkt;  /* time_t definiert in time.h */
                                       struct tm *tp;     /* tm definiert in time.h */
                                       
                                       int main(void)
                                         {
                                         time(&zeitpunkt);           /* Uhrzeit und Datum im internen Format:
                                                                     /* Sekunden seit 1.1.1970 GMT */
                                         printf("%ld\n",zeitpunkt);  /* soviele sind es */
                                       
                                         tp=localtime(&zeitpunkt);   /* umwandeln im etwas Lesbareres */
                                       
                                         printf("Uhrzeit: %02d:%02d:%02d\n",
                                                 tp->tm_hour, tp->tm_min, tp->tm_sec);
                                       
                                         printf("Tag: %02d\n",tp->tm_mday);
                                         printf("Monat: %02d\n",tp->tm_mon+1);
                                         printf("Jahr: %04d\n",tp->tm_year+1900);
                                       
                                         return(0);
                                         }
                                       

Gefahren bei der Rückgabe von Zeigern

Bei Zeigern, die als Rückgabewert einer Funktion dienen, muß darauf geachtet werden, daß sie nicht alf lokale Objekte verweisen, die nach dem Funktionsaufruf verschwunden sind.

Negativ-Beispiel 1: Die lokale Variable existiert nur während des Funtionsaufrufs. Die Ausgabe ist unbestimmt, sie könnte zufällig auch 1234 lauten.

                                       int * murks(void)
                                         {
                                         int x = 1234;
                                       
                                         return(&x);
                                         }
                                       
                                       int main(void)
                                         {
                                         int * ip;
                                       
                                         ip = murks();
                                         printf("%d\n",*ip);
                                         }
                                       

Negativ-Beispiel 2: Die Funktion soll ein Duplikat des als Parameter übergebenen Strings erzeugen und einen Zeiger darauf zurückgeben. Der Speicherplatz für das lokale Feld neu wird jedoch beim Verlassen der Funktion wieder freigegeben und die Kopie zerstört.

                                       char * murks(char * txt)
                                         {
                                         char neu[100];
                                         char *n;
                                         
                                         n = neu;
                                         while ((*n++ = *txt++) != '\0'); /* kopieren */
                                         return(n);
                                         }
                                       
                                       int main(void)
                                         {
                                         char * strp;
                                       
                                         strp = murks("Autsch!");
                                         printf("%ds\n",strp);
                                         }
                                       

Besser wäre es, dynamisch Speicher zu allocieren und den Pointer zurückzugeben, dann entspricht die Funktion der Bibliotheksroutine strdup:

                                       char * kein_murks(char * txt)
                                         {
                                         char *n;
                                         
                                         n = (char *) malloc(strlen(txt) + 1);
                                         while ((*n++ = *txt++) != '\0'); /* kopieren */
                                         return(n);
                                         }
                                       
                                       int main(void)
                                         {
                                         char * strp;
                                       
                                         strp = kein_murks("So geht es!");
                                         printf("%ds\n",strp);
                                         }
                                       

DIPLOMARBEITEN UND BÜCHER

Diplomarbeiten zum Runterladen:

Suche im Katalog:
Architektur / Raumplanung
Betriebswirtschaft - Funktional
Erziehungswissenschaften
Geowissenschaften
Geschichtswissenschaften
Informatik
Kulturwissenschaften
Medien- und Kommunikationswissenschaften
Medizin
Psychologie
Physik
Rechtswissenschaft
Soziale Arbeit
Sozialwissenschaften


JOBS
HOME | E-LEARNING | SITEMAP | LOGIN AUTOREN | SUPPORT | FAQ | KONTAKT | IMPRESSUM
Virtual University in: Italiano - Français - English - Español
VirtualUniversity, WEB-SET Interactive GmbH, www.web-set.com, 6301 Zug

Partner:   Seminare7.de - PCopen.de - HTMLopen.de - WEB-SET.com - YesMMS.com - Ausbildung24.ch - Manager24.ch - Job und Karriere