Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:

osnovyiprogrammirovaniyanac

.pdf
Скачиваний:
24
Добавлен:
12.03.2015
Размер:
1.46 Mб
Скачать

Гпава 9

Массивы

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

5, 10, -3, 72, 0, 27, 34 Мы можем записать эти числа в переменные:

as, vd, lop, f, kok, is, ddr.

Но лучше было бы придумать одно общее имя, а переменные пронумеровать (или, как еще говорят, проиндексировать), как в математике:

Ао, Аь А2, А3, А4, А5, А6

Вповседневной жизни мы тоже часто встречаемся с такой формой записи. В поезде, например, все места пронумерованы, а всех людей, которые едут в вагоне, можно назвать пассажирами. И обратиться к любому из них можно так: "Пассажир 2 места, предъявите билетик!".

Впрограммировании для удобства работы с данными одного типа введено понятие массива. Массив - это конечная совокупность данных одного типа, упорядоченных по значениям одного типа. Каждый элемент массива обозначается именем массива с индексом.

Как же правильно записать массив? В математике, физике, химии и других точных науках можно встретить следующие формы записи:

• с помощью нижних индексов:

А0, АЬА2, А3, А 4, А 5, А6;

• индексов заключенных в круглые скобки:

А(0), А(1), А (2), А (3), А (4), А (5), А (6);

• с помощью фигурных скобок:

{Ai}, 1=0,1,2, - п .

Вязыке С++ индексация производится при помощи квадратных скобок:

А[0], А [1], А [2], А[3], А[4], А[5], А[6],

где А - имя массива, а число, указанное в скобках, - индекс. Обратите внимание, нумерация начинается с нуля.

Если мы хотим использовать массив в программе, то необходимо его заранее объявить, как в случае с переменными. При объявлении массива нужно указать тип массива (т.е. тип хранящихся в нем переменных), имя массива и его размер. Имя массива должно быть подобрано по правилам создания имен идентификаторов. То есть в имени можно использовать только буквы, цифры и знак подчеркивания, и имя не должно начинаться с цифры. Общий дид описания массива следующий:

 

тип

и м я [ к о л и ч е с т в о

э л е м е н т о в ] ;

 

имер

,объявление

из

семи

целых

чисел:

int А[7];

Так как нумерация элементов начинается с 0, то последний доступный элемент массива а[6]. В языке С++ нет контроля при обращении за пределы массива, т.е. если мы напишем а[9], то программа скомпилируется и запустится, но значение, полученное из массива, в этом случае будет не определено. На самом деле мы получим число, находящееся в памяти на 10 месте от начала массива. А так как массиву отведено только 7 ячеек памяти, то значение, записанное на 10 позиции, определить нельзя.

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

60

программ может быть нарушена. Часто неправильная индексация массива приводит к зависанию ОС или даже к ее перезагрузке.

Можно описать сразу несколько массивов одного типа: int а[10], b[17], с[50];

char str[40], ch[5];

Размер массива (т.е. количество его элементов) должен быть задан целым положительным числом или числовой константой. Запись вида:

int i ?

int mas[i];

недопустима, так как i - это переменная, и компилятор не знает заранее, сколько памяти необходимо выделить для массива.

Правильное описание имеет вид: * const int n = 10;

int mas[n];

ИЛИ

int mas[10];

При описании массива его можно сразу инициализировать, т.е. задать всем элементам начальные значения:

double arg[3] = {3.56, 7.32, -0.01};

В этом случае arg[0] = 3.56, arg[l] = 7.32, arg[2] = -0.01. При инициализации размер массива можно не указывать (он автоматически определяется путем подсчета количества перечисляемых значений):

char str[] = { ' а ' , ' b ' , ' с ' , ' m ' , ' е ' , ' f ' } ;

Под массив str будет выделено 6 байт, т.к. каждый его элемент занимает 1 байт (тип char), а их всего шесть. И str[0] = :а', str[l] = 'b', ... str[5] = Т.

Элементы массива могут стоять как в левой, так и в правой части оператора присваивания и в выражениях. То есть их можно использовать точно так же, как и переменные:

Ь[3] = Ь[5]

+ 1;

*

sum += a[k];

 

 

f1 = mas[2 * i + 1] ;

Для последовательного обращения к элементам массива удобно использовать циклические конструкции.

Пример 9.1. Фрагмент программы, цель которого - заполнить массив значениями, которые вводит пользователь.

int i;

int mas[10];

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

scanf(

&mas[i] );

Пример 9.2. Фрагмент программы, цель которого - вывести массив значений на

экран:

int i;

int mas[10] ;

for( i = 0; i < 10; i++ ) printf{ "%i", mas[i] );

Пример 9.3. С клавиатуры вводятся значения массива, состоящего из 5 элементов. Найдите сумму всех элементов массива, а также первый максимальный элемент массива и его номер.

Решая эту задачу, следует обратить внимание на то, что условие требует нахождения именно первого максимального значения, так как их может быть несколько. К примеру, если все элементы массива меньше 9, а элементов со значением 9 два, то необходимо вывести номер элемента, введенного раньше.

6 1

int A[5],i,Summa=0,pos,max;//i - параметр цикла

//Summa - здесь будет храниться сумма

//max - максимальное значение среди элементов

//pos

- номер элемента

for( i=0;i<5;i++) //блок ввода

элементов массива

{

 

scanf("%i",&A[i]);

 

}

max = A[0];//предположим, что максимальный элемент введен первым pos=0;

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

{

Summa+=A[i];

 

 

8

if (A[i] > max

)//если текущий

элемент по

значению больше, чем

{

//максимальный,

то

 

max=A[i];

//изменяем значение максимума и

pos=i+l;

// запоминаем его номер

 

}

 

 

 

printf("CyMMa=%3i

Максимальное значение=%31

номер=%31\п",Summa,max,pos);

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

Массивы, с которыми мы работали до сих пор, содержали только одну строку - такие массивы называются одномерными. Но язык С++ позволяет создавать п-мерные массивы. К примеру, двумерный массив можно интерпретировать как матрицу. Каждая ячейка матрицы задается двумя индексами - номером столбца и строки. Трехмерный массив можно представить в виде куба. В нем уже будут три индекса - столбик, строчка и ряд. Пересечение соответствующих значений - ячейка в виде маленького куба, в котором хранятся данные. Массивы данных, описываемые более чем одним индексом, называют

многомерн ым и.

Объявление многомерного массива производится следующим образом:

тип

имя [размер!] [размер 2] ... [размер N ] ;

Например, чтобы объявить массивы, изображенные на рисунке, достаточно

написать:

 

int

а[б][б ];

double b[4][4][4];

Двумерный массив можно рассматривать как массив массивов. Действительно, каждая строчка - это одномерный массив. А матрица - это массив таких строчек. Чтобы обратиться к любому элементу массива, мы должны указать номер строчки, а затем номер позиции в строчке (столбец).

имя массива [номер строки ] [номер столбца]

Например:

а[0][0] = 10;

a[j][i] = a[i][j] + 4;

z = a[3][4]++;.

С трехмерным массивом ситуация аналогичная. Это есть не что иное, как массив таких матриц, выстроенных рядом. Добавляется еще одно измерение - номер матрицы. Обращение к элементам такого массива задается тремя индексами:

Ь[3][0][1] = 3.14;

f = b[i][j][k] + b[i][j][k];

b[0][0][3] *= 7.34;

По аналогии можно определить массив с любой размерностью (лишь бы памяти хватило). Данные "кубики" можно раздать студентам, и получится 4-мерный массив: новый индекс - номер студента. Студенты сидят в разных классах - номер класса - еще один индекс - в итоге получается 5-мерный массив. На каждом этаже института несколько таких классов. Номер этажа - еще одно измерение. Получили 6-мерный массив. И так можно продолжать бесконечно долго. Теперь, чтобы найти значение в определенном "кубике", надо задать номер этажа, номер класса на этом этаже, номер студента, сидящего в этом классе, а также номер столбца, строчки и ряда в его "кубике". Но на практике редко используются массивы с размерностью больше двух.

При объявлении многомерного массива, его элементам так же можно задать начальные значения:

int mas[2][3] = {{7, 6, 33}, {-4, 56, 0}}; int arr[][] = {{4, 5, 7}, {2, 4, 6}};

Для хранения массива выделяется непрерывный участок памяти. Если мы объявили двумерный массив целых чисел int а[2][3], то элементы этого массива будут лежать в памяти последовательно следующим образом: а[0][0], a[0][lj, а[0][2], а[1][0], а[1][1], а[1][2]. Обратите внимание на то, что быстрее всего изменяется самый правый индекс у массива.

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

int i, j;

int bob[10][20];

for(i = 0; i <

10;

i++)

 

{

 

 

 

//тело цикла_1

for(j = 0;

j <

20;

j++)

//оператор тела цикла_1

p r i n t f Г

%3i

",

b o b [ i ] [ j ] ) ;

//тело цикла_2

printf(" \n " ) ;

 

 

//оператор тела цикла_1

}

 

 

 

 

Этот фрагмент выводит на экран массив bob в виде матрицы. Для каждого значения переменной i выполняется 20 раз тело внутреннего цикла, т.е. выводится i-ая строка массива. Далее каждый раз после завершения этого цикла переходим на новую строку на экране, и для следующего значения переменной i повторяем те же действия.

Пример 9.4. Напишите программу, которая заполняет массив размером ЮхЮ значениями из квадрата Пифагора - таблицы умножения, а потом выводит его на экран.

/* Таблица умножения*/

 

 

const int n = 10;

//

размерность

массива

int a[n][n], i, j ;

 

 

 

for(i = 0 ; i < n;

i++)

 

 

forfj = 0; j < n; j++)

 

 

a[i][j] = (i +

1) * (j + 1 ) ; //

заполнение

таблицы умножения

63

f o r ( i = 0 ; i < n ; i + + )

 

{

 

f o r ( j = 0 ; j < n ;

 

p r i n t f ( " % 4 i " , a [ i ] [ j ] ) ;

// вызол : . ; а " ; : з = :-:a з к с а н

p r i n t f ( " \ n " ) ;

 

}

В работе с матрицами различают главную и побочную диагонали. Так. в матрице:

1 2 3

5 6 1 числа 1, 6 и 0 (они выделены жирным) составляют главную диагональ.

# 9 0 а числа 3, 6 и 8 (они выделены курсивом) - побочную.

Пример 9.5. Напишите программу, цель которой - в квадратной м а т р и ц е размером

5x5 элементов,

заполненной случайными

значениям, п о п е в а т ь

м е с т а м и

главную fi

побочную диагонали.

 

 

 

 

 

 

 

/* Меняем

в м а т р и ц е

м е с т а м и д и а г о н а л и */

 

 

c o n s t i n t

n =

5;

 

//

р а з м е р матрицы

 

 

i n t a [ n ] [ n ] ,

i ,

j ,

t m p ;

 

 

 

 

r a n d o m i z e ( ) ;

 

 

 

 

 

 

 

f o r ( i = 0 ; i < n ; i + + )

 

 

 

 

{

 

 

 

 

 

 

 

 

f o r ( j = 0; j < n; j + + )

 

 

 

 

{

 

 

 

 

 

 

 

 

a [ i ] [ j ]

=

r a n d o m ( 1 0 0 ) ;

/ /

з а п о л н я е м « а т р е щ у сщучамньми

числами

p r i n t f ( " % 3 i " , a [ i ] [ j ] ) ;

/ / и с р а з у ж е п е ч а т а е м е е

э к р а н

}

p r i n t f ( " \ п " ) ;

}

f o r ( i = 0 ; i < n ; i + + )

{

tmp = a [ i ] [ i ] ;

a [ i ] [ i ] = a [ i ] [ n - i - 1 ] ; a [ i ] [ n - i - 1 ] = t m p ;

}

?. - е с е м е н н о й tmp

• на диагонали

»

64

в

Задачи к главе 9.Массивы

Задача 9.1. Напишите программу, в ходе выполнения которой с клавиатуры вводится одномерный массив из 7 целых чисел и выводится количество ненулевых элементов. Перед вводом каждого элемента на экране должна появляться подсказка с его номером.

Задача 9.2. Напишите программу, которая выводит минимальный элемент введенного с клавиатуры одномерного массива целых положительных чисел. Если введен 0, то программа останавливает ввод и требует ввести вместо нуля любое положительное число.

Задача 9.3. Напишите программу, которая вычисляет среднее арифметическое ненулевых элементов введенного с клавиатуры одномерного массива. С клавиатуры вводится количество элементов и сами элементы массива целых чисел.

Рекомендуемый вид экрана:

Введите количество элементов массива: 3 Введите элементы массива:

А [ 0 ] - > 1

А[1]->0

А[2 ] - >2

Количество ненулевых элементов массива: 2

Среднее арифметическое ненулевых элементов массива: 1.5

Задача 9.4. Напишите программу, которая проверяет, находится ли в инициализированном в программе массиве введенное с клавиатуры целое число. Рекомендуемый вид экрана:

Массив: 12 3 4 5 8 9 Введите число: 5

Такое число есть среди элементов массива.

Задача 9.5. Напишите программу, которая проверяет, образуют ли элементы введенного с клавиатуры целочисленного массива возрастающую последовательность.

ь

Задача 9.6. Напишите программу, которая переставляет элементы введенного с клавиатуры целочисленного массива в убывающем порядке. Массив состоит из десяти элементов.

Задача 9.7. Напишите программу, которая вводит с клавиатуры двумерный массив и вычисляет сумму элементов по строкам и столбцам.

Задача 9.8. Напишите программу, которая позволит пользователю вводить матрицу так, как он записывал её на бумаге. Количество строк и столбцов матрицы вводятся во время выполнения программы.

Рекомендуемый вид экрана:

Введите

количество

строк

матрицы:

3

Введите

количество

строк

матрицы:

3

Введите

элементы матрицы:

 

<очистка

экрана>

 

 

 

1

2

 

3

 

 

 

 

4

 

5

6

 

 

 

 

7

 

8

9

 

 

 

 

Задача 9.9. Напишите программу, которая меняет местами элементы квадратной матрицы размера 4x4 относительно главной диагонали. Элементы матрицы вводятся с клавиатуры.

Задача 9.10. Напишите программу, которая обменивает местами две строки квадратной матрицы. Номера строк и элементы массива вводятся с клавиатуры.

Задача 9.11. Напишите программу игры «Угадай число». Компьютер «загадывает» трехзначное число, а пользователь пытается угадать его. На каждом шаге угадывающий делает предположение, а компьютер выводит, сколько цифр угадано и сколько из них находятся на своем месте.

Рекомендуемый вид экрана:

Компьютер «задумал» трехзначное

число.

 

Отгадайте его. Для завершения игры введите

число - 1 .

Ваш

вариант

123

Угадано:

0

На

своих местах:

0

Ваш

вариант

654

Угадано:

2

На

своих местах:

2

Ваш

вариант

954

Угадано:

1

На

своих местах:

1

Ваш

вариант

658

Угадано:

3

На

своих местах:

3

***

Вы выиграли

!***

 

 

 

 

Задача 9.12. Напишите программу, которая выводит на экран рисунок, получаемый при соединении линиями пяти точек. Координаты точек вводятся пользователем.

Задача 9.13. Используя двумерный массив, напишите программу, которая перемещает треугольник по экрану. Координаты вершин треугольника вводятся пользователем.

9

Гпава 10

Строки и указатели

Текст как этой, так и любой другой книги представляет собой определенную последовательность слов. Каждое слово есть последовательность букв. Исходя из этого, можно сказать, что буквы являются наименьшей единицей представления информации, то есть для хранения и обработки текстовой информации люди используют буквы. Компьютер, напротив, для обработки любой информации использует числа и не знает другого языка, кроме языка цифр. Для того чтобы связать две различные системы представления информации и таким образом обеспечить эффективное взаимодействие пользователя и машины, были предложены таблицы, в которых буквы и специальные символы (точка, тире, запятая и т.д.) имеют числовой эквивалент. В попытке стандартизации представления символов большинство производителей компьютеров проектируют их так, чтобы использовать одну из наиболее популярных кодирующих схем - ASCII (см. таблицу ASCII-кодов, Приложение 1). ASCII означает «Американский стандартный код для информационного обмена» («American Standart Code for Informational Interchange))). Существуют и другие схемы кодирования.

ASCII часто называют символьным кодом или символьным набором. Манипуляции символами на самом деле подразумевают манипуляцию соответствующими численными кодами, а не самими символами. Это объясняет взаимозаменяемость символов и малых целых (тип char) в С++.

Символьные переменные объявляются как и любые другие переменные С++:

char a,b,c;

Переменная инициализируется символьным значением, заключаемым в одиночные кавычки, или целочисленным значением, входящим в диапазон типа char:

char symb='A' ;

или так:

s

char symb = 65;

Инициализируя символьные переменные, следует учитывать регистр символов (прописная «А» и строчная «а» имеют различный код в таблице ASCII)

Самый простой способ ввода символов - чтение по одному символу с клавиатуры с помощью функции gercharQ. Она описана в библиотеке stdio.h и имеет вид:

int getchar();

Функция возвращает значение целого типа. Это число можно интерпретировать как ASCII-код введенного символа. Для того чтобы узнать, какой символ был введен с клавиатуры, необходимо объявить переменную целого типа (или типа char) и записать в нее результат, возвращаемый функцией:

char ch;

ch = getchar ( ) ;

Чтобы выводить символы на экран, используют функцию putchar(), которая описана в библиотеке stdio.h. Например:

putchar (ch); — выводит символ, записанный в переменную ch. putchar (6 8); — выводит символ с ASCII-кодом 68. Это буква 'А'.

putchar(32+4) ; — выводит символ с ASCII-кодом 36. Это '$'

Заметим, что для функции getchar() после выбора символа необходимо нажать клавишу <Enter>. Иногда это создает определенные неудобства. Функции getch() и getche() устраняют их. Они имеют следующий вид:

int getch(); int getche() ;

Обе эти функции вводят символ сразу же после нажатия клавиши (здесь не надо нажимать клавишу <Enter>). Отличие между ними заключается в том, что getcheQ отображает вводимый символ на экране дисплея, a getch() - нет. Описания этих функций находятся в файле conio.h.

Также символы можно вводить и выводить, используя функции scanf(): char symb;

scanf("%c",&symb);

и printf():

char symb='A';

printf("%c - %i ", symb, symb); //эта функция выведет символ и его

код.

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

Пример 10.L Напишите программу, которая посимвольно считывает текст, введенный с клавиатуры, и считает количество букв п в нем независимо от регистра. Условием окончания цикла является проверка введенного символа на код 13 (код клавиши <Enter>).

int counter = 0 ; // счетчик буквы "N" char ch = ' ' ; /./ буква текста while (ch 1= 13)

{

»

ch =

getche();

if(ch

== 1 N 1 || ch == 1 n')

counter++;

}

printf("\n Количество букв 'N' в тексте = %i \n", counter);

Пример 10.2. Вывести на экран все прописные буквы латинского алфавита. Поскольку прописные буквы латинского алфавита упорядочены, то можно составить следующий код:

char ch;

for(ch = 'A'; ch <= 'Z'; ch++) putchar(ch);

Строки определяются как массивы символов, то есть массивы типа char. При хранении строки последним ее символом является специальный символ с ASCII кодом 0, передаваемый как '\0'. Он не отображается на экране, однако хранится в последней ячейке, поэтому длина массива для хранения строки должна на единицу превышать ее длину. Если создать массив типа char определенной длины, например:

char str[80];

то в нем можно будет сохранить строку любой длины, не превышающей 79. Поместить строку в массив можно либо посимвольно (при этом не забыть про нулевой символ в 68

конце), либо с помощью стандартных функций. Также можно разместить строку при

создании массива, например:

char str[6] = { У Е ' , ' е ' , ' 1 ' , ' 1 ' , ' о ' } ;

либо так:

char str[6] = "Hello";

Как и в случае обычных массивов, здесь можно написать так: char str[] = { Х Н ' , ' е ' , ' 1 ' , ' 1 ' , 'о' };

либо так:

char str[] = "Hello";

В памяти элементы строки будут храниться, как показано на рисунке:

S T R [ 0 ]

//

не 1 1 0 \0

Однако и в этом случае длина массива определяется при его создании, и разместить в этом массиве более длинную строку не удастся. Поэтому рекомендуется создавать строки максимальной длины, то есть в 255 символов, даже если первоначально в нее записывается более короткая строка. В этом случае «лишние» ячейки будут выделены, но не будут использоваться, а в дальнейшем это позволит избежать многих проблем. Итак, рекомендуемый способ создания массива примерно такой:

char str[255] = " " ;

для изначально пустой строки и:

char str[255] = " С т р о ч к а

т е к с т а " ;

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

 

Пример 10.3. Напишите программу, которая выводит первое слово введенного с

клавиатуры предложения.

 

int i=0;

 

char symb[255];

 

scanf("%s",&symb);

 

while(i! = ' ' )

 

{

ь

printf("%c",symb[i]);

 

i++;

 

}

Пример 10.4. Напишите программу, которая заменяет строчные буквы их прописными эквивалентами.

int i=0;

char str[255 ] ;

scanf("%s",Sstr);

 

 

 

 

while(str[i]! = '\0' )

 

 

 

{

 

 

 

 

if(str[i]>='a')

str[i]-=32;

/ / с о г л а с н о

т а б л и ц е A S C I I , р а з н и ц а

между

i++;

//

строчными и

прописными буквами - 32

символа

}

 

 

 

 

printf("%s",str);

 

 

 

 

Строки также можно вводить-выводить, используя функции библиотеки stdio.h:

 

gets() - ввести строку:

,

char str[120 ] ;

 

gets(str);

 

и puts() - вывести строку:

 

char str[120];

 

puts(str);

 

69

Соседние файлы в предмете [НЕСОРТИРОВАННОЕ]