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

Алгоритмизация и программирование на языке С++. Ч.1. Учебник

.pdf
Скачиваний:
0
Добавлен:
07.09.2026
Размер:
2 Мб
Скачать
7. Циклы
case2l: cout << "\nEnd program " << endl;
Результат приведен на рис. 7.19.
Рис. 7.19. Использование операторов прерывания
в инструкции
101
switch-case
 
 
В С++ могут быть объявлены переменные с добавлением
*
префикса храниться адрес области памяти. Приведем пример.
int *p;
В переменной р будет храниться адрес. Но он пока не опре­делен. Так, связываем адрес с уже определенной переменной.
int Value = 10; p=&Value;
cout << " *p " << *p << " &p " << &p;
Такой фрагмент программы приведет, например, к тако­му результату:
*p = 10 &p = 0x6e00
Но второе число может меняться при последующих выпол­нениях. Это зависит от начального адреса загрузки программы. В приведенном примере адрес переменной в памяти выводится в шестнадцатеричной системе счисления. Расширим програм­му, добавив переменные разных типов (рис. 8.1).
char *pChar; int *pInt; oat *pFloat; char vChar='1'; int vInt=2; oat vFloat=3.0; pChar=&vChar; pInt=&vInt; pFloat=&vFloat;
. Последний определяет указатель. В нем должен
cout << " *pChar = " << *pChar << " &pChar = " << &pChar << endl; cout << " *pInt = " << *pInt << " &pInt = " << &pInt << endl; cout << " *pFloat = " << *pFloat << " &pFloat = " << &pFloat << endl;
Рис. 8.1. Указатели трех разных типов данных
8. Массивы
103
А вот такая инструкция
pChar = &vInt;
вызовет ошибку, так как предпринята попытка определить указатель на переменные разных типов:
[Error] cannot convert 'int*' to 'char*' in assignment
Указатель может использоваться при работе с функция­ми, примеры будут приведены в разделе 9.
Теперь приведем пример со ссылкой. Она должна указы­вать на значение сразу при ее объявлении. Например, такая инструкция
char &newChar;
вызовет ошибку:
[Error] 'newChar' declared as reference but not initialized
Если добавить такой текст
char v2Char;
char &newChar = v2Char; cout << endl << " newChar= " << newChar << endl;
будет выведено
newChar пусто
так как переменная не получила значения – пустой сим­вол.
А после таких инструкций
v2Char = '5'; cout << " newChar= " << newChar << endl;
будет выведено
newChar=5
Данные типа указатель часто используются для доступа к элементам массива. Массив – это структура данных, содер­жащая несколько значений одного типа, обозначаемая од­ним именем.
Приведем пример задания символьного массива и пока­жем, как получить доступ к его элементам, используя ука­затель.
Массив, состоящий из пяти элементов символьных зна­чений, можно задать так:
char cVal[5];
104
АЛГОРИТМИЗАЦИЯ ИПРОГРАММИРОВАНИЕ НАЯЗЫКЕ С++
Таким образом, сначала указывается тип элементов, за­тем имя и в квадратных скобках количество элементов. Эле­менты имеют имена от
cVal[0]
до
cVal[4]
.
Задавая массив таким образом, мы определяем массив ста­тически.
В противоположность этому массив можно задать динами­чески. Первый экономичен в смысле быстродействия, но не эко­номно использует память. Пусть стоит задача переноса части элементов одного массива в другой. Если у второго задать столь­ко же элементов, сколько и у первого, то часть элементов вто­рого будут не использованы. Это зависит от значений первого.
Динамический способ для задачи переноса части элемен­тов массива в другой не предполагает задания количества элементов массива при его объявлении. Можно даже сначала определить пустой массив. Но при необходимости добавить элемент ко второму массиву программа должна остановиться и получить место в памяти. Это потеря быстродействия при экономии памяти. В этом разделе мы будем использовать только статический способ определения массивов.
Задать значения элементов массива можно при его опре­делении. Это называется инициализацией при объявлении.
char cVal[5] = {'1', '2', '3', '4', '5'};
Эти значения могут быть выведены в цикле, например, так:
for(int i=0; i<5; i++)
cout << cVal[i] << " ";
Они будут выведены в строку. Если надо вывести их в стол­бец, надо инструкцию вывода записать так:
cout << cVal[i] << " " << endl;
Теперь покажем, как получать доступ к элементам масси­ва с использованием указателей. Определим указатель так:
char *pChar1;
Поместим в указатель адрес области памяти, где располо­жен массив.
pChar = cVal;
Если теперь вывести символьное значение по адресу ука­зателя, то получим первый элемент массива.
8. Массивы
105
pChar1 = cVal;
cout << *pChar1 << endl;
Обратим внимание, что у имени массива нет никаких пре­фиксов, а у имени указателя – символ звездочка (разыменова­ние указателя).
Значение указателей можно менять. При этом реализует­ся так называемая адресная арифметика. Если теперь указа-
pChar1
телю
присвоить такое значение
pChar1 = cVal + 2;
то будет выведено значение третьего элемента массива.
cout << *pChar1 << endl;
Можно указателю присвоить адрес любого из элементов массива. Например, так укажем не пятый элемент:
pChar1 = &cVal[4];
cout << *pChar1 << endl;
Обратим внимание на то, что при указании конкретного элемента перед его именем надо обязательно поставить пре-
&
фикс
. Напомним, что при создании указателя на массив ни­каких префиксов не используется. Теперь приведем код про­граммы, иллюстрирующий введенные понятия.
// Массив и указатель char cVal[5] = {'1', '2', '3', '4', '5'}; for(int i=0; i<5; i++)
cout << cVal[i] << " " ; // << endl; cout << endl;
char *pChar1;
pChar1 = cVal;
cout << *pChar1 << endl;
pChar1 = cVal + 2;
cout << *pChar1 << endl;
pChar1 = &cVal[4];
cout << *pChar1 << endl;
cout << endl;
106
АЛГОРИТМИЗАЦИЯ ИПРОГРАММИРОВАНИЕ НАЯЗЫКЕ С++
Результат приведен на рис. 8.2.
Рис. 8.2. Первый пример использования указателей
для доступа к массиву
Приведем еще один способ доступа к элементам массива
по указателю:
double dArr[] = { 1.0,2.1, 3.2, 4.3 };
cout << *(dArr + 2) << '\n';
// выводит 3.2 – значение эл-та с индексом 2
А такой фрагмент программы выводит все элементы массива:
double dArr[] = { 1.0,2.1, 3.2, 4.3 }; for (int i = 0; i < 4; i++)
cout << *(dArr + i) << " ";
Перейдем к рассмотрению типовых алгоритмов, которые могут быть частью, «кирпичиками» более сложных. При реа­лизации программ в большинстве случаев будем использовать инициализацию массивов при объявлении. Такие программы решают задачу только с одним набором исходных данных, но удобны легкой модификацией для анализа работы програм­мы с разными тестами.
 
Рассмотрим примеры использования массивов для реше­ния задач.
Вычислить среднее значение среди положительных членов последовательности чисел. Отметим, что для решения этой за­дачи необходимо просмотреть все элементы.
8. Массивы
Вообще говоря, если значения вводить с клавиатуры, эту задачу можно решить без использования массива:
int n, k, s; double x;
k=0; s=0.0; n=5; for (int i=0; i<n; i++)
{ cout << " input x " ; cin >> x;
if (x>=0) { k=k+1; s=s+x;
} }
s=s/(double (k) );
cout << " k s " << k << " " << s;
Результаты для различных исходных данных представ­лены на рис. 8.3 и 8.4.
107
Рис. 8.3. Среднее значение среди положительных.
Тест 1 – все элементы положительные
Рис. 8.4. Среднее значение среди положительных.
Тест 2 – все элементы отрицательные
108
АЛГОРИТМИЗАЦИЯ ИПРОГРАММИРОВАНИЕ НАЯЗЫКЕ С++
Как видно, значение переменной s во втором случае ока­залось некорректным. Следовательно, надо после выхода из цикла проанализировать, не осталось ли количество элемен-
k
нулевым. И если это так, то следует обойти деление на
тов значение этой переменной и вывести соответствующее сооб­щение.
Теперь покажем, как решить эту задачу с использовани­ем массива.
int n, k, s; double x[5]; k=0; s=0.0; n=5; for (int i=0; i<n; i++)
{ cout << " input x " ; cin >> x[i];
if (x[i]>=0) { k=k+1; s=s+x[i];
} }
if (k == 0) cout << " Нет положительных элементов" << endl;
else {
s=s/(double (k) );
cout << " k s " << k << " " << s; }
Результат представлен на рис. 8.5.
Рис. 8.5. Среднее среди положительных элементов массива
с использованием цикла
for
8. Массивы
109
В следующем фрагменте показано, как можно инициали­зировать массив (задать значения при объявлении) и исполь­зовать указатели на его элементы.
int n, k, s; double x[5] {1.0,2.0,3.0, –4.0, –5.0}; k=0; s=0.0; n=5; double *p; p=x; for (int i=0; i<n; i++)
{ cout << *p << " "; if ( *p > 0) {
k=k+1; s=s+x[i]; // Можно s=s+*p;
}
p=p+1;
}
cout << endl; // перенос вывода на новую строку if (k == 0) cout << " Нет положительных элементов " << endl;
else {
s=s/(double (k) ); cout << " k= " << k << " s=" << s;
}
Результат представлен на рис. 8.6.
Рис. 8.6. Среднее среди положительных элементов массива
с использованием указателей
Теперь приведем пример, в котором вводится массив сим­волов и выводятся их коды (рис. 8.7).
// Символьный массив char *cp; int n=5; char cx[5] {'0','a','1','z','9'}; cp=cx;
110
АЛГОРИТМИЗАЦИЯ ИПРОГРАММИРОВАНИЕ НАЯЗЫКЕ С++
cout << "Array char: " << " " << endl;
for (int i=0; i<n; i++)
{
cout << *cp << " " << (int)*cp << endl; cp=cp+1;
}
Рис. 8.7. Вывод кодов элементов символьного массива
Следующая задача формулируется так. Подсчитать коли­чество элементов массива меньших среднего.
int n, k, s; double x[5] {1.0,2.0,3.0,–4.0,–5.0}; k=0; double summa=0.0; n=5; double Sr;
cout << "Array: " << " ";
for (int i=0; i<n; i++)
{ cout << x[i] << “ “; }
for (int i=0; i<n; i++)
{
summa=summa+x[i];
}
Sr = summa / n; cout << endl << " Среднее= " << Sr << endl; int lessSr=0; for (int i=0; i<n; i++)
{
if (x[i] < Sr) lessSr = lessSr +1;
}
cout << endl << "Меньше среднего " << lessSr;
Соседние файлы в предмете [НЕСОРТИРОВАННОЕ]