Архитектура Аудит Военная наука Иностранные языки Медицина Металлургия Метрология
Образование Политология Производство Психология Стандартизация Технологии


Генерация двумерных массивов



Методические указания

 

Массивы - это группа элементов одного типа (double, float, int и т.п.). Из объявления массива компилятор должен получить информацию о типе элементов Объявление массива имеет два формата:

спецификатор-типа имя_массива [константное_выражение];

спецификатор-типа имя_массива [ ];

Спецификатор-типа задает тип элементов объявляемого массива. Элементами массива не могут быть функции и элементы типа void.

Константное_выражение в квадратных скобках задает количество элементов массива.

int sample [I0];

#define Nmax 10

int sample [Nmax] /*равносильно объявлению int sample [I0]; */

При объявлении массива константное_выражение может быть опущено в случаях, если:

- при объявлении массив инициализируется,

- массив объявлен как формальный параметр функции,

- массив объявлен как ссылка на массив, явно определенный в другом файле.

Обращение к элементам массива осуществляется с помощью индексированного имени. В языке Си первый элемент массива получает индекс 0. Таким образом, выше объявлен массив с десятью элементами: от sample[0] до sample[9].

Массив занимает непрерывную область памяти. Для одномерного массива полный объем занимаемой памяти в байтах вычисляется по формуле:

Байты = sizeof (тип) * длина массива

Массив представляет собой набор однотипных данных, расположенных в памяти таким образом, чтобы по индексам элементов можно было легко вычислить адрес соответствующего значения. Например, пусть одномерный массив A состоит из элементов, расположенных в памяти подряд по возрастанию индексов, и каждый элемент занимает по k байт. Тогда адрес i-того элемента вычисляется по формуле:

адрес(A[i]) = адрес(A[0]) + i*k

Отсутствие проверки границ

В языке Си не производится проверки границ массивов: таким образом, ничто не остановит вас при выходе за границы массива. Если переполнение массива происходит во время выполнения оператора присваивания, то лишние значения могут присвоиться другим переменным или включиться в текст программы. С другой стороны, вы можете объявить массив размером N и указать индекс элемента, выходящий за пределы N, что не приведет к появлению сообщений об ошибке, как на шаге компиляции, так и на шаге выполнения, даже если это послужит причиной аварийного завершения программы. Таким образом, как программист, вы отвечаете за то, чтобы ваши массивы были достаточно велики для содержания поступающих в них данных.

 

Пример:

#define N_max 25

int b1[N_max];

 

Так как индексы в Си всегда отсчитыватся от 0, так что, например, в массиве b1можно манипулировать с элементами b1[0], b1[1], ..., b1[24]. Элемент b1[25] массиву b1 уже не принадлежит и попытка записи в него может привести к непредсказуемым последствиям.

Инициализация массивов

Термином " инициализация" обозначают возможность задать начальные значения элементов массива без программирования соответствующих действий. Например, не прибегая к программным средствам типа присвоения значений в цикле или считывания данных из внешнего источника (файл, клавиатура, блок данных). В Си одновременно с объявлением массива можно задать начальные значения всех элементов массива или только нескольких первых его компонент:

int d[10]={1, 2, 3, 4};

char a[7]=" Привет";

char b[7]={'П', 'р', 'и', 'в', 'е', 'т'};

Пример выполнения задания:

 

1. В одномерном массиве, состоящем из n вещественных элементов, вычислить:

· сумму отрицательных элементов массива;

· произведение элементов массива, расположенных между максимальным и минимальным элементами;

Блок - Схема

 

Код программы:

#include < conio.h>

#include < iostream>

using namespace std;

#include < math.h>

int main()

{

const int n = 6;

int a[n], kx, kn, i, z, s;

int otr=0;

cout < < " \nvvedite massiv\n";

for (i=0; i< n; i++) cin> > a[i]; //vvod massiva a s klaviaturi //

int max=a[0];

int min=a[0];

kn=0; kx=0;

for (i=0; i< n; i++)

if (a[i]> max) //cikl dlya nahozhdeniya naibolshego elementa //

{

kx=i;

max=a[i];

}

 

for (i=n; i> 0; i--) //cikl dlya nahozhdeniya naimenshego elementa //

if (a[i]< min)

{

min=a[i];

kn=i;

}

cout< < " max=" < < max< < " min=" < < min;

for (i=0; i< n; i++)

if (a[i]< 0)

{

otr=otr+a[i]; //podschet summi otric. elementov //

}

if (kn> kx)

{

s=1;

for (i=kn; i< kx; i++) s=s*a[i];

}

else

{

s=1;

for (i=kx; i> kn; i--) s=s*a[i];

}

 

cout< < " \n proizvedenie chlenov mezhdu max i min chlenami - " < < s;

cout< < " \n summa otric 4lenov - " < < otr;

getch();

return 0;

}


Генерация двумерных массивов

Принцип генерации двумерных массивов такой же, как и одномерных.

//Описание функции генерации массиваvoid gen(int str, int slb, int a, int b, int m[max_x][max_y]){ int i, j; srand(time(NULL)*1000); //устанавливает начальную точку генерации случайных чисел for (i=0; i< str; i++) for (j=0; j< slb; j++) m[i][j]=rand()%(b-a)+a); //функция генерации случайных чисел на [a, b)}

 

 

Ввод-вывод массива

Язык Си не имеет встроенных средств для ввода-вывода массива целиком, поэтому массив вводят и выводят поэлементно с помощью циклов, как, например, в следующей программе:

1. #include < stdio.h>

2.

3. void main(void)

4. {

5. double a[100]; int n, i;

6. printf(" Введите количество чисел n = " );

7. scanf(" %d", & n);

8. if( n> (sizeof a)/sizeof(double) )

9. { printf(" Слишком много элементов\n" ); return; }

10. for(i=0; i< n; i++)

11. {

12. printf(" a[%d] = ", i); scanf(" %lf", & a[i]);

13. }

14.

15. /* Операторы, обрабатывающие массив */

16.

17. }

 

 

Блок-схема ввода массива

 

#include < stdio.h> void main(void) { double a[100]; int n, i; printf(" Введите количество чисел n = " ); scanf(" %d", & n); if( n> (sizeof a)/sizeof(double) ) { printf(" Слишком много элементов\n" ); return; } for(i=0; i< n; i++) { printf(" a[%d] = ", i); scanf(" %lf", & a[i]); } /* Операторы, обрабатывающие массив */ }

Во многих случаях удобно возложить на программу подсчет числа элементов, вводимого массива, при этом ввод завершается при появлении во входном потоке признака конца данных. Таким признаком в следующей программе служит число большее 1.0e300

1. #include < stdio.h>

2.

3. void main(void)

4. {

5. double a[100], temp; int n, end;

6. for(end=n=0; n< (sizeof a)/sizeof(double); n++)

7. {

8. printf(" a[%d] = ", n); scanf(" %lf", & temp);

9. if( temp> =1.0e300 ) { end=1; break; }

10. a[n] = temp;

11. }

12. if( end )

13. {

14.

15. /* Операторы, обрабатывающие массив */

16.

17. }

18. else

19. printf(" Переполнение массива\n" );

20. }

 

#include < stdio.h> void main(void) { double a[100], temp; int n, end; for(end=n=0; n< (sizeof a)/sizeof(double); n++) { printf(" a[%d] = ", n); scanf(" %lf", & temp); if( temp> =1.0e300 ) { end=1; break; } a[n] = temp; } if( end ) { /* Операторы, обрабатывающие массив */ } else printf(" Переполнение массива\n" ); }

Вывод массива, содержащего большое количество элементов желательно производить в несколько строк с остановом после заполнения экрана.

Блок-схема вывода массива

 

Следующий фрагмент программы выводит массив строками по 5 элементов. После вывода 120 элементов программа останавливается для просмотра выдачи. Очередные 120 элементов выводятся после нажатия на любую клавишу.

1. for (i=0; i< n; i++)

2. {

3. printf(" %10.3lf ", a[i]);

4. if( (i+6) % 5 == 0 ) printf(" \n" );

5. if( (i+121) % 120 == 0 ) { getch(); clrscr(); }

6. }

for (i=0; i< n; i++) { printf(" %10.3lf ", a[i]); if( (i+6) % 5 == 0 ) printf(" \n" ); if( (i+121) % 120 == 0 ) { getch(); clrscr(); } }

Здесь стандартная функция clrscr() очищает экран.

Итак, основные выводы по вышеизложенной информации.

 

Свойства массивов:

1. В массиве хранятся отдельные значения, которые называются элементами.
2. Все элементы массива должны быть одного типа данных (int, float, char*...).
3. Все элементы хранятся в памяти последовательно, и первый имеет нулевой адрес.
4. Имя массива является константой и содержит адрес первого элемента массива.

Результаты работы программы

n=

Massiv x

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15

Massiv x

x(0)=1 x(1)=2 x(2)=3 x(3)=9 x(4)=10 x(5)=11 x(6)=12 x(7)=13 x(8)=14 x(9)=15

Сортировка выбором

int main()

{

float b, max, a[20];

int i, j, n, k, nom;

cout< < " n=";

cin> > n;

cout< < " Massiv a\n";

for(i=0; i< n; i++)

cin> > a[i];

k=n;

for(j=0; j< =k-2; j++)

{

max=a[0]; nom=0;

for(i=1; i< k; i++)

if (a[i]> max)

{

max=a[i];

nom=i;

}

b=a[k-1];

a[k-1]=a[nom];

a[nom]=b;

k--;

}

cout< < " Massiv a\n";

for(i=0; i< n; i++)

cout< < " a(" < < i< < " )=" < < a[i]< < " \t";

cout< < endl;

return 0;

}

Сортировка методом пузырька

int main()

{

float b, max, a[20];

int i, j, n, k, nom;

cout< < " n=";

cin> > n;

cout< < " Massiv a\n";

for(i=0; i< n; i++)

cin> > a[i];

for(j=1; j< =n-1; j++)

for(i=0; i< =n-1-j; i++)

if (a[i]> a[i+1])

{

b=a[i];

a[i]=a[i+1];

a[i+1]=b;

}

cout< < " Massiv a\n";

for(i=0; i< n; i++)

cout< < " a(" < < i< < " )=" < < a[i]< < " \t";

cout< < endl;

return 0;

}

Примеры

 

Пусть, например, в заданном массиве из 10 целых чисел надо изменить порядок следования его элементов на обратный без использования вспомогательного массива. Текст программы приведен на примере 1.

Пример 1

/*обращение массива*/ #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++]); }  

Пример2. Найти среднее арифметическое элементов заданного массива.

#include< stdio.h>
#define TEN 10 //так объявляются константы. Менять значения TEN после этого объявления мы не имеем права
//Здесь же константе TEN мы присвоили значение 10

Void main()

{
float a[TEN], s=0; //мы объявили массив типа float из TEN(десяти) элементов и переменную s

Int i; //переменная цикла

printf(" Введите массив: " );

for(i=0; i< TEN; i++)

scanf(" %d", m[i]); /*последовательный ввод массива*/

for(i=0; i< TEN; i++)
s = s+a[i]; /*нахождение суммы элементов*/

s=s/TEN; //нахождение среднего арифметического делением суммы на TEN, то есть на 10
printf(" s = %8.2f", s);
}

 

Приведем несколько примеров, в которых ведется обработка двумерных массивов. Но прежде одну полезную возможносить языка Си. Речь идет о препроцессорном утверждении #dеfine, позволяющем присваивать символические имена константам.

В общем случае это утверждение записывают так:

#define строка1 строка2 (точка с запятой не ставится).


Прежде чем исходный текст программы будет передан компилятору, он обрабатывается препроцессором, котоый всюду в исходном текстезаменит вхождение " строка1" на " строка2". Например, строка #difine max 80, записанная в начале программы, обеспечит всюду замену указанного имени max на соответствующую константу. Замена имени связана не только числами, но и текстами.

А теперь вернемся к примерам. В следующей программе (пример 3) строится единичная матрица a[m][m], размер которой определяется с помощью конструкции #difine m 5. Сам алгоритм вычисления элементов матрицы основан на возведении (i/j)*(j/i) равно единице тогда и только тогда. когда i равно j. В остальных случаях оно равно нулю.

Пример 3

#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" ); } }

 

Методические указания

 

Массивы - это группа элементов одного типа (double, float, int и т.п.). Из объявления массива компилятор должен получить информацию о типе элементов Объявление массива имеет два формата:

спецификатор-типа имя_массива [константное_выражение];

спецификатор-типа имя_массива [ ];

Спецификатор-типа задает тип элементов объявляемого массива. Элементами массива не могут быть функции и элементы типа void.

Константное_выражение в квадратных скобках задает количество элементов массива.

int sample [I0];

#define Nmax 10

int sample [Nmax] /*равносильно объявлению int sample [I0]; */

При объявлении массива константное_выражение может быть опущено в случаях, если:

- при объявлении массив инициализируется,

- массив объявлен как формальный параметр функции,

- массив объявлен как ссылка на массив, явно определенный в другом файле.

Обращение к элементам массива осуществляется с помощью индексированного имени. В языке Си первый элемент массива получает индекс 0. Таким образом, выше объявлен массив с десятью элементами: от sample[0] до sample[9].

Массив занимает непрерывную область памяти. Для одномерного массива полный объем занимаемой памяти в байтах вычисляется по формуле:

Байты = sizeof (тип) * длина массива

Массив представляет собой набор однотипных данных, расположенных в памяти таким образом, чтобы по индексам элементов можно было легко вычислить адрес соответствующего значения. Например, пусть одномерный массив A состоит из элементов, расположенных в памяти подряд по возрастанию индексов, и каждый элемент занимает по k байт. Тогда адрес i-того элемента вычисляется по формуле:

адрес(A[i]) = адрес(A[0]) + i*k

Отсутствие проверки границ

В языке Си не производится проверки границ массивов: таким образом, ничто не остановит вас при выходе за границы массива. Если переполнение массива происходит во время выполнения оператора присваивания, то лишние значения могут присвоиться другим переменным или включиться в текст программы. С другой стороны, вы можете объявить массив размером N и указать индекс элемента, выходящий за пределы N, что не приведет к появлению сообщений об ошибке, как на шаге компиляции, так и на шаге выполнения, даже если это послужит причиной аварийного завершения программы. Таким образом, как программист, вы отвечаете за то, чтобы ваши массивы были достаточно велики для содержания поступающих в них данных.

 

Пример:

#define N_max 25

int b1[N_max];

 

Так как индексы в Си всегда отсчитыватся от 0, так что, например, в массиве b1можно манипулировать с элементами b1[0], b1[1], ..., b1[24]. Элемент b1[25] массиву b1 уже не принадлежит и попытка записи в него может привести к непредсказуемым последствиям.

Инициализация массивов

Термином " инициализация" обозначают возможность задать начальные значения элементов массива без программирования соответствующих действий. Например, не прибегая к программным средствам типа присвоения значений в цикле или считывания данных из внешнего источника (файл, клавиатура, блок данных). В Си одновременно с объявлением массива можно задать начальные значения всех элементов массива или только нескольких первых его компонент:

int d[10]={1, 2, 3, 4};

char a[7]=" Привет";

char b[7]={'П', 'р', 'и', 'в', 'е', 'т'};

Пример выполнения задания:

 

1. В одномерном массиве, состоящем из n вещественных элементов, вычислить:

· сумму отрицательных элементов массива;

· произведение элементов массива, расположенных между максимальным и минимальным элементами;

Блок - Схема

 

Код программы:

#include < conio.h>

#include < iostream>

using namespace std;

#include < math.h>

int main()

{

const int n = 6;

int a[n], kx, kn, i, z, s;

int otr=0;

cout < < " \nvvedite massiv\n";

for (i=0; i< n; i++) cin> > a[i]; //vvod massiva a s klaviaturi //

int max=a[0];

int min=a[0];

kn=0; kx=0;

for (i=0; i< n; i++)

if (a[i]> max) //cikl dlya nahozhdeniya naibolshego elementa //

{

kx=i;

max=a[i];

}

 

for (i=n; i> 0; i--) //cikl dlya nahozhdeniya naimenshego elementa //

if (a[i]< min)

{

min=a[i];

kn=i;

}

cout< < " max=" < < max< < " min=" < < min;

for (i=0; i< n; i++)

if (a[i]< 0)

{

otr=otr+a[i]; //podschet summi otric. elementov //

}

if (kn> kx)

{

s=1;

for (i=kn; i< kx; i++) s=s*a[i];

}

else

{

s=1;

for (i=kx; i> kn; i--) s=s*a[i];

}

 

cout< < " \n proizvedenie chlenov mezhdu max i min chlenami - " < < s;

cout< < " \n summa otric 4lenov - " < < otr;

getch();

return 0;

}


Генерация двумерных массивов

Принцип генерации двумерных массивов такой же, как и одномерных.

//Описание функции генерации массиваvoid gen(int str, int slb, int a, int b, int m[max_x][max_y]){ int i, j; srand(time(NULL)*1000); //устанавливает начальную точку генерации случайных чисел for (i=0; i< str; i++) for (j=0; j< slb; j++) m[i][j]=rand()%(b-a)+a); //функция генерации случайных чисел на [a, b)}

 

 

Ввод-вывод массива

Язык Си не имеет встроенных средств для ввода-вывода массива целиком, поэтому массив вводят и выводят поэлементно с помощью циклов, как, например, в следующей программе:

1. #include < stdio.h>

2.

3. void main(void)

4. {

5. double a[100]; int n, i;

6. printf(" Введите количество чисел n = " );

7. scanf(" %d", & n);

8. if( n> (sizeof a)/sizeof(double) )

9. { printf(" Слишком много элементов\n" ); return; }

10. for(i=0; i< n; i++)

11. {

12. printf(" a[%d] = ", i); scanf(" %lf", & a[i]);

13. }

14.

15. /* Операторы, обрабатывающие массив */

16.

17. }

 

 

Блок-схема ввода массива

 

#include < stdio.h> void main(void) { double a[100]; int n, i; printf(" Введите количество чисел n = " ); scanf(" %d", & n); if( n> (sizeof a)/sizeof(double) ) { printf(" Слишком много элементов\n" ); return; } for(i=0; i< n; i++) { printf(" a[%d] = ", i); scanf(" %lf", & a[i]); } /* Операторы, обрабатывающие массив */ }

Во многих случаях удобно возложить на программу подсчет числа элементов, вводимого массива, при этом ввод завершается при появлении во входном потоке признака конца данных. Таким признаком в следующей программе служит число большее 1.0e300

1. #include < stdio.h>

2.

3. void main(void)

4. {

5. double a[100], temp; int n, end;

6. for(end=n=0; n< (sizeof a)/sizeof(double); n++)

7. {

8. printf(" a[%d] = ", n); scanf(" %lf", & temp);

9. if( temp> =1.0e300 ) { end=1; break; }

10. a[n] = temp;

11. }

12. if( end )

13. {

14.

15. /* Операторы, обрабатывающие массив */

16.

17. }

18. else

19. printf(" Переполнение массива\n" );

20. }

 

#include < stdio.h> void main(void) { double a[100], temp; int n, end; for(end=n=0; n< (sizeof a)/sizeof(double); n++) { printf(" a[%d] = ", n); scanf(" %lf", & temp); if( temp> =1.0e300 ) { end=1; break; } a[n] = temp; } if( end ) { /* Операторы, обрабатывающие массив */ } else printf(" Переполнение массива\n" ); }

Вывод массива, содержащего большое количество элементов желательно производить в несколько строк с остановом после заполнения экрана.

Блок-схема вывода массива

 

Следующий фрагмент программы выводит массив строками по 5 элементов. После вывода 120 элементов программа останавливается для просмотра выдачи. Очередные 120 элементов выводятся после нажатия на любую клавишу.

1. for (i=0; i< n; i++)

2. {

3. printf(" %10.3lf ", a[i]);

4. if( (i+6) % 5 == 0 ) printf(" \n" );

5. if( (i+121) % 120 == 0 ) { getch(); clrscr(); }

6. }

for (i=0; i< n; i++) { printf(" %10.3lf ", a[i]); if( (i+6) % 5 == 0 ) printf(" \n" ); if( (i+121) % 120 == 0 ) { getch(); clrscr(); } }

Здесь стандартная функция clrscr() очищает экран.

Итак, основные выводы по вышеизложенной информации.

 

Свойства массивов:

1. В массиве хранятся отдельные значения, которые называются элементами.
2. Все элементы массива должны быть одного типа данных (int, float, char*...).
3. Все элементы хранятся в памяти последовательно, и первый имеет нулевой адрес.
4. Имя массива является константой и содержит адрес первого элемента массива.


Поделиться:



Популярное:

Последнее изменение этой страницы: 2017-03-08; Просмотров: 802; Нарушение авторского права страницы


lektsia.com 2007 - 2024 год. Все материалы представленные на сайте исключительно с целью ознакомления читателями и не преследуют коммерческих целей или нарушение авторских прав! (0.131 с.)
Главная | Случайная страница | Обратная связь