МАССИВЫ
Как известно, массив
- это конечная совокупность данных одного
типа. Можно говорить о массивах целых чисел,
массивов символов и.т.д. Мы можем даже определить
масссив, элементы которого - массивы( массив
массивов), определяя, таким образм, многомерные
массивы. Любой массив в программе должен быть
описан: после имени массива добаляют квадратные
скобки [], внутри которых обычно стоит
число, показывающее количество элементов
массива. Например, запись int x[10];
определяет x как массив из 10 целых чисел.
В случае многомерных массивов показывают
столько пар скобок , какова размерность массива,
а число внутри скобок показывает размер массива
по данному измерению. Например, описание
двумерного массива выглядит так: int a[2][5];. Такое
описание можно трактовать как матрицу из 2 строк
и 5 столбцов. Для обрщения к некоторому элементу
массива указывают его имя и индекс, заключенный в
квадратные скобки(для многомерног массива -
несколько индексов , заключенные в отдельные
квадратные скобки): a[1][3], x[i] a[0][k+2]. Индексы
массива в Си всегда начинаются с 0, а не с 1, т.е.
описание int x[5]; порождает элементы x[0],
x[1], x[2], x[3], x[4], x[5]. Индекс может быть не только
целой константой или целой переменной, но и любым
выражением целого типа. Переменная с индексами в
программе используется наравне с простой
переменной (например, в операторе присваивания, в
функциях ввода- вывода). Начальные значения
массивам в языке Си могут быть присвоены при
компиляции только в том случае, если они
объявлены с классом памяти extern или static,
например:
static int
a[6]={5,0,4,-17,49,1};
обеспечивает присвоения a[0]=5;
a[1]=0; a[2]=4 ... a[5]=1. Как видите, для начального
присвоения значений некоторому массиву надо в
описании поместить справа от знака = список
инициирующих значений, заключенные в фигурные
скобки и разделенные запятыми. Двумерный массив
можно инициировать так:
static int matr[2][5] =
{{3,4,0,1,2},{6,5,1,4,9}};
Матрица хранится в памяти построчно, т.е.
самый правый индекс в наборе индексов массива
меняется наиболее быстро.
Пусть, например, в заданном массиве из 10
целых чисел надо изменить порядок следования его
элементов на обратный без привлечения
вспомагательного массива. Соответствующая
прорамма приведена на примере 3.6 .
Пример 3.6
/*обращение массива*/
#include <stdio.h>
main()
{
int p,i=0;
static a[10]={10,11,12,13,14,
15,16,17,18,19};
while(i<10/2)
{
p=a[i];
a[i]=a[9-i];
a[9-i]=p;
i++;
}
i=0;
while(i<10)
printf(" %d",a[i++]);
} |
Следующяя программа (пример 3.7)
позволяет в целочисленном массиве найти
разность максимального и минимального элемента .
Обратите внимание, что функция fmax при
первом обращении к ней дает максимальный элемент
массива, а при повторном вызове - минимальный,
так как предварительно мы изменили знаки
элементов на противоположные. Это изменение
знаков учитывается при вызове функции printf. В
языке Си отсутствует возможность динамически
распределять память под массивы: надо при
описании массива задать точно его размер. Но если
тот же массив описывается еще раз в другой
программе, размеры можно не указывать;достаточно
после имени сохранить пару квадратных скобок,
например int x[]. Если при вызове функции в
качестве аргумента ей передается имя массива, то,
в отличае от простых переменных, берется
фактически адрес начала этого массива. Поэтому
записи fmax(a, 10) и fmax(&a[0], 10) равносильны.
Пример 3.7
/*в массиве найти разность
мин. и макс. элементов */
int fmax(x,n)
int x[],n;
{
int max, i=0; max=x[0];
while(i<n)
{
if(x[i]> max)
max=x[i];
i++;
}
return(max);
}
#include <stdio.h>
main()
{
static int a[10]=
{1,-2,3,-4,5,-6,7,-8,9,-13};
max=fmax(a,10);
i=0;
while(i<10)
{
a[i]=-a[i];
i++;
}
main=fmax(a,10);
printf("макс-мин=%d\n",max+min);
} |
В следующем пример 3.8
массив описан как внешний. Функция main
подсчитывает наибольшее число одинаковых идущих
подряд элементов массива, определенного вне
функции main.
Пример 3.8
/*макс одинаковых подряд*/
#include <stdio.h>
int a[]={5,6,6,6,4,3,3,3,3,3,8};
int n=10;
main()
{
int i,k,max;
i=k=max=1;
while(i<n)
{
if(a[i]==a[i-1])
k++;
else
{
if(k>max)max=k;
k=1;
}
i++;
}
printf("kmax=%d\n",(k>max)?k:max);
}
|
Если, как в данном
примере, размер массива пропущен, то транслятор
определит его дляну, считая присваиваемые
значения во время начальной инициализации.
Условная операция (k>max)?k:max в
операторе printf предусмотрена для того
частного случая, когда весь массив состоит из
одинаковых элементов. Приведем несколько
примеров, в которых ведется обработка двумерных
массивов. Но прежде одну полезную возможносить
языка Си. Речь идет о препроцессорном
утверждении #difine, позволяющем
присваивать символические имена константам. В
общем случае это утверждение записывают так: #define
строка1 строка2 (точка с запятой не ставится).
Прежде чем исходный текст программы будет
передан компилятору, он обрабатывается
препроцессором, котоый всюду в исходном тексте
заменит вхождение "строка1" на
"строка2". Например, строка #difine max 80, записанная
в начале программы, обеспечит всюду замену
указанного имени max на соответствующую
константу. Замена имени связана не только
числами, но и текстами. А теперь вернемся к
примерам. В следующей программе (пример 3.9)
строится единичная матрица a[m][m], размер
которой определяется с помощью конструкции #difine
m 5. Сам алгоритм вычисления элементов
матрицы основан на возведении (i/j)*(j/i) равно
единице тогда и только тогда. когда i равно
j. В остальных случаях оно равно нулю.
Пример 3.9
#define M 5
#include <stdio.h>
main()
{
int a[M][M];
int j,i=0;
while(i<M)
{
j=1;
while(j<M)
{
a[i][j]=(i/j)*(j/i);
printf("%d",a[i][j]);
j++;
}
i++;printf("\n");
}
} |
В программе
(пример 4.0) определяется минимальный элемент
кажой строки матрицы и выполняется обмен местами
найденого и диагональю этой же строки.
Обращаем внимание на следующее
обстоятельство. Если двумерный массив надо
передать ыункции, то описание параметра в ней
должно обязательно включать в себя размер строки
массива, а размер столбцов несущественен. Так,
массив из трех строк и пяти столбцов можно
описать как int a[3][5]; либо int a[][5];
Пример 4.0
/*обмен мин с диагональю*/
#include <stdio.h>
#define M 4
main()
{
static a[M][M]={
{ 3,4,1,5),
{-1,6,7,0},
{ 1,8,7,-1},
{ 4,9,7,-1}};
int i, j, jmin, amin;
i=0;
while(i<M)
{
amin=a[i][0];
jmin=0;j=1;
while(j<m)
{
if(a[i][j]<amin)
{
amin=a[i][j];
jmin=j;
}
j++;
}
a[i][jmin]=a[i][i];
a[i][i]=amin;
i++;
}
i=0
while(i<M)
{
j=0;
while(j<M)
printf("%3d",a[i][j++]);
printf("\n");
i++;
}
} |
< Дальше >
|