|
Wichtig: Die Angabe der Feldgröße muß in diesem Fall durch eineKonstante erfolgen, deshalb die Bezeichnung "statisch"! Die so deklarierten Felder beginnen immer mit Index [0] und enden mit Index [Feldgröße-1].
Es erfolgt keine Überprüfung auf gültigen Speicherbereich von Seiten des Compilers! |
Ansonsten gilt für Feldelemente das gleiche, wie für sonstige Variable
dieses Typs.
- Bei der Deklaration kann eine elegante Initialisierung erfolgen;
Beispiel: int n[] = {8,7,9,-13};
Die (Mindest-)Feldgröße wird dabei automatisch festgelegt.
- Strings stellen hierbei einen Sonderfall dar:
"..." sind bereits eindimensionale Felder, die mit
'\0' terminiert sind. Beispiel:
char ch[] = "String"; ist völlig äquivalent mit
char ch[] = {'S','t','r','i','n','g','\0'};
mögliche Verwendung bei printf() bzw. scanf():
char msg[] = "Hello world!", format[] = "%s\n";
printf(format, msg);
oder:
char msg[100]; /* sicherheitshalber ueberdimensioniert */
scanf("%s", msg); /* hier vor msg KEIN '&', weil
'msg' eine Adresse ist */
Mehrdimensionale Felder
Bei mehrdimensionalen Arrays werden die Variablen durch ein Tupel von
Indizes unterschieden. Beispiel (Deklaration):
float x[8][30];
Hier gilt dann analog: erstes Element ist x[0][0],
bzw. letztes x[7][29]. Dementsprechend werden zweidimensionale
Array zeilenweise gespeichert:
Analog lassen sich auch Felder mit mehr als zwei Dimensionen definieren. Angesprochen
werden die Komponenten über den Index:
x[8][30] =12.5;
Anstelle der Zahlen kann für den Index auch ein beliebiger Integer-Ausdruck
angegeben werden, z. B.:
x[i-1][j*k+2] =32.5;
Der Compiler kann aber selbstständig nur die Zahl der Zeilen feststellen;
die notwendige (Mindest-)Zahl der Spalten muß ihm mitgeteilt werden.
Bemerkung: intern werden mehrdimensionale Felder (wenn
statisch allociert!) eindimensional angelegt; wenn also z. B. ein Array
deklariert ist mit int a[4][3];, dann sind die Aufrufe
a[i][j], a[0][i*3+j] und a[k][(i-k)*3+j] völlig
äquivalent:
a[0][0] |
a[0][1] |
a[0][2] |
a[1][0] |
a[1][1] |
a[1][2] |
a[2][0] |
... |
a[0][0] |
a[0][1] |
a[0][2] |
a[0][3] |
a[0][4] |
a[0][5] |
a[0][6] |
... |
Auch hier gibt es bei der Deklaration wieder die bequeme Möglichkeit
der Initialisierung:
static int md[5][10] =
{
{0,1,2,3,4,5,6,7,8,9},
{1,2,3,4,5,6,7,8,9,10},
{2,3,4,5,6,7,8,9,10,11},
{3,4,5,6,7,8,9,10,11,12},
{4,5,6,7,8,9,10,11,12,13}
};
Die Angaben für die zweite (und weitere) Dimension werden also
jeweils in eigene geschweifte Klammern geschrieben. Innerhalb
der geschweiften Klammern gilt, daß eventuell nicht
initialisierte Elemente auf null gesetzt werden.
Die Kennzeichnung der Array-Struktur bei den Initialisierungswerten
ist notwendig, wenn Elemente "innerhalb" des Arrays durch fehlende Angabe mit
0 initialisiert werden sollen. Beispiele:
int mat[3][4] = { { 1, 4, 3, -4 },
{ 2, 0, -3, 1 } };
Die letzte Zeile (mat[2][0] ... mat[2][3]) wird mit 0 initialisiert.
int mat[3][4] = { { 1, 4, 3 },
{ 2, 0, -3 },
{ 0, -5, 6 } };
Die letzte Spalte (mat[0][3], mat[1][3], mat[2][3]) wird mit 0
initialisiert. Die Kennzeichnung der Arraystruktur bei den Initialisierungswerten
ist notwendig.
Man kann die inneren geschweiften Klammern auch weglassen, dann wird der ganze Vektor
Element für Element initialisiert.
int mat[3][4] = { 1, 4, 3, -4, 2, 0, -3, 1, 0, -5 };
oder:
int mat[ ][4] = { 1, 4, 3, -4, 2, 0, -3, 1, 0, -5 };
Die beiden letzten Elemente der letzten Zeile (mat[2][2], mat[2][3])
werden mit 0 initialisiert. Ein weiteres Beispiel:
/* Tag im Jahr aus Monat und Tag bestimmen */
day_of_year(int year, int month, int day)
{
static int day_tab[2][13] = {
{0,31,28,31,30,31,30,31,31,30,31,30,31},
{0,31,29,31,30,31,30,31,31,30,31,30,31}
};
int i, leap;
leap = year%4 == 0 && year%100 != 0 || year%400 == 0;
for (i=1; i < month; i++)
day += day_tab[leap][i];
return (day);
}
Die folgende Funktion liefert den Namen eines Monats, falls der Parameter
im Bereich 1..12 liegt und andernfalls einen Fehlertext
char *month_name(int n)
{
static char *name[] = { /* Vektor von Zeigern */
"*** gibt's nicht ***", /* String ist ein char- */
"Januar", /* Vektor und daher durch */
"Februar", /* seine Anfangsadresse */
"Maerz", /* charakterisiert */
"April",
"Mai",
"Juni",
"Juli",
"August",
"September",
"Oktober",
"November",
"Dezember"
};
return ((n < 1 || n > 12) ? name[0] : name[n]);
}
Beispiele für die Verwendung von zweidimensionalen Feldern,
die als Felder von Feldern aufgefaßt werden können.
#include <stdio.h>
#include <stdlib.h>
void main(void)
{
/* Deklaration eines Schachbretts von Zeichen */
char brett[8][8];
/* Belegen des Schachbretts */
for(i=0;i<8;i++)
{
for(j=0;j<8;j++)
{
brett[i][j]=' ';
}
}
for(i=0;i<8;i++) /* Bauern */
{
brett[1][i]='b';
brett[6][i]='B';
}
/* weitere Figuren */
brett[0][0]=brett[0][7]='t';
brett[0][1]=brett[0][6]='s';
brett[0][2]=brett[0][5]='l';
brett[0][3]='d';
brett[0][4]='k';
brett[7][0]=brett[7][7]='T';
brett[7][1]=brett[7][6]='S';
brett[7][2]=brett[7][5]='L';
brett[7][3]='D';
brett[7][4]='K';
/* Ausgabe */
printf(" A B C D E F G H\n");
for(i=7;i>=0;i=i-1)
{
printf(" +-+-+-+-+-+-+-+-+\n%d|",i+1);
for(j=0;j<=7;j=j+1)
{
printf("%c|",brett[i][j]);
}
printf("%d\n",i+1);
}
printf(" +-+-+-+-+-+-+-+-+\n A B C D E F G H\n");
}
Demonstrationsprogramm zu 2-dimensionalen Arrays: Matrixaddition
#include <stdio.h>
#define ZEILEN 3
#define SPALTEN 4
void mat_add (float mat1[ZEILEN][SPALTEN],
float mat2[ZEILEN][SPALTEN],
float erg[ZEILEN][SPALTEN])
{
int i, j;
for (i=0; i<ZEILEN; i++)
for (j=0; j<SPALTEN; j++)
erg[i][j]=mat1[i][j] + mat2[i][j];
}
void mat_aus(float fmat[ZEILEN][SPALTEN])
{
int i,j;
for(i=0; i<ZEILEN; i++)
{
printf("\n{");
for (j=0; j<SPALTEN; j++)
printf("%6.2f", fmat[i][j]);
printf("}");
}
printf("\n");
}
int main(void)
{
float fmat1[ZEILEN][SPALTEN] = {
{ 1.5, 4.1, 3.4, -4.0 },
{ 2.2, 0, -3.7, 1.1 },
{ 0, -5.1, 6.6, 0.2 }
};
float fmat2[ZEILEN][SPALTEN] =
{-1.5, 2.3, 3.7, 2.1, 0.7,5.5, 3.3,0,0,0,0,0};
float fmat3[ZEILEN][SPALTEN];
mat_add(fmat1, fmat2, fmat3);
mat_aus(fmat3);
return 0;
}
Ein matadd-Probelauf ergibt:
{ 0.00, 6.40, 7.10, -1.90, }
{ 2.90, 5.50, -0.40, 1.10, }
{ 0.00, -5.10, 6.60, 0.20, }
|
|
|