Rheinwerk Computing < openbook > Rheinwerk Computing - Professionelle Bücher. Auch für Einsteiger.
Professionelle Bücher. Auch für Einsteiger.

Inhaltsverzeichnis
Vorwort
Vorwort des Gutachters
1 Einstieg in C
2 Das erste Programm
3 Grundlagen
4 Formatierte Ein-/Ausgabe mit »scanf()« und »printf()«
5 Basisdatentypen
6 Operatoren
7 Typumwandlung
8 Kontrollstrukturen
9 Funktionen
10 Präprozessor-Direktiven
11 Arrays
12 Zeiger (Pointer)
13 Kommandozeilenargumente
14 Dynamische Speicherverwaltung
15 Strukturen
16 Ein-/Ausgabe-Funktionen
17 Attribute von Dateien und das Arbeiten mit Verzeichnissen (nicht ANSI C)
18 Arbeiten mit variabel langen Argumentlisten – <stdarg.h>
19 Zeitroutinen
20 Weitere Headerdateien und ihre Funktionen (ANSI C)
21 Dynamische Datenstrukturen
22 Algorithmen
23 CGI mit C
24 MySQL und C
25 Netzwerkprogrammierung und Cross–Plattform-Entwicklung
26 Paralleles Rechnen
27 Sicheres Programmieren
28 Wie geht’s jetzt weiter?
A Operatoren
B Die C-Standard-Bibliothek
Stichwort

Buch bestellen
Ihre Meinung?

Spacer
<< zurück
C von A bis Z von Jürgen Wolf
Das umfassende Handbuch
Buch: C von A bis Z

C von A bis Z
3., aktualisierte und erweiterte Auflage, geb., mit CD und Referenzkarte
1.190 S., 39,90 Euro
Rheinwerk Computing
ISBN 978-3-8362-1411-7
Pfeil 11 Arrays
Pfeil 11.1 Arrays deklarieren
Pfeil 11.2 Initialisierung und Zugriff auf Arrays
Pfeil 11.2.1 Gültigkeitsbereich von Arrays
Pfeil 11.3 Arrays vergleichen
Pfeil 11.4 Anzahl der Elemente eines Arrays ermitteln
Pfeil 11.5 Übergabe von Arrays an Funktionen
Pfeil 11.6 Arrays aus Funktionen zurückgeben
Pfeil 11.7 Programmbeispiel zu den Arrays
Pfeil 11.8 Einlesen von Array-Werten
Pfeil 11.9 Mehrdimensionale Arrays
Pfeil 11.9.1 Mehrdimensionale Arrays initialisieren
Pfeil 11.9.2 Übergabe von zwei- bzw. mehrdimensionalen Arrays an Funktionen
Pfeil 11.10 Arrays in Tabellenkalkulation einlesen (*.CSV–Dateien)
Pfeil 11.11 Strings/Zeichenketten (»char«-Array)
Pfeil 11.11.1 Vom String zur Binärzahl
Pfeil 11.12 Einlesen von Strings
Pfeil 11.13 Die Standard-Bibliothek <string.h>
Pfeil 11.13.1 »strcat()« – Strings aneinanderhängen
Pfeil 11.13.2 »strchr()« – ein Zeichen im String suchen
Pfeil 11.13.3 »strcmp()« – Strings vergleichen
Pfeil 11.13.4 »strcpy()« – einen String kopieren
Pfeil 11.13.5 »strcspn()« – einen Teilstring ermitteln
Pfeil 11.13.6 »strlen()« – Länge eines Strings ermitteln
Pfeil 11.13.7 »strncat()« – String mit n Zeichen aneinanderhängen
Pfeil 11.13.8 »strncmp()« – n Zeichen von zwei Strings miteinander vergleichen
Pfeil 11.13.9 »strncpy()« – String mit n Zeichen kopieren
Pfeil 11.13.10 »strpbrk()« – nach dem Auftreten bestimmter Zeichen suchen
Pfeil 11.13.11 »strrchr()« – das letzte Auftreten eines bestimmten Zeichens im String suchen
Pfeil 11.13.12 »strspn()« – das erste Auftreten eines Zeichens, das nicht vorkommt
Pfeil 11.13.13 »strstr()« – einen String nach dem Auftreten eines Teilstrings durchsuchen
Pfeil 11.13.14 »strtok()« – einen String anhand bestimmter Zeichen zerlegen


Rheinwerk Computing - Zum Seitenanfang

11.9 Mehrdimensionale Arrays Zur nächsten ÜberschriftZur vorigen Überschrift

Arrays, wie sie bisher besprochen wurden, können Sie sich als einen Strang von hintereinander aufgereihten Zahlen vorstellen. Man spricht dann von eindimensionalen Arrays oder Feldern. Es ist aber auch möglich, Arrays mit mehr als nur einer Dimension zu verwenden:

int Matrix[4][5];    /* Zweidimensional - 4 Zeilen x 5 Spalten */

Hier wurde z. B. ein zweidimensionales Array mit dem Namen Matrix definiert. Dies entspricht im Prinzip einem Array, dessen Elemente wieder Arrays sind. Sie können sich dieses Feld wie bei einer Tabellenkalkulation vorstellen (siehe Abbildung 11.6).

Abbildung 11.6 Ein zweidimensionales Array (4 Zeilen × 5 Spalten)


Rheinwerk Computing - Zum Seitenanfang

11.9.1 Mehrdimensionale Arrays initialisieren Zur nächsten ÜberschriftZur vorigen Überschrift

Werte bei mehrdimensionalen Arrays werden ähnlich übergeben wie bei einem eindimensionalen Array. Hier sehen Sie zum Beispiel eine Deklaration mit sofortiger Initialisierung von Werten:

/* 4 Zeilen 5 Spalten */
int Matrix[4][5] = { {10,20,30,40,50},
                     {15,25,35,45,55},
                     {20,30,40,50,60},
                     {25,35,45,55,65}};

Dadurch ergibt sich die Belegung des Feldes, die Sie in Abbildung 11.7 sehen.

Abbildung 11.7 Ein zweidimensionales Array, mit Werten initialisiert

Wie bei den normalen Arrays lassen sich die einzelnen Elemente mithilfe des Feldindex initialisieren. Wollen Sie beispielsweise das Element mit dem Wert 60 in 100 ändern, dann geht das wie folgt:

Matrix[2][4] = 100;

Hier wurde zum Beispiel der Inhalt von Matrix[2][4] verändert. Wollen Sie das Element mit dem Wert 65 in 66 umändern, dann wird folgender Feldindex verwendet:

Matrix[3][4] = 66;

Eine weitere Möglichkeit zur Initialisierung von mehrdimensionalen Arrays ist folgende:

int Matrix[4][4] = { {0},
                     {1},
                     {0,1},
                     {0,0,1} };

Hiermit besitzen alle Feldelemente, die nicht ausdrücklich initialisiert wurden, automatisch den Wert 0. Die Belegung des Feldes sieht also so aus wie in Abbildung 11.8.

Abbildung 11.8 Ein zweidimensionales Array (4 × 4)

In der Praxis werden mehrdimensionale Arrays bei verschiedensten Arten von Berechnungen benötigt oder bei 2D-Darstellungen von Grafiken. Das folgende Programm demonstriert die Anwendung eines mehrdimensionalen Arrays:

/* md_array1.c */
#include <stdio.h>
#include <stdlib.h>

#define VOL1 3   /* Anzahl Felder erste Dimension - Zeilen   */
#define VOL2 4   /* Anzahl Felder zweite Dimension - Spalten */

int main(void) {
   int i,j;
   int myarray[VOL1][VOL2];     /* [3][4] */

   /* Eingabe der Array-Elemente */
   for(i=0; i < VOL1; i++) {
      for(j=0; j < VOL2; j++) {
         printf("Wert für myarray[%d][%d]:", i, j);
         scanf("%d", &myarray[i][j]);
      }
   }
   printf("\nAusgabe von myarray[%d][%d]...\n\n", VOL1, VOL2);
   for(i=0; i < VOL1; i++) {
      for(j=0; j < VOL2; j++) {
         printf("\t%4d ",myarray[i][j]);
      }
      printf("\n\n");
   }
   return EXIT_SUCCESS;
}

Das Programm tut nichts anderes, als den Anwender nach Ganzzahlen abzufragen, um diese Werte im zweidimensionalen Array zu speichern und wieder auszugeben. Um dies zu realisieren, wird eine äußere und innere for-Schleife verwendet. Die äußere for-Schleife dient dabei zur Inkrementierung der Variablen im linken Indizierungsoperator (oder, aus der Sicht einer Tabellenkalkulation, in der Zeile). Die innere for-Schleife inkrementiert den Wert im rechten Indizierungsoperator (und somit in der Spalte).

Im nächsten Beispielprogramm soll ein kleines Zeitkonto für einen Arbeitgeber verwaltet werden. Damit sollen einige Arbeitszeitberechnungen durchgeführt werden.

/* md_array2.c */
#include <stdio.h>
#include <stdlib.h>

#define ARBEITER 3
#define TAGE     5

int zeitkonto[ARBEITER][TAGE];

/* Fehlerausgabe */
void error(int n) {
   printf("%d (?) Falsche Eingabe!!\n",n);
}

/* -1- Ausgabe der Wochenarbeitszeit je Arbeiter */
void ArbeiterWochenStunden(void) {
   int i,j,tmp;

   for(i=0; i < ARBEITER; i++) {
      tmp=0;
      printf("Wochenarbeitszeit von Arbeiter Nr. %d\n", i+1);
      printf("-------------------------------------\n");
      for(j=0; j < TAGE; j++) {
         printf("|%d Std.", zeitkonto[i][j]);
         tmp += zeitkonto[i][j];
      }
      printf("| = Ges. %d Std.\n\n",tmp);
   }
}

/* -2- Durchschnittszeiten pro Tag in der Woche je Arbeiter */
void ArbeiterTagesDurchschnitt(void) {
   int i,j,tmp;

   for(i=0; i < ARBEITER; i++) {
      tmp=0;
      printf("Durchschn. pro Tag/Woche Arbeiter: %d\n",i+1);
      printf("-------------------------------------------\n");
      for(j=0; j < TAGE; j++) {
         tmp+=zeitkonto[i][j];
      }
      printf("Durchschn. v. Arbeiter %d p. Tag: %.1f "
             "Std/Tag\n\n" , i+1, (float)tmp / TAGE);
   }
}

/* -3- Durchschnittszeit aller Arbeiter pro Tag */
void TeamTagesDurchschnitt(void) {
   int i,j,tmp;

   for(i=0; i < TAGE; i++) {
      tmp=0;
      printf("Durchschn. Arbeitszeit aller Mitarbeiter pro "
             "Tag %d = ", i+1);
      for(j=0; j < ARBEITER; j++) {
         tmp += zeitkonto[j][i];
      }
      printf("%.1f Std.\n\n",(float)tmp/ARBEITER);
   }
}

/* -4- Gesamtstunden aller Arbeiter in der Woche */
void TeamWochenStunden(void) {
   int i, j, tmp=0;

   printf("Gesamtstunden aller Arbeiter in der Woche\n");
   printf("-----------------------------------------\n");
   for(i=0; i < ARBEITER; i++) {
      for(j=0; j < TAGE; j++) {
         tmp+=zeitkonto[i][j];
      }
   }
   printf("Gesamtstunden aller Arbeiter i. d. Woche: "
          " %d Std.\n" , tmp);
}

/* Stundenübersicht eines einzelnen Arbeiters */
void ArbeiterStundenUebersicht(void) {
   int arb,tag;

   printf("Welcher Arbeiter: ");
   scanf("%d", &arb);
   printf("Welcher Tag: ");
   scanf("%d", &tag);
   if(arb > ARBEITER) {
      printf("Die Firma hat nur %d Arbeiter\n", ARBEITER);
      return;
   }
   else if(tag > TAGE) {
      printf("Es werden nur %d Tage gespeichert\n", TAGE);
      return;
   }
   printf("Arbeiter Nr.%d hat am Tag %d : ", arb, tag);
   printf("%d Stunden gearbeitet!\n\n", zeitkonto[arb-1][tag-1]);
}

int main(void) {
   int abfrage, i, j;

   for(i=0; i < TAGE; i++) {
      printf("\n\tTag %d in der Woche\n",i+1);
      printf("\t-------------------\n\n");
      for(j=0; j < ARBEITER; j++) {
         printf("Arbeiter Nr.%d in Std.: ",j+1);
         scanf("%d",&zeitkonto[j][i]);
         if(zeitkonto[j][i] > 24)
            printf("Ein Tag hat nur 24 Stunden?\n");
      }
   }
   do {
      printf("\n\n");
      printf("\t-1- Stundenwoche\n");
      printf("\t-2- Durchschnitt/Tag\n");
      printf("\t-3- Durchschnitt aller Arbeiter/Tag\n");
      printf("\t-4- Stunden aller Arbeiter/Woche\n");
      printf("\t-5- Einzelauswahl eines Arbeiters\n");
      printf("\t-6- ENDE\n");
      printf("\n\tIhre Wahl : ");
      scanf("%1d",&abfrage);
      printf("\n");

      switch(abfrage) {
         case 1  : ArbeiterWochenStunden();
                   break;
         case 2  : ArbeiterTagesDurchschnitt();
                   break;
         case 3  : TeamTagesDurchschnitt();
                   break;
         case 4  : TeamWochenStunden();
                   break;
         case 5  : ArbeiterStundenUebersicht();
                   break;
         case 6  : break;
         default : error(abfrage);
      }
   } while(abfrage != 6);
   return EXIT_SUCCESS;
}

Die Bildschirmausgabe des Programms könnte zum Beispiel so aussehen wie in Abbildung 11.9.

Es fällt auf, dass die Funktionen immer in etwa gleich aufgebaut sind. Auf eine entsprechende korrekte Feldindexierung muss natürlich geachtet werden. In der Funktion ArbeiterStundenUebersicht() wird demonstriert, wie gezielt auf ein Element eines Arrays zugegriffen werden kann. Das Programm ist natürlich noch verbesserungswürdig. Warnungen, dass ein Arbeiter zu viel oder zu wenig arbeitet, die Information, ob ein Arbeiter krank war, oder die Anweisung, dass Stunden als Gleitpunktzahlen angegeben werden sollen, sind nur einige Vorschläge dazu.

Abbildung 11.9 Die Stundenverwaltung des Personals in Aktion

Tatsächlich sind Arrays zwar sehr komfortabel in der Anwendung, sie sind jedoch sehr unflexibel, was die Anzahl der Elemente angeht. Die Anzahl der Elemente muss zum Zeitpunkt der Implementierung schon festgelegt werden, da sich ein Feld nicht ohne Mehraufwand dynamisch zur Laufzeit des Programms vergrößern oder verkleinern lässt.

Das bedeutet, dass die Menge der im Array zu speichernden Daten schon vor Ablauf des Programms bekannt sein oder zumindest überdimensioniert werden muss.

Wenn das Array im vorgestellten Beispiel für 1000 Mitarbeiter dimensioniert würde, wäre das Programm nicht mehr benutzbar, sobald mehr als 1000 Mitarbeiter verwaltet werden sollen.

Eine Lösungsmöglichkeit besteht darin, das Array sehr groß zu dimensionieren, um von vornherein sehr große Grenzen vorzugeben, etwa MitarbeiterArray[100000].

Dieser Ansatz kostet aber sehr viel (möglicherweise) ungenutzten Arbeitsspeicher, der das Programm unter Umständen stark verlangsamt.

Da aus Performance-Gründen generell stets möglichst wenig Arbeitsspeicher von Programmen belegt werden soll, gelten Arrays bei großen Datenmengen oder bei stark wechselnder Anzahl der Daten als nicht so effizient wie etwa verkettete Listen.

In Kapitel 21, »Dynamische Datenstrukturen«, gehe ich auf die Datenverwaltung mit verketteten Listen näher ein.

Tic Tac Toe

Ein weiteres interessantes Beispiel zur Demonstration von zweidimensionalen Arrays ist das wohl allseits bekannte Spiel »Tic Tac Toe«. Sie benötigen dabei lediglich ein Kästchen von 3 × 3 Feldern. Dies lässt sich prima mit einem zweidimensionalen Array darstellen: Sie verwenden eine Dimension für die Reihe und eine weitere für die Spalte.

char TicTacToe[3][3] = { {' ',' ',' '},
                         {' ',' ',' '},
                         {' ',' ',' '} };

Ein kurze Beschreibung des Spiels: Ein Spieler hat das Zeichen X und ein anderer das Zeichen O. Nach einem Zug ist der andere Spieler an der Reihe. Gewonnen hat der Spieler, der zuerst drei gleiche Zeichen (X oder O) in der Waagerechten, in der Senkrechten oder in der Diagonalen hat. Es gibt insgesamt acht Stellungsmöglichkeiten, um das Spiel zu gewinnen. Diese gilt es zu überprüfen. Es gibt außerdem noch eine neunte Möglichkeit, nämlich die, dass alle Felder besetzt sind, aber keiner der beiden Spieler gewonnen hat. Hier ist der vollständige Quellcode dazu:

/* tictactoe.c */
#include <stdio.h>
#include <stdlib.h>
#ifdef __unix__
    #define clrscr() printf("\x1B[2J")
#elif __BORLANDC__ && __MSDOS__
    #include <conio.h>
#elif __WIN32__ || _MSC_VER
    #define clrscr() system("cls")
#else
    #define clrscr() printf("clrscr() - Fehler!!\n")
#endif

#define X 'X'
#define O 'O'
#define LEER ' '
#define GAME_OVER 0
#define A_WINNER 1
#define CONTINUE 2

/* Inhalt des 3 x 3 großen Felds */
char TicTacToe[3][3] = { {' ',' ',' '},
                         {' ',' ',' '},
                         {' ',' ',' '} };
/* Spieler1 hat das Zeichen 'X'. */
char Spieler1 = X;
/* Spieler2 hat das Zeichen 'O'. */
char Spieler2 = O;
/* Anzahl der Felder, die besetzt werden können */
unsigned int felder = 9;

/* Funktionsprototypen */
void print_spielfeld(void);
char neuer_zug(char);
int if_win(void);

/* Gibt den aktuellen Zustand des Spielfelds aus. */
void print_spielfeld(void) {
   int i;

   clrscr();
   printf("       1   2   3  \n     +---+---+---+\n");
   for(i = 0; i < 3; i++) {
      printf("  %d  | ",i+1);
      printf("%c",TicTacToe[i][0]);
      printf(" | ");
      printf("%c",TicTacToe[i][1]);
      printf(" | ");
      printf("%c",TicTacToe[i][2]);
      printf(" | \n");
      if(i != 2) {
         printf("     +---+---+---+\n");
      }
      else {
         printf("     +---+---+---+\n");
      }
   }
}
/* Führt einen neuen Zug aus.
 * char ch: Zeichen des Spielers, der an der Reihe ist, 'X'
 * oder 'O'
 * Rückgabewert: Zeichen des Spielers, der eben an der Reihe war.
 * Falls ein Feld besetzt ist, wird der Rückgabewert vertauscht,
 * damit der aktuelle Spieler nochmals seinen Zug machen kann.
 * Hat ein Spieler gewonnen, gibt die Funktion die
 * symbolische Konstante GAME_OVER zurück.
 */
char neuer_zug(char ch) {
   unsigned int row, colum;

   printf("\nSpieler \"%c\" ist an der Reihe\n\n",ch);
   printf("Zeile  (1-3): ");
   scanf("%u",&row);
   printf("Spalte (1-3): ");
   scanf("%u",&colum);

   if(TicTacToe[row-1][colum-1] == LEER) {
      /* Zeichen in das mehrdimensionale Array */
      TicTacToe[row-1][colum-1] = ch;
      print_spielfeld();
      /* Haben wir schon einen Gewinner? */
      if(if_win() == A_WINNER)
         return GAME_OVER;
   }
   else { /* Ein bereits besetztes Feld */
      print_spielfeld();
      printf("\n!!! Feld ist bereits gesetzt !!!\n");
      return (ch == X) ?O :X;
   }
   /* Sind bereits alle Felder besetzt? */
   if(--felder > 0)
      return ch;
   else {
      printf("\nAlle Felder sind besetzt - Unentschieden\n");
      return GAME_OVER;
   }
}

/* Auswertung aller Möglichkeiten, um einen Gewinner zu ermitteln.
 * Rückgabewert: symb. Konstante A_WINNER, falls ein Gewinner
 * ermittelt wurde, oder die symbolische Konstante CONTINUE zum
 * Weiterspielen
 */
int if_win(void) {
  /* Zuerst Spieler1 'X' */
  if(TicTacToe[0][0] == Spieler1 &&
     TicTacToe[0][1] == Spieler1 &&
     TicTacToe[0][2] == Spieler1 ||
     TicTacToe[1][0] == Spieler1 &&
     TicTacToe[1][1] == Spieler1 &&
     TicTacToe[1][2] == Spieler1 ||
     TicTacToe[2][0] == Spieler1 &&
     TicTacToe[2][1] == Spieler1 &&
     TicTacToe[2][2] == Spieler1 ||
     TicTacToe[0][0] == Spieler1 &&
     TicTacToe[1][0] == Spieler1 &&
     TicTacToe[2][0] == Spieler1 ||
     TicTacToe[0][1] == Spieler1 &&
     TicTacToe[1][1] == Spieler1 &&
     TicTacToe[2][1] == Spieler1 ||
     TicTacToe[0][2] == Spieler1 &&
     TicTacToe[1][2] == Spieler1 &&
     TicTacToe[2][2] == Spieler1 ||
     TicTacToe[0][0] == Spieler1 &&
     TicTacToe[1][1] == Spieler1 &&
     TicTacToe[2][2] == Spieler1 ||
     TicTacToe[0][2] == Spieler1 &&
     TicTacToe[1][1] == Spieler1 &&
     TicTacToe[2][0] == Spieler1) {
        printf("Spieler1 hat gewonnen\n");
        return A_WINNER;
  }

  /* Jetzt Spieler2 'O' */
  else if( TicTacToe[0][0] == Spieler2 &&
           TicTacToe[0][1] == Spieler2 &&
           TicTacToe[0][2] == Spieler2 ||
           TicTacToe[1][0] == Spieler2 &&
           TicTacToe[1][1] == Spieler2 &&
           TicTacToe[1][2] == Spieler2 ||
           TicTacToe[2][0] == Spieler2 &&
           TicTacToe[2][1] == Spieler2 &&
           TicTacToe[2][2] == Spieler2 ||
           TicTacToe[0][0] == Spieler2 &&
           TicTacToe[1][0] == Spieler2 &&
           TicTacToe[2][0] == Spieler2 ||
           TicTacToe[0][1] == Spieler2 &&
           TicTacToe[1][1] == Spieler2 &&
           TicTacToe[2][1] == Spieler2 ||
           TicTacToe[0][2] == Spieler2 &&
           TicTacToe[1][2] == Spieler2 &&
           TicTacToe[2][2] == Spieler2 ||
           TicTacToe[0][0] == Spieler2 &&
           TicTacToe[1][1] == Spieler2 &&
           TicTacToe[2][2] == Spieler2 ||
           TicTacToe[0][2] == Spieler2 &&
           TicTacToe[1][1] == Spieler2 &&
           TicTacToe[2][0] == Spieler2)  {
              printf("Spieler2 hat gewonnen\n");
              return A_WINNER;
   }
   return CONTINUE;
}

int main(void) {
   char check = X;

   /* Leeres Spielfeld ausgeben */
   print_spielfeld();

   do { /* War Spieler mit dem Zeichen 'X' gerade dran ... */
      /* ... dann ist jetzt Spieler mit dem Zeichen 'O' dran ...*/
      if(check==X) {
            check=neuer_zug(O);
      }
      else { /* ... ansonsten der Spieler mit dem Zeichen 'X'. */
        check=neuer_zug(X);
      }
   } while( check != GAME_OVER );
   return EXIT_SUCCESS;
}

Abbildung 11.10 Das Spiel »Tic Tac Toe« für die Konsole

Wenn Sie jetzt noch Lust und viel Zeit haben, können Sie sich ja hinsetzen und eine Funktion basteln, um gegen den Computer antreten zu können, also eine eigene KI programmieren. Dabei können Sie so ähnlich vorgehen wie bei der Funktion if_win().


Künstliche Intelligenz

Das Kürzel KI steht für künstliche Intelligenz. Gemeint ist damit die Möglichkeit einer Maschine, sich Funktionen des Menschen, wie Denken oder Bewegungsabläufe, mithilfe von Programmen anzueignen (zu simulieren).


Dreidimensionale Arrays

Zur Veranschaulichung folgt hier ein Beispiel dafür, wie ein dreidimensionales Array direkt mit Werten initialisiert werden kann:

int dreid[2][3][4]={{{6,7,4,3},{6,4,6,9},{3,4,6,7}},
                    {{7,8,6,4},{5,99,3,5},{4,6,7,8}}};

Hier ist eine geschweifte Klammer hinzugekommen:

int dreid[][][]= {1.Feldindex{2.Feldindex{3.Feldindex}}};

Wenn zum Beispiel auf die erste Zahl zugegriffen werden soll, geschieht das folgendermaßen:

dreid[0][0][0]    /* erste Zahl 6 */

Auf die Zahl 99 greifen Sie so zu:

dreid[1][1][1]    /* die Zahl 99 */

Ein Beispiel dazu erspare ich mir, da Sie in der Regel selten mit einem solchen Array zu tun haben. Außerdem lässt sich ein dreidimensionales Array nur recht schwer vorstellen.


Rheinwerk Computing - Zum Seitenanfang

11.9.2 Übergabe von zwei- bzw. mehrdimensionalen Arrays an Funktionen topZur vorigen Überschrift

Unschön an den vorangegangenen Beispielen mit den zweidimensionalen Arrays war, dass der Speicher immer global definiert wurde. Allerdings ist es auch hier immer ein wenig verwirrend, wenn man ein zweidimensionales Array an eine Funktion übergeben will – da ein zweidimensionales Array (oder auch Array auf Array) in einen Zeiger auf Arrays zerfällt – und nicht, wie man vielleicht vermuten würde, in einen Zeiger auf einem Zeiger!

Wollen Sie also ein zweidimensionales Array wie folgt an eine Funktion übergeben:

int val[ZEILE][SPALTE];
function(val);

dann sollte die Funktion so aussehen:

/*  1. Möglichkeit :
 *     automatische Umsetzung, wird vom Compiler vorgenommen
 */
void function( int feld[][SPALTE] ) {
   ...
}

// ODER :

/*  2. Möglichkeit:
 *     explizite Umsetzung
 */
void function( int (*ptr)[SPALTE] ) {
   /* ptr ist ein Zeiger auf das Array der Länge SPALTE */
   ...
}

Da eine aufgerufene Funktion keinen Speicher für ein Array bereitstellt, muss die gesamte Größe des Arrays (erste Dimension) nicht angegeben werden – weshalb hier die (Dimension) Zeile weggefallen ist. Allerdings müssen die weiteren Dimensionen (zweite, dritte etc.), wie im Beispiel mit SPALTE, immer mit angegeben werden.

Hierzu zeige ich noch ein einfaches Beispiel, das demonstriert, wie Sie ein zweidimensionales Array an eine Funktion übergeben können:

/* md_array3.c */
#include <stdio.h>
#include <stdlib.h>
#define DIM1 5
#define DIM2 5

void function(int feld[][DIM2], int dim1) {
   int i, j;

   for(i = 0; i < dim1; i++) {
      for(j = 0; j < DIM2; j++) {
         printf("%d; ", feld[i][j]);
      }
      printf("\n");
   }
   printf("\n");
}

int main(void) {
   int val[DIM1][DIM2];
   int i, j;

   for(i = 0; i < DIM1; i++)
      for(j = 0; j < DIM2; j++)
         val[i][j] = i+j;

   function(val, DIM1);
   return EXIT_SUCCESS;
}


Ihr Kommentar

Wie hat Ihnen das <openbook> gefallen? Wir freuen uns immer über Ihre freundlichen und kritischen Rückmeldungen. >> Zum Feedback-Formular
<< zurück
  
  Zum Katalog
Zum Katalog: C von A bis Z

 C von A bis Z
Jetzt bestellen


 Ihre Meinung?
Wie hat Ihnen das <openbook> gefallen?
Ihre Meinung

 Buchtipps
Zum Katalog: C/C++






 C/C++


Zum Katalog: Einstieg in C






 Einstieg in C


Zum Katalog: Schrödinger programmiert C++






 Schrödinger
 programmiert C++


Zum Katalog: C++ Handbuch






 C++ Handbuch


Zum Katalog: IT-Handbuch für Fachinformatiker






 IT-Handbuch für
 Fachinformatiker


 Shopping
Versandkostenfrei bestellen in Deutschland und Österreich
InfoInfo




Copyright © Rheinwerk Verlag GmbH 2009
Für Ihren privaten Gebrauch dürfen Sie die Online-Version natürlich ausdrucken. Ansonsten unterliegt das <openbook> denselben Bestimmungen, wie die gebundene Ausgabe: Das Werk einschließlich aller seiner Teile ist urheberrechtlich geschützt. Alle Rechte vorbehalten einschließlich der Vervielfältigung, Übersetzung, Mikroverfilmung sowie Einspeicherung und Verarbeitung in elektronischen Systemen.


[Rheinwerk Computing]

Rheinwerk Verlag GmbH, Rheinwerkallee 4, 53227 Bonn, Tel.: 0228.42150.0, Fax 0228.42150.77, service@rheinwerk-verlag.de