ThInf-HOME

  1. Einführung

  2. Datentyp 'struct'

  3. Felder und Zeiger als Argumente von Funktionen, Teil 2

  4. Anmerkung zu 'scanf'

  5. Anordnung der Feldelemente im Speicher

  6. Übungsaufgaben


I-PROGRAMMIEREN1 WS 0203 - Vorlesung mit Übung
VL5: Strukturen 1; Funktionen und Zeiger Teil 2


AUTHOR: Gerd Döben-Henisch
DATE OF FIRST GENERATION: Oct-27, 2002
DATE OF LAST CHANGE: Jan-16, 2003
EMAIL: Gerd Döben-Henisch



1. Einführung



START

2. Datentyp 'struct'

Mit dem Datentyp struct begegnet uns ein Datentyp, der innerhalb von C die interessanteste Möglichkeit bietet, um Gegenstände/ Objekte der realen Welt zu modellieren. Modellierung bedeutet grundsätzlich (siehe auch das Schaubild) eine Art Abbildung von Aspekten der realen Welt in ein formales Modell. Der Zugang zu den Aspekten der realen Welt wird grundsätzlich über Sensoren realisiert, die Eigenschaften der realen Welt in Eigenschaften ('features') der sensorisch ermittelten Welt transformieren. Gegenstände ('objects') sind in der Regel charakteristische Kombinationen von Eigenschaften.

Mit dem Datentyp struct bietet die Sprache C weitreichende Möglichkeiten, beliebige Eigenschaften zu definieren und diese in einer einzigen Datenstruktur zusammenzufassen.



STRUCTURE

MODELLIERUNG DURCH STRUKTUREN



Grundsätzlich gibt es zwei Möglichkeiten, mittels struct eine neue Datenstruktur einzuführen: mit und ohne typedef:

typedef struct { ... ELEMENTE ...} NAME;

struct cellobject { ... ELEMENTE ...} ;

wobei ELEMENT die Vereinbarung einer Variablen ist (siehe Beispiele in proto5.h)

Der Vorteil der Version mit 'typedef' ist, dass man den neuen Typ auch durch einen eigenen Namen kenntlich machen kann. Der Nachteil der ersten Version und der Vorteil der zweiten Version, man kann bei der Benutzung von typedef keine selbstbezüglichen Zeiger benutzen. Dies ist aber für viele interessante Datentypen unumgänglich (spätere Vorlesung).





/****************
 *
 * proto5.h
 *
 * author: gdh
 * first: oct-24,02
 * last: oct-28,02
 *
 *********************/

.....

  /* Deklarierung einer Struktur mit typedef*/
  /* OBJECT wird zur Abkürzung für die gesamte struct-Definition */

  typedef struct  {
    char name[40];
    char surface;
    int direction;
    int velocity;
    int smell;
    int energy;
  } OBJECT;             /* Typ OBJECT als Buendel von Eigenschaften */

 /* Deklarierung einer Struktur ohne typedef */


  struct  cellobject {

    char name[40];
    char surface;
    int direction;
    int velocity;
    int smell;
    int energy;
  } ;




Interessant ist dann, wie man mit diesen beiden neuen vereinbarten Typen Variablen einführen kann. Die nachfolgenden Beispiele aus dem Programm 'usage5.c' demonstrieren dies. Im Falle der Typeinführung mit 'typedef' genügt es, den neuen Namen OBJECT als Typangabe zu benutzen. Im anderen Fall muss man explizit 'struct cellobject' als Typangabe hinschreiben. Alle weiteren Massnahmen entsprechen der Situation, wenn man eine Vaiable neu vereinbart.







  /* Definition einer Variablen car vom Typ OBJECT mit Initialisierung */

  OBJECT car = { "vw", '1',2,1,2,1000 };


  /* Definition einer Variablen car vom Typ cellobject mit Initialisierung */

struct cellobject animal =   { "dog", '1',2,1,2,1000 };

/* Definition eines Arrays mit Elementen vom Typ OBJECT */

 OBJECT world[2];

 /* Definition eines arrays von Pointern auf Elemente vom Typ OBJECT */

 OBJECT *erde[2];


/* Definition eines Arrays mit Elementen vom Typ OBJECT mit  Initialisierung */

 OBJECT planet[2] = {
                                    { "mercedes", '4',2,1,2,1000},  /* Erstes Element */
                                    { "taifun", '5',2,1,2,1000 } /* Zweites Element */
                                  };




Wie man dann mit den Elememnten von Struktur-Objekten arbeiten kann, zeigt das Beispielprogramm usage5.c in seinem ersten Teil. Im Prinzip muss man sich nur zwei Dinge merken. Auf 'normale' Elemente eines Struktur-Objektes greift man mit dem Struktur-Element-Operator '.' zu, d.h. man benutzt den Namen der Strukturvariablen gefolgt von einem Punkt '.' und gefolgt von dem Namen des Elementes, dessen Wert man manipulieren will. Sei 'car' der Name eines Struktur-Objektes, dann würde man mit 'car.name' auf das Element 'name' des Struktur-Objektes 'car' zugreifen (siehe auch Beispiele in usage5.c).

Will man mittels eines Zeigers ('pointer') auf das Element 'name' von 'car' zugreifen, dann muss man einen Zeiger vom gleichen Typ definieren (z.B. OBJECT *p;), die Adresse des gewünschten Strukturobjektes übergeben (z.B. p = &car; ) und dann kann man mit dem speziellen Struktur-Element-Operator '->' für Zeiger auf das Element 'name' zugreifen (z.B. mit 'p->name') (siehe Beispiele in 'usage5.c').





/**************************
 *
 * usage5.c
 *
 * author: gdh
 * first: oct-24,02
 * last: oct-28, 02
 * idea: some simple functions to demonstrate the use
 *           of arrays or pointers as arguments of functions
 * compilation: gcc -o usage5 usgae5.c funktionen5.c
 * usage: usgae5
 *
 **********************************/

#include <stdio.h>
#include "proto5.h"

#define DIM1 3
#define DIM2 20

int main(void){

  .....

  /* Definition einer Variablen car vom Typ OBJECT mit Initialisierung */

  OBJECT car = { "vw", '1',2,1,2,1000 };


  /* Definition einer Variablen car vom Typ cellobject mit Initialisierung */

struct cellobject animal =   { "dog", '1',2,1,2,1000 };

/* Definition eines Arrays mit Elementen vom Typ OBJECT */

 OBJECT world[2];

 /* Definition eines arrays von Pointern auf Elemente vom Typ OBJECT */

 OBJECT *erde[2];


/* Definition eines Arrays mit Elementen vom Typ OBJECT mit  Initialisierung */

 OBJECT planet[2] = {
                                    { "mercedes", '4',2,1,2,1000},  /* Erstes Element */
                                    { "taifun", '5',2,1,2,1000 } /* Zweites Element */
                                  };

 /**ANFANG************ DATENTYP struct DEMOS **********************************************/


 /* Uebergabe der Adresse des ersten Elementes vom Array planet an den Pointer von erde */

 erde[0] = &planet[0];
 erde[0]->direction = 5; /* Zuweisung eines Wertes an ein Element von Array planet mittels Pointer */


 /* Initialisierung eines Array-Elementes durch andere Variablen */

 world[0] = car;               /* Kopiere komplettes Objekt */
strcpy(world[1].name,"irgendwas");




  /* Kontrollausdruck von  Strukturen */

/* OBJECT car */

  printf("OBJECT car name = %s\n",car.name);

  printf("OBJECT car surface = %c \n",car.surface);

  printf("OBJECT car direction = %d \n",car.direction);

  printf("OBJECT car velocity = %d \n",car.velocity);

  printf("OBJECT car smell = %d \n",car.smell);

  printf("OBJECT car energy = %d \n",car.energy);


  /* cellobject animal */

  printf(" cellobject animal name = %s\n",animal.name);


  printf(" cellobject animal surface = %c \n",animal.surface);

  printf(" cellobject animal direction = %d \n",animal.direction);

  printf(" cellobject animal velocity = %d \n",animal.velocity);

  printf(" cellobject animal smell = %d \n",animal.smell);

  printf(" cellobject animal energy = %d \n",animal.energy);

  /* Array  von elementen von Typ OBJECT */


  printf("OBJECT-Array world name = %s\n",world[0].name);

  printf(" OBJECT-Array world surface = %c \n", world[0].surface);

  printf(" OBJECT-Array world direction = %d \n", world[0].direction);

  printf(" OBJECT-Array world velocity = %d \n", world[0].velocity);

  printf(" OBJECT-Array world smell = %d \n", world[0].smell);

  printf(" OBJECT-Array world energy = %d \n", world[0].energy);

  /*------------*/

  printf("OBJECT-Array world name = %s\n",world[1].name);

  /*-------------*/


  printf("OBJECT-Array planet name = %s\n",planet[0].name);

  printf(" OBJECT-Array planet surface = %c \n", planet[0].surface);

  printf(" OBJECT-Array planet direction = %d \n", planet[0].direction);

  printf(" OBJECT-Array planet velocity = %d \n", planet[0].velocity);

  printf(" OBJECT-Array planet smell = %d \n", planet[0].smell);

  printf(" OBJECT-Array planet energy = %d \n", planet[0].energy);

  /* Array mit Pointern auf Objekte vom Typ OBJECT */

  printf("OBJECT-Pointer-Array erde name = %s\n",erde[0]->name);

  printf(" OBJECT-Pointer-Array erde surface = %c \n", erde[0]->surface);

  printf(" OBJECT-Pointer-Array erde direction = %d \n", erde[0]->direction);

  printf(" OBJECT-Pointer-Array erde velocity = %d \n", erde[0]->velocity);

  printf(" OBJECT-Pointer-Array erde smell = %d \n", erde[0]->smell);

  printf(" OBJECT-Pointer-Array erde energy = %d \n", erde[0]->energy);



 /**ENDE************ DATENTYP struct DEMOS *********************************************************************/
.....
return (0);

}






START

3. Felder und Zeiger als Argumente von Funktionen, Teil 2


Es soll heute nochmals das Thema der Felder und Zeiger als Argumente von Funktionen aus der letzten Vorlesung aufgegriffen und an prinzipiellen Beispielen vertieft werden.

In der Datei 'funktionen5.c' wurden zu diesem Zweck vier Funktionen definiert, deren Prototypen in der Datei 'proto5.h' zu finden sind.





/****************
 *
 * proto5.h
 *
 * author: gdh
 * first: oct-24,02
 * last: oct-28,02
 *
 *********************/

extern int f1(int [],int);

extern int f2(int *, int);

extern int f3(char [][20], int, int);

extern int f4(char *,int, int);

  .....



/****************
 *
 * funktionen5.c
 *
 * author: gdh
 * first: oct-24,02
 * last:-
 * idea: some simple functions to demonstrate the use
 *           of arrays or pointers as arguments of functions
 *
 ********************/

/*****************
 *
 * f1(int ar[], int dim)
 *
 *idea: ar[] is the name of a one-dimensional array and
 *         dim is the dimensionality
 *
 ********************/
int f1(int ar[], int dim){

  int i;

  i=0;

  printf("In f1() mit dim = %d\n",dim);

  while(i < dim){
    printf("%d = %d \n",i,ar[i]);
    i++;
  }

  return i;

}

/*****************
 *
 * f2(int *ap, int dim)
 *
 *idea: ap is the name of a pointer, which can point to a n-dimensional array and
 *         dim is the dimensionality of the first dimension
 *
 ********************/
int f2(int *ap, int dim){

int i;

  i=0;

  printf("In f2() %u = mit dim = %d\n",ap,dim);

  while(i < dim){
    printf("%d = %d \n",i,*(ap+i));
    i++;
  }

  return i;


}
/*****************
 *
 * f3(int ar[][4], int dim1, int dim2)
 *
 *idea: ar[][4] is the name of a two-dimensional array and
 *         dim1 is the dimensionality of the first dimension and
 *         dim2 is the dimensionality of the second dimension
 *
 ********************/
int  f3(char ar[][20], int dim1, int dim2){

int i;

  i=0;

  printf("In f3() mit %u = dim1 = %d und dim2 = %d \n",ar[0],dim1, dim2);

  while(i < dim1){
    printf("%d = %u = %s \n",i,ar+i,ar[i]);
    i++;
  }

  return i;



}

/*****************
 *
 * f4()
 *
 *idea: app is the name of a pointer, which can point to a n-dimensional array and
 *         dim1 is the dimensionality of  the first dimension and
 *         dim2 is the dimensionality of the second dimension
 *
 ********************/

int f4(char *app,  int dim1, int dim2){
int x,y;

  x = y = 0;

  printf("In f4() mit %u = dim1 = %d und dim2 = %d \n",app+(x*dim2),dim1, dim2);

  while(x < dim1){
    y=0;
      while( (y < dim2) && (*(app+(x*dim2)+y) != '\0') ){

    printf("<%d,%d> = %u = %c \n",x,y,app+(x*dim2)+y,*(app+(x*dim2)+y));
    y++;
      } /* End of y */

    x++;
  }/* End of x */

  return 1;


}






In der datei 'usage5.c' werden zwei Feldvaraiablen ('arrays') definiert: 'feld1' mit einer Dimension und 'feld2' mit zwei Dimensionen.

   
   int feld1[DIM1];
  char feld2[DIM1][DIM2];
 
  

In der Datei 'funktionen5.c' hat die Funktion 'f1()' als erstes Argument eine Feldvariable vom Typ des Feldes 'feld1', die Funktion 'f2()' dagegen hat als erstes Argument eine Zeigervariable vom Typ des Feldes 'feld1'.

int f1(int ar[], int dim)
int f2(int *ap, int dim)

Man sieht, dass sich die Übergabe der Werte an die beiden Funktionen beim Aufruf in 'usage5.c' nicht unterscheidet.

f1(feld1, DIM1);
f2(feld1, DIM1);

Der Name eines Feldes gilt intern als die Adresse des Feldes. Man muss also nicht eigens den Adressoperator '&' einsetzen. Man kann dies natürlich auch tun, dann muss man aber explizit das erste Element des Feldes angeben, da dies die Startadresse des Feldes enthält:

f2(&feld1[0], DIM1);

Während sich beim Aufruf der beiden Funktionen f1() und f2() kein Unterschied zeigt, so ergibt sich aber ein Unterschied in der Art und Weise, wie innerhalb der Funktionen f1() und f2() auf die Werte der Feldvariablen 'feld1' zugreifen: die Funktion f1() benutzt die Indexschreibweise eines Feldes

 printf("%d = %d \n",i,ar[i]);

und die Funktion f2() benutzt ihre Zeigervariable 'ap' und greift mittels Inhaltsoperator '*' sowie einem Offfset '+i' auf die Werte zu:

printf("%d = %d \n",i,*(ap+i));

'ap+i' bedeutet die Basisadresse des Feldes 'feld1', die in ap gespeichert ist, plus i-viele Elemente von der Basisadresse entfernt.

Die Funktionen f3() und f4() werden benutzt, um auf das 2-dimensionale Feld 'feld2' zuzugreifen. Die Funktion f3() benutzt als Argument wieder eine Feldvariable und f4() wieder einen Zeiger.

int  f3(char ar[][20], int dim1, int dim2)
int f4(char *app, int dim1, int dim2)

Dabei fällt auf, dass die Funktion f3() die Grösse der zweiten dimension explizit angeben muss; dies verlangt der Compiler. Dies gilt auch für den Prototypen:

extern int f3(char [][20], int, int);
extern int f4(char*, int, int);

Durch diese Notwendigkeit, die konkreten Grössen aller Dimensionen ab der zweiten Dimension bei der Funktionsdefinition explizit angeben zu müssen, erweist sich die Methode der Funktionsdefinition mittels Feldvariablen als Funktionsargumente als nicht sehr flexibel. Wie man sieht, kann man das Problem durch die Verwendung von Zeigern umgehen. Dabei sei bemerkt, dass die Grössenangaben in den Dimensionen der Feldvariablen innerhalb der Funktion f3 nicht direkt nutzbar sind! Will man explizit die Grösse einer Dimension in der Funktion benutzen, dann muss man die Grösse der Dimensionen über spezielle Variablen mitübergeben. Darin unterscheiden sich die Funktionen f3() und f4() also nicht.




 
/**************************
 *
 * usage5.c
 *
 * author: gdh
 * first: oct-24,02
 * last: oct-28, 02
 * idea: some simple functions to demonstrate the use
 *           of arrays or pointers as arguments of functions
 * compilation: gcc -o usage5 usgae5.c funktionen5.c
 * usage: usgae5
 *
 **********************************/

#include <stdio.h>
#include "proto5.h"

#define DIM1 3
#define DIM2 20

int main(void){

  int feld1[DIM1];
  char feld2[DIM1][DIM2];
  int i;

  .....
/**ANFANG*********************** FELDER und ZEIGER als ARGUMENTE von FUNKTIONEN ********************************/
 

  printf("\nBitte geben Sie drei Zahlen ein z1, z2, z3 \n");

  /* Achtung: eine-Zeichenkettenvariable bekommt keinen (!) Adressoperator, wohl aber die einzelnen
   * Elemente eines Feldes
   */

  scanf("%d,%d,%d", &feld1[0],  &feld1[1], &feld1[2]);

i=0;
while( i < DIM1 ){
printf("\n Feld-Nr. %d = %d \n",i,feld1[i]);
i++;
}

 printf("Bitte geben Sie drei Woerter ein: \n");
 getchar();

 printf("Wort Nr.1 : ");
 fgets(feld2[0],DIM2-2,stdin);
 printf("\n\nWort Nr.2 : ");
 fgets(feld2[1],DIM2-2,stdin);
 printf("\n\nWort Nr.3 : ");
 scanf("%s",feld2[2]);

printf("Aufruf von f1() \n");
f1(feld1, DIM1);

printf("Aufruf von f2() \n");
 f2(feld1, DIM1);        /* Name eines Feldes impliziert seine Adresse */

printf("Zweiter Aufruf von f2() \n");
f2(&feld1[0], DIM1);     /* Angabe eines konkreten Feldes verlangt explizit den
                          * Adressoperator '&' */


printf("Aufruf von f3() \n");
f3(feld2, DIM1, DIM2);


printf("Zweiter Aufruf von f3() \n");
f3(&feld2[0], DIM1, DIM2);


printf("Aufruf von f4() \n");
f4(&feld2[0][0], DIM1, DIM2);

/**ENDE*********************** FELDER und ZEIGER als ARGUMENTE von FUNKTIONEN ********************************/
return (0);

}






START

4. Anmerkung zu 'scanf'


Bei der Funktion scanf() gilt als generelle Regel, dass diejenigen Variablen, in die hinein die von scanf() gescannten Eingaben abgespeichert werden sollen, mit einem Adressoperator zu versehen sind, da die Funktion die Adressen der Variablen erwartet, z.B.:

scanf("%d,%d,%c", &x,  &y, &aba);

Von dieser Regel gibt es aber eine Ausnahme, nämlich dann, wenn man den Namen einer Feldvariablen angibt. Der Name einer Feldvariablen wird intern vom Compiler sowieso als Adresse gehandelt, z.B. mit der Feldvariablen 'str' vom Typ char:

scanf("%s",str);

Es fragt sich dann, wie sind die Elemente von Feldvariablen zu behandeln? Hier muss man dann einfach wissen, dass die Elemente von Feldvariablen wieder den Adressoperator brauchen.

scanf("%d,%d,%d", &feld1[0],  &feld1[1], &feld1[2]);

Allerdings mit der sehr speziellen Ausnahme, dass solche Elemente von Feldvariablen, die selbst wieder Stringvariablen sind, keinen Adressoperator benötigen, wie etwa in der 2-dimensionalen Feldvariablen 'feld2', in der jedes Element eine Stringvariable ist:

scanf("%s",feld2[2]);



START

5. Anordnung der Feldelemente im Speicher


Als letztes sei mit der Datei 'feldmulti1.c' ein Beispiel gegeben, das zeigt, wie die Elemente eines 3-dimensionalen Feldes im Speicher abgelegt werden. Die Feldvariable 'ar1' hat 2 Dimensionen mit 3 Elementen, von denen jedes wieder 4 Elemente hat. Diese Feldvariable wird zu Beginn mit einer festen Zahlenfolge initialisiert. Schon an der Wertzuweisung kann man grob erkennen, wie die Werte den Elementen des Feldes zugeordnet werden.

Gesondert sei darauf hingewiessen, dass die Übergabe der Adresse an eine Funktion über einen Zeiger auf zweierlei Weise geschehen kann (siehe beispiel).





/*************************
//
// feldmulti1.c
//
// first: april-10, 2002
// last: jan-16,03
//
// compile: gcc -o feldmulti1 feldmulti1.c
// usage: feldmulti1
//
//*******************************/

#include <stdio.h>

#define dim1 2
#define dim2 3
#define dim3 4

int main(){


  int x,y,z;                                     /* Indexvariablen für die for-Schleifen */


  int  ar1[dim1][dim2][dim3]={         /* 3-dimensionales Feld mit 2*3*4 Elementen = 24 Elementen */
                            {
			      {1,2,3,4},
			      {5,6,7,8},
			      {9,10,11,12},
			    },
                            {
			      {13,14,15,16},
			      {17,18,19,20},
			      {21,22,23,24},
                              }
  };

 for( x=0; x<2; x++){

    for( y=0; y<3; y++){

    for( z=0; z<4; z++){
      printf("<%d , %d , %d> = ADR = %u = %d = %d = %d \n", x,y,z, &ar1[x][y][z], ar1[x][y][z], f3(ar1, x, y, z, dim1, dim2, dim3), f4(&ar1[0][0][0], x, y, z, dim1, dim2, dim3));

    }/* End of z-loop */
    }/* End of y-loop*/
 }/* End of x-loop*/

  return (0);
}

/*********************
 *
 * f3()
 *
 * Demofunktion: Uebergabe eines 3D-Feldes mittels Zeiger
 * an eine Funktion
 * Strukturinformation im Zeiger!
 ********************************/

int f3(int ***intp, int x, int y, int z, int d1, int d2, int d3){

     return (int) *(intp+(x*d2*d3)+(y*dim3)+z);



}
/*********************
 *
 * f4()
 *
 * Demofunktion: Uebergabe eines 3D-Feldes mittels Zeiger
 * an eine Funktion
 * Strukturinformation im Argument!
 ********************************/

int f4(int *intp, int x, int y, int z, int d1, int d2, int d3){

     return  *(intp+(x*d2*d3)+(y*dim3)+z);



}





Lässt man sich die Adressen aller Feldelemente samt Werten ausdrucken, dann sieht man, dass das 3-dimensionale Feld sequentiell angeordnet ist. Die Anordnung beginnt mit der Adresse [0][0][0] und folgt dann einer Erhöhung der Adressen von 'innen' nach 'aussen' (nebenbei erkennt man daran, dass der datentyp 'int' pro Wert 4 Bytes benutzt):



gerd@goedel:~/WEB-MATERIAL/fh/I-PROGR1/I-PROGR1-TH/VL5> ./feldmulti1
<0 , 0 , 0> = ADR = 3221222188 = 1 = 1 = 1
<0 , 0 , 1> = ADR = 3221222192 = 2 = 2 = 2
<0 , 0 , 2> = ADR = 3221222196 = 3 = 3 = 3
<0 , 0 , 3> = ADR = 3221222200 = 4 = 4 = 4
<0 , 1 , 0> = ADR = 3221222204 = 5 = 5 = 5
<0 , 1 , 1> = ADR = 3221222208 = 6 = 6 = 6
<0 , 1 , 2> = ADR = 3221222212 = 7 = 7 = 7
<0 , 1 , 3> = ADR = 3221222216 = 8 = 8 = 8
<0 , 2 , 0> = ADR = 3221222220 = 9 = 9 = 9
<0 , 2 , 1> = ADR = 3221222224 = 10 = 10 = 10
<0 , 2 , 2> = ADR = 3221222228 = 11 = 11 = 11
<0 , 2 , 3> = ADR = 3221222232 = 12 = 12 = 12
<1 , 0 , 0> = ADR = 3221222236 = 13 = 13 = 13
<1 , 0 , 1> = ADR = 3221222240 = 14 = 14 = 14
<1 , 0 , 2> = ADR = 3221222244 = 15 = 15 = 15
<1 , 0 , 3> = ADR = 3221222248 = 16 = 16 = 16
<1 , 1 , 0> = ADR = 3221222252 = 17 = 17 = 17
<1 , 1 , 1> = ADR = 3221222256 = 18 = 18 = 18
<1 , 1 , 2> = ADR = 3221222260 = 19 = 19 = 19
<1 , 1 , 3> = ADR = 3221222264 = 20 = 20 = 20
<1 , 2 , 0> = ADR = 3221222268 = 21 = 21 = 21
<1 , 2 , 1> = ADR = 3221222272 = 22 = 22 = 22
<1 , 2 , 2> = ADR = 3221222276 = 23 = 23 = 23
<1 , 2 , 3> = ADR = 3221222280 = 24 = 24 = 24

Dieser Sachverhalt sei auch nochmals an einem Bild erläutert:



feldmulti

ANORDNUNG VON FELDELEMENTEN IM SPEICHER





START


6. Übungsaufgaben

  1. Bilden sie ein Team von 3 Mitgliedern


  2. Erstellung Sie gemeinsam einen Texte mit Namen und Matr.Nr. der AutorenInnen. Abgabe einer Kopie des Textes an den Dozenten vor Beginn der Vorlesung am Di (1 Woche nach Aufgabenstellung). Falls die Aufgabe ausführbaren Programmcode enthält wäre die zusätzliche Übergabe des Quelltextes auf Diskette oder per email wünschenswert, aber nicht verbindlich. Im Falle von Programmcode muss im Programmtext auch nochmals Name und Matr.Nr. erscheinen.


  3. Präsentation der Lösung als Team vor der gesamten Gruppe. Präsentationszeit (abhängig von der Gesamtzahl der Teams) 3-5 Min. Mögliche Punkte: 1-2 im Normalfall. Bei besonders guten Leistungen bis zu 3 Punkten.


  4. Versuchen Sie in dem Text Antworten auf folgende Aufgaben zu formulieren:


  5. Schreiben Sie ein kleines Programm, das folgende Benutzerschnittstelle bereitstellt:

    1. Sie können Namen (Vorname und Familienname), Telefonnummern und email-Adresse von Personen eingeben

    2. Sie können sich die Liste anzeigen lassen

    3. Sie können über die einzelnen Elemente in der Liste suchen lassen


  6. Zur Erstellung des Programms können Sie auch Funktionen aus der Headerdatei <string.h> verwenden.


START