 |
вы, и они описываются именно так, как вы себе и представляли:
type name[size1][size2]...[sizeN]
(тип имя [размер1][размер2]...[размерN])
Рассморим следующую программу, которая определяет два дву-
мерных массива, а затем выполняет их матричное умножение:
main()
{
int a[3][4] = {{ 5, 3, -21, 42},
{44, 15, 0, 6},
{97 , 6, 81, 2}};
int b[4][2] = {{22, 7},
{97, -53},
{45, 0},
{72, 1} };
int c[3][2],i,j,k;
for (i=0; i<3; i++) {
for (j=0; j<2; j++) {
c[i][j] = 0;
for (k=0; k<4; k++)
c[i][j] += a[i][k] * b[k][j];
}
}
for (i=0; i<3; i++) {
for (j=0; j<2; j++)
printf("c[%d][%d] = %d ",i,j,c[i][j]);
printf("\n");
}
}
Отметим два момента в этой программе. Синтаксис определения
двумерного массива состоит из набора {...} списков, разделенных
запятой. Квадратные скобки ([ ]) используются для записи каждого
индекса.
Некоторые языки для определения массивов используют синтак-
сис [i,j]. Так можно написать и на Си, но это все равно, что ска-
зать просто [j], т.к. запятая интерпретируется как оператор, оз-
начающий (" определить i, затем определить j, затем присвоить
всему выражению значение j").
- 503,504 -
Для полной уверенности ставьте квадратные скобки вокруг
каждого индекса.
Многомерные массивы хранятся в памяти слева направо по пра-
вилу "строки - столбцы". Это означает, что последний индекс изме-
няется быстрее. Другими словами, в массиве arr[3][2] элементы arr
хранятся в памяти в следующем порядке:
arr[0][0]
arr[0][1]
arr[1][0]
arr[1][1]
arr[2][0]
arr[2][1]
Тот же принцип сохраняется для массивов двух-, трех- и
большей размерности.
Массивы и функции
-----------------------------------------------------------------
Что произойдет, если вы захотите передать массив в функцию?
Рассмотрим следующую функцию, возвращающую индекс минимального
числа массива int:
int imin(int list[], int size)
{
int i, minindx, min;
minindx = 0;
min = list[minindx];
for (i = 1; i < size; i++)
if (list[i] < min) {
min = list[i];
minindx = i;
}
return(minindx);
}
Здесь вы видите одну из важных особенностей Си: вам необяза-
тельно знать при трансляции величину list[]. Почему? Потому что
компилятор считает list[] начальным адресом массива, и не забо-
- 505,506 -
тится о том, где его конец.
Программа, обращающаяся к функции imin, может выглядеть так:
main()
{
#define VSIZE 22
int i,vector[VSIZE];
for (i = 0; i < VSIZE; i++) {
vector[i] = rand();
printf("vector[%2d] = %6d\n",i,vector[i]);
}
i = imin(vector,VSIZE);
printf("minimum: vector[%2d] = %6d\n",i,vector[i]);
}
Может возникнуть вопрос: что именно передается в imin? В
функцию imin передается начальный адрес массива vector. Это озна-
чает, что если вы производите какие-либо изменения массива list в
imin то, те же изменения будут произведены и в массиве vector.
Например, вы можете написать следующую функцию :
void setrand(int list[],int size);
{
int i;
for (i = 0; i < size; i++) list[i] = rand();
}
Теперь для инициализации массива vector вы можете написать в
main setrand(vector,VSIZE). Следует заметить, что массиву vector
будут присвыоены некие случайные числа, являющиеся результатом
работы датчика случайных чисел, эмулируемого функцией Турбо Си
rand().
А как передавать многомерный массив? Имеется ли такая воз-
можность? Предположим, вы хотите модифицировать setrand для рабо-
ты с двумерным массивом. Вы должны написать приблизительно следу-
ющее:
void setrand(int matrix[][CSIZE],int rsize)
{
int i,j;
for (i = 0; i < rsize; i++) {
- 507,508 -
for (j = 0; j < CSIZE; i++)
matrix[i][j] = rand();
}
}
Где CSIZE - это глобальная константа, определяющая второе
измерение массива. Другими словами, любой массив, передаваемый
setrand получит второе измерение массива, равный CSIZE.
Однако, есть еще одно решение. Предположим, у вас есть мас-
сив matrix[15,7], который вы хотите передать в setrand. Если вы
используете следующее описание:
setrand(int list[],int size)
обращение к функции будет иметь вид:
setrand(matrix,15*7);
Массив matrix будет рассматриваться функцией setrand как од-
номерный массив, содержащий 105 элементов (15 строк * 7 столб-
цов), с которым будут произведены необходимые вам действия.
Структуры
-----------------------------------------------------------------
Массивы и указатели позволяют вам создавать список элементов
одного типа. А что, если вы хотите создать нечто, содержащее эле-
менты различного типа? Для этого используются СТРУКТУРЫ.
Структура - это конгломерат элементов различного типа. До-
пустим, вы хотите сохранить информацию о звезде: ее имя, спект-
ральный класс, координаты и прочее. Вы можете описать это следую-
щим образом:
typedef struct {
char name[25];
char class;
short subclass;
float decl,RA,dist;
} star ;
Здесь определена структура (struct) типа star. Сделав такое
описание в начале своей програмы, вы можете дальше использовать
этот определенный вами тип данных:
- 509,510 -
main()
{
star mystar;
strcpy(mystar.name,"Эпсилон Лебедя");
mystar.class = 'N';
|