Добавил:
Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
Програм-е на ЯВУ / Программирование на языках выского уровня, алгоритмические языки.doc
Скачиваний:
63
Добавлен:
11.04.2014
Размер:
1.74 Mб
Скачать

Массивы

Понятие массива, операции над массивами

Массив – это структурированный (составной) тип данных, состоящий из фиксированного количества элементов, имеющих один и тот же тип.

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

float Vector[10]; // вектор из десяти элементов

float Matrix[10][15]; // матрица из 10 строк и 15 столбцов

В языке Си не существует операций над массивами, например, нельзя скопировать один массив в другой за одно действие. Все операции над массивами выполняются поэлементно. Для этого у каждого элемента массива имеется свой индекс, по которому к нему можно обратиться.

Одномерные массивы

Объявление одномерного массива подразумевает резервирование компилятором необходимого количества памяти под массив. Выполняется это с помощью следующего оператора

int Mass[10]; // массив из 10 целых чисел

В результате резервируется непрерывная последовательность из 40 ячеек памяти (4*10). Логически же массив выглядит следующим образом

индексы

0

1

2

3

4

5

6

7

8

9

элементы

Обратите внимание, что первый элемент массива имеет индекс 0 – это особенность языка Си.

Одновременно с созданием массива его элементам можно задать инициализирующие значения, например, так

int Mass[10]= {1, 2, 3, 4, 5, 6, 7, 8, 9, 10};

или так

int Mass[]= {1, 2, 3, 4, 5, 6, 7, 8, 9, 10};

В обоих случаях результат будет одинаков

индексы

0

1

2

3

4

5

6

7

8

9

элементы

1

2

3

4

5

6

7

8

9

10

В последнем случае количество элементов массива определяется по длине списка инициализирующих значений.

После объявления массива можно либо записывать значения в элементы массива, либо их считывать.

Ниже приведен пример записи данных в элементы массива:

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

{ Mass[i]= i; }

Как результат в памяти будет получен массив Mass

индексы

0

1

2

3

4

5

6

7

8

9

элементы

0

1

2

3

4

5

6

7

8

9

А теперь, считаем данные из массива Mass в обратном порядке:

for(i= 9; i > 0; i--)

{ printf(“%d, ”, Mass[i]); }

printf(“%d”, Mass[0]);

Как результат этих действий на экране отобразится следующая последовательность чисел:

9, 8, 7, 6, 5, 4, 3, 2, 1, 0

Замечание 1. В языке Си нет контроля выхода за пределы массива. Например, следующий код с точки зрения языка программирования не является синтаксической ошибкой:

Mass[20]= 12; // семантическая, но не синтаксическая ошибка

A= Mass[10]; // семантическая, но не синтаксическая ошибка

Однако выход за пределы массива может привести к многочисленным ошибкам в программе. Поэтому в некоторых средах разработки, в том числе и в Microsoft Visual Studio 2005, имеются дополнительные механизмы для поиска таких ошибочных ситуаций.

Замечание 2. Массивы относятся к классу статических типов данных, т.е. их размерность не может изменяться в процессе работы программы. Кроме того, в языке Си размерность массива должна быть задана константным значением, т.е. следующий код является ошибочным:

// синтаксическая ошибка

int N;

scanf(“%d”, &N);

int Mass[N];

Представление строк в языке Си

В языке Си отсутствует специализированный тип данных для хранения строк. Строки в языке Си реализуются посредством массивом символов. Однако такой массив отличается от любого другого целочисленного массива тем, что последним элементом массива всегда является нуль-символ, код которого равен 0. По положению нуль-символа определяется фактическая длина строки.

Рассмотрим примеры создания строк и их заполнения:

// Первый вариант задания строки, используя строковую константу

// Размер массива определяется по длине строковой константы

char String[] = “Это пример”;

String

0

1

2

3

4

5

6

7

8

9

10

Э

т

о

п

р

и

м

е

р

\0

// Второй вариант задания строки, используя символьные константы

// Размер массива определяется по количеству символов

char String[] = {‘Э’, ‘т’, ‘о’, ‘ ’, ‘п’, ‘р’, ‘и’, ‘м’, ‘е’, ‘р’,

‘\0’};

String

0

1

2

3

4

5

6

7

8

9

10

Э

т

о

п

р

и

м

е

р

\0

// Третий вариант задания строки. Создается массив для хранения 12

// символов (нуль-символ не считаем), а используем только 10

char String[13] = “Это пример”;

String

0

1

2

3

4

5

6

7

8

9

10

11

12

Э

т

о

п

р

и

м

е

р

\0

×

×

// Четвертый вариант задания строки. Строка вводится с клавиатуры

char String[13] = “”;

scanf(“%s”, &String); // предположим пользователь ввел строку

// “Это пример”

String

0

1

2

3

4

5

6

7

8

9

10

11

12

Э

т

о

п

р

и

м

е

р

\0

×

×

Для реализации наиболее часто используемых операций над строками в языке Си имеется ряд библиотечных функций. Далее приводится неполный перечень этих функций.

Библиотека string.h:

Функция

Описание функции

strcmp()

Сравнивает две строки

strncmp()

Сравнивает части двух строк

strcat()

Склеивает две строки

strncat()

Добавляет к строке заданный символ

strchr()

Находит первое вхождение в строку заданного символа

strrchr()

Находит последнее вхождение заданного символа

strstr()

Находит первое вхождение заданной строки

strcpy()

Копирует одну строку в другую

strncpy()

Копирует часть одной строки в другую

strdup()

Удваивает строку

strlen()

Определяет длину строки

strlwr()

Переводит всю строку в нижний регистр

strupr()

Переводит всю строку в верхний регистр

strnset()

Создает строку из N заданных символов

isaplha()

Библиотека stdio.h:

gets()

Считывает строку с клавиатуры

puts()

Выводит строку на экран

sprintf()

Преобразует число в строку

sscanf()

Преобразует строку в число

Библиотека stdlib.h:

atof()

Преобразует строку в double

atoi()

Преобразует строку в int

atol()

Преобразует строку в long int

_itoa()

Преобразует int в cтроку

_ltoa()

Преобразует long int в cтроку

_gcvt()

Преобразует double в cтроку

Окончание занятия №8 (лекция)

Рассмотрим пример программы, использующей вышеназванные библиотечные функции:

char String[41], FIO[31]; // объявляем строки, предполагая, что

// фамилия и инициалы человека не

// превышают 30 символов

// Просим ввести ФИО

puts(“Введите Вашу фамилию и инициалы = ”);

gets(FIO);

// Формируем сообщение и распечатываем его

strcpy(String, “Вас зовут ”); // String= “Вас зовут ”

strcat(String, FIO); // String= String + FIO

puts(String);

Замечание. Использование нуль-символа приводит к тому, что для представления строки длиной N символов нужен массив размерности N+1 (внимательно просмотрите предыдущие примеры).

Окончание занятия №9 (практика)

Двумерные массивы

Среди многомерных массивов наибольшую популярность имеют двумерные массивы.

Двумерный массив объявляется следующим образом:

int Mass[3][5]; // матрица целых чисел 35

Mass

0

1

2

3

4

0

1

2

Инициализация двумерного массива осуществляется таким образом:

int Mass[3][5]= {{ 1, 2, 3, 4, 5},

{ 6, 7, 8, 9, 10},

{11, 12, 13, 14, 15}};

С логической точки зрения результат выглядит так

Mass

0

1

2

3

4

0

1

2

3

4

5

1

6

7

8

9

10

2

11

12

13

14

15

Однако в памяти двумерный массив располагается в последовательных ячейках построчно:

Mass

0

1

2

3

4

5

6

7

8

9

10

11

12

13

14

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

В заключение рассмотрим операции записи и чтения данных в двумерном массиве:

Mass[2][4]= 20; // записываем в последний элемент массива константу

Mass

0

1

2

3

4

0

1

2

3

4

5

1

6

7

8

9

10

2

11

12

13

14

20

Mass[1][3]= Mass[1][3] + 1; // измененяем значение элемента массива

Mass

0

1

2

3

4

0

1

2

3

4

5

1

6

7

8

10

10

2

11

12

13

14

20

printf(“%d”, Mass[1][2]); // распечатываем значение элемента

// массива (будет распечатано число 8)

Использование двумерных массивов для хранения текста

Многострочный текст представляется двумерным массивом типа char, каждая строка которого соответствует строке (или предложению) текста. Соответственно количество строк массива должно соответствовать максимальному количеству строк (предложений) текста, а ширина массива – максимальному количеству символов в строке (предложении) текста.

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

// Многострочный текст, состоящий не более чем из пяти строк, в

// каждой строке не более 80 символов

char Text[5][81]= { “Написание хороших программ”,

“требует ума, вкуса и терпения.”,

“Б. Страуструп”, “”, “” };

Text

0

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

80

0

Н

а

п

и

с

а

н

и

е

х

о

р

о

ш

и

х

п

р

о

г

р

а

м

м

\0

1

т

р

е

б

у

е

т

у

м

а

,

в

к

у

с

а

и

т

е

р

п

е

н

и

я

.

\0

2

Б

.

С

т

р

а

у

с

т

р

у

п

\0

3

\0

4

\0

Подобного результата можно добиться, используя ввод данных с клавиатуры:

// Многострочный текст, состоящий не более чем из пяти строк, в

// каждой строке не более 80 символов

char Text[5][81]= { “”, “”, “”, “”, “” };

int i;

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

{ scanf(“%s”, Text[i]); }

Многомерные массивы

В языке Си могут создаваться массивы большей размерности, чем двумерные.

Рассмотрим, как в трехмерном массиве можно постранично хранить содержание книги и подсчитаем количество символов в книге:

char Book[700][41][73]; // массив символов книги: в книге не более

// 700 страниц по 41 строке; в каждой строке

// до 72 символов

// Количество выделенной памяти = 700  41  73 = 2 095 100 байт

//(максимальное количество символов в книге)

int SymbolCount; // фактическое кол-во символов

int i, j;

SymbolCount= 0;

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

{

for(j= 0; j < 41; j++)

{ SymbolCount += strlen(Book[i][j]); }

}

printf(“В книге %d символов”, SymbolCount);

Окончание занятия №10 (лекция)