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
pa = a; verwendet werden, wo auf der rechten Seite der Feldname a steht. Die einzelnen Elemente des Feldes a können auf drei verschiedene Weisen angesprochen werden:
                                          a[i]       i-tes Feldelement
                                          *(pa+i)    Pointer pa + i * (Laenge eines Elementes von a)
                                          *(a+i)     Arrayanfang + i * (Laenge eines Elementes von a)
                                       
a ist also in C äquivalent zu &a[0]. So kann man statt pa = &a[0] auch schreiben pa = a. Die Verwandtschaft zwischen Arrays und Pointern kann beim Programmieren recht praktisch und effizient sein, führt aber auch zu unsauberem Stil und unverständlichen Programmen.

Das folgende Beispiel soll die Äquivalenz von Arrays und Pointern etwas verdeutlichen:

                                       
                                       void arraytest(char x[])
                                         { /* Ersetzt im Array x alle 'e"' durch ".", 
                                              Array wird als Parameter uebergeben */
                                         int z;
                                       
                                         for (z = 0; x[z] != '\0'; z++)
                                           if (x[z] == 'e') x[z] = '.';
                                         } 
                                       
                                       
                                       void pointertest(char *px)
                                         { /* Ersetzt im Array x alle 'e"' durch ".",
                                              ein Pointer wird als Parameter uebergeben */
                                         int z;
                                       
                                         for (z = 0; *(px+z) != '\0'; z++)
                                           if (*(px+z) == 'e') *(px+z) = '.';
                                         } 
                                       

Beide Unterprogramme können mit einem Array als Parameter aufgerufen werden und liefern das gleiche Ergebnis.

Im folgenden Programmbeispiel werden die drei Möglichkeiten in der Anweisung printf einander gegenübergestellt:

   
                                       /* Zeiger und Felder */
                                       #include <stdio.h>
                                       int main(void)
                                         {
                                         int i, a[10] = {12, 23, 34, 35, 36, 37, 44, 46, 48, 50} ;
                                         int *pa;  
                                       
                                         pa = a;  /* oder: pa = &a[0]; */
                                         for (i=0; i<10; i++)
                                           printf("a[%d]= %d\t *(pa+%d)= %d\t *(a+%d)= %d\n", 
                                                     i, a[i], i, *(pa+i), i, *(a+i));
                                         }
                                       
Die Korrespondenz von Indizieren und Zeigerarithmetik ist daher sehr eng: Die Schreibweise pa + i bedeutet die Adresse des i-ten Objekts hinter demjenigen, auf welches pa zeigt. Es gilt:

Jeder Array-Index-Ausdruck kann auch als Pointer-Offset-Ausdruck formuliert werden und umgekehrt.

Der Ausdruck pa + i bedeutet nicht, daß zu pa der Wert i addiert wird, sondern i legt fest, wie oft die Länge des Objekt-Typs von pa addiert werden muß.

Es besteht jedoch ein gravierender Unterschied zwischen Array-Namen und Zeigern:

  • Ein Zeiger ist eine Variable, deren Wert jederzeit geändert werden darf, z.B.:
    	
                                              int x,*px;
                                              px = &x;     /* Veränderung ist jederzeit zulässig */
                                           
  • Ein Array-Name ist eine Zeiger-Konstante, ihr Wert ist nicht veränderbar! Z. B.:
                                              int z, y[5];
                                              y = &z;      /*  U n z u l ä s s i g */
                                           

Beispiel zur Verwandschaft zwischen Zeigern und Arrays: Äquivalente Formulierungen der Funktion strcopy()

                                       
                                       void strcopy(char strl[] ,char str2[]) 
                                         {
                                         int i=0;
                                         while((str1[i]=str2[i]) != '\0')
                                           i++;
                                         }
                                       
                                       void strcopy(char *strl ,char *str2) 
                                         {
                                         int i=0;
                                         while((str1[i]=str2[i]) != '\0')
                                       	i++;
                                         }
                                       
                                       void strcopy(char *strl ,char *str2) 
                                         {
                                         int i=0;
                                         while((*(str1+i)= *(str2+i)) != '\0')
                                       	i++;
                                         }
                                       
                                       
                                       void strcopy(char *strl ,char *str2) 
                                         {
                                         while((*str1 = *str2) != '\0') 
                                           {
                                       	str1++;
                                       	str2++;
                                       	}
                                         }
                                       
                                       void strcopy(char *strl ,char *str2) 
                                         {
                                         while (*str1++ = *str2++);
                                         }
                                       

Beispiel: Zeichenketten und Pointer:

                                       void main(void)
                                         {
                                         int   i = 0;
                                         char  zeichenKette1[]   = "Hier stehen ganz viele Zeichen",
                                               zeichenKette2[32] = {'D','i','e',' ','z','w','e','i','t','e',
                                                                    ' ','Z','e','i','c','h','e','n','k','e',
                                                                    't','t','e','\0'},
                                              *zeichenKette3     = "Heiter geht's weiter!",
                                              *zeichenPtr        = NULL;                           
                                                                
                                         printf("String 1: %s\n",zeichenKette1);
                                         printf("String 2: %s\n",zeichenKette2);
                                         printf("String 3: %s\n\n",zeichenKette3);
                                       
                                         printf("Zeichen 5 aus String 1: %c\n",zeichenKette1[5]);
                                         printf("String 1 ab Zeichen 5: %s\n\n", &zeichenKette1[5]);
                                       
                                         zeichenPtr = zeichenKette2;
                                       
                                         printf("ZeichenPtr     zeigt auf: %s\n",zeichenPtr);
                                         printf("ZeichenPtr + 4 zeigt auf: %s\n",zeichenPtr+4);
                                       
                                        for(i = 0; i < 24; i++)
                                          {
                                          printf("%c",*(zeichenPtr+i));
                                          }
                                        printf("\n\n");
                                        }
                                       

Ausgabe:

                                       String 1: Hier stehen ganz viele Zeichen
                                       String 2: Die zweite Zeichenkette
                                       String 3: Heiter geht's weiter!
                                       
                                       Zeichen 5 aus String 1: s
                                       String 1 ab Zeichen 5: stehen ganz viele Zeichen
                                       
                                       ZeichenPtr     zeigt auf: Die zweite Zeichenkette
                                       ZeichenPtr + 4 zeigt auf: zweite Zeichenkette
                                       Die zweite Zeichenkette
                                       

Im nächsten Programmbeispiel werden drei Versionen einer Funktion vom Datentyp int einander gegenübergestellt, die zur Ermittlung der Länge einer Zeichenkette dienen.

   
                                       #include <stdio.h>
                                       
                                       int strlen0(char s[]);
                                       int strlen1(char *s);
                                       int strlen2(char *s);
                                       
                                       int main(void) /* Laenge einer Zeichenkette ermitteln */
                                         {
                                         char name[51];
                                       
                                         printf("Zeichenkette mit max. 50 Zeichen eingeben:\n");
                                         scanf("%s",name);
                                         printf(" name: %s\n",name);
                                         printf("Laenge von name mit strlen0: %d\n",strlen0(name));
                                         printf("Laenge von name mit strlen1: %d\n",strlen1(name));
                                         printf("Laenge von name mit strlen2: %d\n",strlen2(name));
                                         }
                                       
                                       int strlen0(char s[])  /* liefert die Laenge von s */
                                          {
                                          int i;
                                          for (i = 0; s[i] != '\0'; i++)
                                            ;
                                          return i;
                                          }  
                                       
                                       int strlen1(char *s)  /* 1.Zeigerversion */
                                          {
                                          int i;
                                          for (i = 0; *s != '\0'; s++, i++)
                                            ;
                                          return i;
                                          }
                                            
                                       int strlen2(char *s)  /* 2.Zeigerversion */
                                          {
                                          char *p;
                                          for (p = s; *p != '\0'; p++)
                                            ;
                                          return p - s;
                                          }
                                       
Die Funktion strlen0 verwendet keine Zeiger und hat als Parameter ein Feld vom Datentyp char unbestimmter Länge. In der for Anweisung der Funktion strlen0 wird die Laufvariable i ausgehend vom Anfangswert Null solange inkrementiert, wie das i-te Zeichen der beim Aufruf übergebenen Zeichenkette vom Nullzeichen '\0' am Ende der Zeichenkette verschieden ist. Der Wert von i, für den s[i] gleich '\0' gilt, wird nicht mehr inkrementiert und über die return Anweisung als Länge der Zeichenkette an die rufende Funktion main zurückgegeben.

Die Funktionen strlen1 und strlen2 haben jeweils einen Zeiger auf den Datentyp char als Parameter. Wenn beim Aufruf von strlen1 eine Zeichenkette als Argument übergeben wird, wird die Adresse des ersten Elements übergeben, so daß der Zeiger s auf das erste Element der übergebenen Zeichenkette zeigt. In der for Anweisung von strlen1 wird geprüft, ob das Objekt, auf welches s zeigt, vom Nullzeichen am Ende der Zeichenkette verschieden ist. Ist dies nicht der Fall, werden der Zeiger s und die Laufvariable i inkrementiert. Durch die Inkrementierung von s weist diese Zeigervariable auf das nächste Element der beim Aufruf übergebenen Zeichenkette. Wenn aber der Zeiger s auf das Nullzeichen am Ende der Zeichenkette zeigt, findet keine Inkrementierung von s und i mehr statt. Der Wert von i wird durch die return Anweisung an main zurückgegeben.

In der Funktion strlen2 wird p als Zeiger auf den Datentyp char vereinbart. Im ersten Ausdruck in der for Anweisung wird p so initialisiert, daß p auf das erste Zeichen der als Argument übergebenen Zeichenkette zeigt. In der Schleifenbedingung wird geprüft, ob das Nullzeichen am Ende der Zeichenkette erreicht ist. Ist dies noch nicht der Fall, wird der Zeiger p inkrementiert, so daß er auf das nächste Element der Zeichenkette zeigt. Ist das Nullzeichen aber erreicht, findet eine Inkremetierung von p nicht mehr statt. Die Zeigerdifferenz p-s, die als Ergebnis zurückgegeben wird, gibt die Anzahl der Inkrementierungen von p an, also die Länge der Zeichenkette.

Das folgende Beispiel zeigt, wie man ein Array von Zeigern initialisieren kann:

                                       char *month_name(int n)
                                         {
                                         static char *name[] = {  /* Array von Zeigern */
                                           "falscher Monat",      /* Ein String ist ein char-Array */
                                           "Januar",              /* und daher durch seine */
                                           "Februar",             /* Anfangsadresse charakterisiert */
                                           "Maerz",
                                           "April",
                                           "Mai",
                                           "Juni",
                                           "Juli",
                                           "August",
                                           "September",
                                           "Oktober",
                                           "November",
                                           "Dezember"
                                           };
                                        
                                         return ((n < 1 || n > 12) ? name[0] : name[n]);
                                         }
                                       

Beispiel: Sortieren von n eingegebenen int-Werten
An die Sortierfunktion ssort werden nur zwei Zeiger übergeben, die auf das erste und letzte Element des Feldes zeigen. Innerhalb von ssort wird auch nur mit Zeigern gearbeitet.

                                       
                                       #include <stdio.h>
                                       #define MAX 100
                                       
                                       void ausgabe(char *text, int *feld, int m);
                                       void ssort(int *first, int *last);
                                       
                                       int main(void)
                                         {	
                                         int feld[MAX];
                                         int m, anz;
                                       
                                         printf("Eingabe von n int-Werten (unsortiert) - bis EOF\n");
                                         for (m = 0; m < MAX; m++) 
                                           { /* Einlesen bis EOF erreicht wurde
                                                 oder bis MAX Werte eingelesen wurden */
                                           anz = scanf("%d", &feld[m]);
                                           if (anz == EOF) break;
                                       	}	
                                         printf("\n");
                                       
                                         ausgabe("Unsortiert:",feld, m);
                                       
                                         ssort(&feld[0], &feld[m]);    
                                                    /* oder kuerzer: ssort(feld, &feld[m]); */
                                         
                                         ausgabe("Sortiert:",feld, m);
                                       
                                         return(0);
                                         }
                                       
                                       void ausgabe(char* text, int *feld, int m)
                                         { /* Array ausgeben */
                                         int j;
                                       
                                         printf("%s\n",text);
                                         for(j = 0; j < m; j++) 
                                           {
                                       	printf(" %6d\n", feld[j]);
                                           }
                                         printf("\n");
                                         }
                                           
                                       void ssort(	int *first, int *last)
                                         /* Sortieren durch direktes Einfuegen */
                                         {	
                                         int *i, *j, temp;
                                       
                                         for(i = first; i < last; i++) 
                                           {
                                           for(j = i-1; j >= first && *j > *(j+1); j--) 
                                             {	
                                             temp = *(j+1);
                                             *(j+1) = *j;
                                             *j = temp;
                                             }
                                           }
                                         }
                                       

Zeiger auf mehrdimensionale Arrays

Zur Erinnerung: bei statischer Speicherbelegung sind mehrdimensionale Arrays intern eindimensional angelegt, die Arrayzeilen liegen alle hintereinander. Definiert man beispielsweise

float matrix[N][M];

Dann berechnet sich die die Adresse von matrix[1][2] mit der Zeigerarithmetik zu:

Der letzte Ausdruck ist von der Form, wie er intern tatsächlich berechnet wird. Die Zeilenlänge M muß dem Compiler also explizit bekannt sein!

Alternative: Adressen zu den Zeilenanfängen können explizit abgespeichert werden.
Beispiel:

                                          int  aa[N][M], *a[N], i;
                                          for(i=0; i<N; i++)
                                             a[i] = aa[i];
                                       
ab dann nur noch Verwendung von a[k][l].

"echt 2-dimensional"; Adressen werden nicht berechnet, sondern nur gelesen; Zeilenlänge muß dazu nicht bekannt sein. Nachteil: es ist (geringfügig) mehr Speicherplatz nötig.

Zeiger auf Strukturen

Strukturpointer finden so häufig Verwendung, daß es dafür eine eigene Syntax gibt; bei gegebener Adresse auf eine Strukturvariable werden deren Elemente mit '->' angesprochen, in der Form:

Zeiger auf Strukturvariable ->Elementname

Beispiel: mit der Strukturdefinition

                                       struct point 
                                         {
                                         double  px, py;
                                         int  farbe;
                                         }  punkt, sprueh[100];
                                       
sind folgende Aufrufe äquivalent:

punkt.pxentspricht(&punkt)->px
sprueh[20].pxentspricht(sprueh+20)->px

Nun wird noch ein Zeiger auf punkt definiert:

                                       struct point *zeiger;
                                       
Mit der Anweisung zeiger = &punkt; kann man zeiger auf punkt zeigen lassen. Der Zugriff auf die Komponente px von punkt würde in reiner Pointerschreibweise lauten (erster Versuch):
                                       irgendwas = *zeiger.px;
                                       
Diese Notation ist aber zweideutig. Bedeutet das jetzt "Das worauf zeiger zeigt, Komponente px" oder "Das worauf zeiger.px zeigt"? Diese Zweideutigkeit wird man los durch (zweiter Versuch):
                                       irgendwas = (*zeiger).px;
                                       
Nun ist es eindeutig "Das worauf zeiger zeigt, Komponente px". Der Operator -> vereinfacht das nun nur noch und wir schreiben (Endfassung):
                                       irgendwas = zeiger->>px;
                                       

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