правила стандартных арифметических преобразований




Исходный тип Преобразуется в Правила преобразований
char int Расширение нулем или знаком в зависимости от умолчания для char
unsigned char int Старший байт заполняется нулем
signed char int Расширение знаком
short int Сохраняется то же значение
unsigned short unsigned int Сохраняется то же значение
enum int Сохраняется то же значение
битовое поле int Сохраняется то же значение

 

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

  1. Все короткие целые типы преобразуются в типы наименьшей длины в соответствии с таблицей. Затем оба значения, участвующие в операции, принимают тип int или float либо double в соответствии со следующими правилами.
  2. Если один из операндов имеет тип long double, то второй тоже будет преобразован в long double.
  3. Если п.2 не выполняется и один из операндов есть double, другой приводится к типу double.
  4. Если пп.2-3 не выполняются и один из операндов есть float, другой приводится к типу float.
  5. Если пп.2-4 не выполняются (оба операнда целые) и один операнд long int, а другой unsigned int, то, если long int может представить все значения unsigned int, последний преобразуется к long int; иначе оба операнда преобразуются к unsigned long int.
  6. Если пп.2-5 не выполняются и один операнд есть long, другой преобразуется к long
  7. Если пп.2-6 не выполняются и один из операндов есть unsigned, другой приводится к типу unsigned.
  8. Если пп.2-7 не выполнены, то оба операнда принадлежат типу int

Используя арифметические выражения, следует учитывать приведенные правила и не попадать в "ловушки" преобразования типов, т.к. некоторые из них приводят к потерям информации, а другие изменяют интерпретацию битового (внутреннего) представления данных.

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

В C++ есть операция нахождения остатка от деления. Операция целочисленного деления как отдельная отсутствует. Вместо этого применяют обычное деление, но с приведением к целым типам.

Например, 15 / 3 = 5; 18 / 5 = 3; 123 / 10 = 12, 7 / 10 = 0. Но! 18 / 5.0 = 3.6, 7.0 / 10 = 0.7

С помощью операции % можно найти остаток от деления одного целого числа на другое.

Например, 15 % 3 = 0; 18 % 5 = 3; 123 % 10 = 3, 7 % 10 = 7.

При записи алгебраических выражений используют арифметические операции (сложение, умножение, вычитание, деление), функции из библиотеки math.h, круглые скобки.

Математические функции из библиотеки math.h

Математическая запись Запись на C++ Назначение
cos x cos(x) Косинус x радиан
sin x sin(x) Синус x радиан
tg x tan(x) Тангенс x радиан
ch x cosh(x) Гиперболический косинус x радиан
sh x sinh(x) Гиперболический синус x радиан
th x tanh(x) Гиперболический тангенс x радиан
arccos x acos(x) Арккосинус числа x
arcsin x asin(x) Арксинус числа x
arctg x atan(x) Арктангенс числа x
e x exp(x) Значение e в степени x
xy pow(x,y) Число x в степени y
| x | fabs(x) Модуль числа x
sqrt(x) Квадратный корень из x
ln x log(x) Натуральный логарифм x
log10 x log10(x) Десятичный логарифм x

Примеры записи математических выражений:

Математическая запись Запись на C++
1. x 2 – 7 x + 6 pow(x,2) - 7 * x + 6
2. (fabs(x) - fabs(y)) / (float)(1 + fabs(x * y))
3. log(fabs((y - sqrt(fabs(x))) * (x - y / (z + pow(x,2) / 4.0))))

Логический операнд — это конструкция соответствующего языка программирования, которая задает правило для вычисления одного из двух возможных значений: Истина или Ложь.

В отличии от языка Pascal в С++ нет логического типа - вместо него используется 0 в качестве Лжи и отличное от нуля число в качестве Истины. Составными частями логических выражений могут быть: числа (0 или неравные ему), отношения.

Например, 1) Y = 0; 2) Z = 1; 3) LogPer = A > B; 4) Log1 = (A = = B) && (C < = D).

Как видно из примеров, отношение — это два выражения, разделенных между собой знаком операции отношения (>, <, = =,!=, <=, >=). Отношение является простейшей конструкцией логического выражения. Оно вычисляет результат отличный от нуля, если выполняется заданное соотношение, и 0 — в противном случае.

Примечание. Несмотря на то, что операции отношения ==,!=, >=, <= определены для вещественных типов, реально они в большинстве случаев корректно не работают в силу того, что множество вещественных величин, представимых в памяти ЭВМ, дискретно. Поэтому их следует, если это возможно, избегать. В том случае, когда всё-таки для вещественных возникает необходимость вычисления указанных отношений, разумно проверять вещественные величины не на равенство, а на близость расположения друг к другу, т.е. заменять отношения вида A == B отношениями вида |A-B|<E, где E — достаточно малое по абсолютной величине число (в общем случае — так называемое машинное епсилон).

В языке С++ операции отношения определены для целых и вещественных типов. Операции отношения могут быть выполнены также над символьными переменными. Сравнение идет по индексам в соответствии с лексикографической упорядоченностью в таблице кодов ASCII. Эта упорядоченность предполагает, что "1"<"2", "a"<"b", "B"<"C" и т.д.

Логическое выражение — это логический операнд или последовательность логических операндов, разделенных между собой знаками логических операций (!, &&, ||).

Порядок действий при вычислении значения логического выражения в Си++:

  1. вычисляются значения в скобках;
  2. вычисляются значения функций;
  3. выполняется унарная операция — отрицание(!);
  4. выполняются операции отношения;
  5. выполняется операция &&;
  6. выполняются операции ||.

Действия выполняются слева направо с учетом их старшинства. Желаемая последовательность операций обеспечивается путем расстановки скобок в соответствующих местах выражения.

Рассмотрим примеры задач, где алгоритм решения является линейным.

Задача 1. Скорость первого автомобиля v1 км/ч, второго — v2 км/ч, расстояние между ними s км. Какое расстояние будет между ними через t ч, если автомобили движутся в разные стороны?

Согласно условию задачи искомое расстояние s 1= s +(v 1+ v 2) t (если автомобили изначально двигались в противоположные стороны) или s 2=|(v 1+ v 2) t-s| (если автомобили первоначально двигались навстречу друг другу).

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

Заметим, что идентификатор должен начинаться с латинской буквы, кроме латинских букв может содержать цифры, знак подчеркивания (_).

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

Для всех величин в программе объявлен тип float, что связано со стремлением сделать программу более универсальной и работающей с как можно большими наборами данных.

Задача 2. Записать логическое выражение, принимающее значение 1, если точка лежит внутри заштрихованной области, иначе — 0.

Прежде всего обратим внимание на то, что эту сложную фигуру целесообразно разбить на несколько более простых: треугольник, лежащий в I и IV координатных четвертях и треугольник, лежащий во II и III четвертях. Таким образом, точка может попасть внутрь одной из этих фигур, либо на линию, их ограничивающую. Количество отношений, описывающих какую-либо область, обычно совпадает с количеством линий, эту область ограничивающих. Чтобы точка попала внутрь области, необходима истинность каждого из отношений, поэтому над ними выполняется операция AND. Так вся область была разбита на несколько, то между отношениями, описывающими каждую из них, используется операция OR.

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

(X >= 0) && (Y >= 1.5 * X – 1) && (Y <= X)

|| (X <= 0) && (Y >= –1.5 * X – 1) && (Y <= –X)

Задача 3. Вычислить значение выражения

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

 

Контрольные вопросы и задания

1. Что такое величина?

2. Какие величины называют аргументами? результатами? промежуточными величинами? Приведите примеры.

3. Каковы атрибуты величины?

4. Какие величины называют постоянными? переменными? Приведите примеры.

5. Какие простые типы величин существуют в языке C++?

6. Что определяет тип величины?

7. Расскажите о простых типах данных и их атрибутах.

8. Как осуществляется потоковый ввод данных в языке C++? Приведите примеры.

9. Как осуществляется потоковый вывод данных в языке C++? Приведите примеры.

10. Какова общая структура программы в языке C++?

11. Расскажите об операторе присваивания и преобразовании типов.

12. Что такое формат вывода?

13. Расскажите о правилах вычисления алгебраического выражения. Приведите прмеры.

14. Расскажите о правилах вычисления логического выражения. Приведите прмерыи.

15. Расскажите о логических операциях. Приведите примеры.

16. Приведите примеры задач, имеющих линейный алгоритм решения.

17. Определите, какой суммарный объём памяти требуется под переменные в каждом из примеров 1–3 в вышеприведенном тексте.

18. Каково назначение следующей программы?

// программа Example

#include <iostream.h>

void main()

{

int n;

cout << "Введите натуральное трёхзначное число: ";

cin >> n;

cout << "Искомая величина: " << N / 100 + N / 10 % 10 + N % 10;

}

19. Задайте на координатной плоскости некоторую область, которую можно описать математическими уравнениями и заштрихуйте её. Запишите логическое выражение, принимающее значение 1, если точка (x, y) лежит внутри заштрихованной области, иначе — 0.

20. Выпишите несколько алгебраических выражений и запишите их на языке C++.

21. Запишите алгебраические выражения, соответствующие следующим записям на языке C++:

а) (a + b) / c; б) a + b / c; в) a / b / c; г) a / (b * c);

д) (a + b) / (d + c); е) a + b / (d + c);

ё) a + b / d + c; ж) (a + b) / d + c.

Условный оператор. Полная и неполная развилка. Переключатель

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

if (выражение) серия1; else серия2;

Если выражение, выступающее в качестве условия, принимает значение 0, то выполняются операторы, расположенные после else (серия2), если отлично от нуля, — операторы, после if. При записи логического выражения следует избегать знака = = (равно) для действительных переменных (double), так как они представляются неточно, а поэтому может не произойти совпадений значений выражений, стоящих слева и справа от знака равно. Для устранения указанного недостатка следует требовать выполнения условия с заданной точностью, т.е. вместо отношения X = = Y рекомендуется, например,

fabs(X - Y) < 1E-8.

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

if (логическое выражение) серия;

Условный оператор реализует разветвление вычислительного процесса по двум направлениям, одно из которых осуществляется при выполнении условия, другое — в противном случае. Для реализации разветвлений более чем по двум направлениям необходимо использовать несколько условных операторов. Рассмотрим примеры.

 

Задача 1. Даны действительные числа x, y. Если x и y отрицательны, то каждое значение заменить модулем; если отрицательно только одно из них, то оба значения увеличить на 0,5; если оба значения неотрицательны и ни одно из них не принадлежит отрезку [0,5; 2,0], то оба значения уменьшить в 10 раз; в остальных случаях x и y оставить без изменения.

Разработаем алгоритм решения задачи, после чего напишем программу. Алгоритм запишем словесно:

  1. ввести значения x, y;
  2. если x<0 и y<0, найти их Классы и перейти к п. 5, иначе перейти к следующему пункту;
  3. если x<0 или y<0, увеличить каждую величину на 0,5 и перейти к п. 5,иначе перейти к следующему пункту;
  4. если ни x, ни y не принадлежат отрезку [0,5; 2,0], уменьшить их в 10 раз;
  5. вывести значения x и y;
  6. конец.

function changeProof(proofobj) { if (proofobj.style.display=='none') {proofobj.style.display='inline'} else {proofobj.style.display='none'} } Листинг решения

// программа условие1   #include <iostream.h> #include <math.h>   void main() { double x,y; cout << "'Введите два действительных числа "; cin >> x >> y; if((x<0)&&(y<0)) { x = fabs(x); y = fabs(y); } else { if((x<0)||(y<0)) { x += 0.5; y += 0.5; } else { if(!(((x>=0.5)&&(x<=2.0))||((y>=0.5)&&(y<=2.0)))) { x /= 10.0; y /= 10.0; } } } cout << "Результат: "; cout.width(6); cout << x << " " << y; }

Задача 2. Дано действительное число a. Вычислить f(a), если

function changeProof(proofobj) { if (proofobj.style.display=='none') {proofobj.style.display='inline'} else {proofobj.style.display='none'} } Листинг решения

  // программа условие2   #include <iostream.h> #include <math.h>   void main() { double a,f; cout << "Введите действительное число: "; cin >> a; if(a <= 0) f = 0; else if(a <= 1) f = a*a-a; else f = a*a - sin(3.14*a*a); cout.width(6); cout << "Значение функции F(x) при x = " << a << " равно " << f; }

Кроме условного оператора в качестве управляющей структуры довольно часто используется переключатель switch. Эта структура позволяет переходить на одну из ветвей в зависимости от значения заданного выражения (селектора выбора). Ее особенность состоит в том, что выбор решения здесь осуществляется не в зависимости от истинности или ложности условия, а является вычислимым. Переключатель позволяет заменить несколько операторов развилки (в силу этого его ещё называют оператором множественного ветвления).

В конструкции switch вычисляется выражение K и выбирается ветвь, значение метки которой совпадает со значением K. После выполнения выбранной ветви происходит выход из конструкции switch по метке break. Если в последовательности нет метки со значением, равным K, то управление передается по метке default, если он присутствует, если же его нет, то следующему за переключателем оператору.

Запись переключателя:

switch (K)

{

case константа1: опрераторы1; break;

case константа2: опрераторы2; break;

...

default: опрераторы_default

}

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

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

Поскольку цикл является двенадцатилетним, поставим название года в соответствие остатку от деления номера этого года на 12. function changeProof(proofobj) { if (proofobj.style.display=='none') {proofobj.style.display='inline'} else {proofobj.style.display='none'} }

Листинг решения

  // программа горосокоп   #include <iostream.h>   void main() { int year; cout << "введите год: "; cin >> year; switch (year%12) { case 0: cout << "Год Обезьяны"; break; case 1: cout << "Год Петуха"; break; case 2: cout << "Год Собаки"; break; case 3: cout << "Год Свиньи"; break; case 4: cout << "Год Крысы"; break; case 5: cout << "Год Коровы"; break; case 6: cout << "Год Тигра"; break; case 7: cout << "Год Зайца"; break; case 8: cout << "Год Дракона"; break; case 9: cout << "Год Змеи"; break; case 10: cout << "Год Лошади"; break; case 11: cout << "Год Овцы"; break; } }

Задача 2. Найти наибольшее из двух действительных чисел, используя переключатель. function changeProof(proofobj) { if (proofobj.style.display=='none') {proofobj.style.display='inline'} else {proofobj.style.display='none'} }

Листинг решения

  // программа максмум   #include <iostream.h>   void main() { int x,y,max; cout << "Введите два неравных числа"; cin >> x >> y; switсh (x>y) { case 1: max = x; case 0: max = y; } cout << "Максимальное из них есть " << max; }

 

Контрольные вопросы и задания

  1. Когда возникает необходимость в организации развилки?
  2. Какая развилка называется полной? неполной?
  3. Выражение какого типа может выступать в качестве условия при организации развилки? Какие значения принимают такие выражения?
  4. Могут ли в полной развилке не выполниться операторы ни по одной из ветвей? выполниться по обеим ветвям?
  5. Записать примеры 1-3 по теме "переключатель" с помощью условного оператора. Сколько развилок понадобилось в каждом из случаев?
  6. В каком случае целесообразно использовать переключатель?
  7. Используя переключатель, решить задачу: "Определить знак заданного целого числа".

Циклы

Командой повторения или циклом называется такая форма организации действий, при которой одна и та же последовательность действий повторяется до тех пор, пока сохраняется значение некоторого логического выражения. При изменении значения логического выражения на противоположное повторения прекращаются (цикл завершается).

Для организации цикла необходимо выполнить следующие действия:

  • перед началом цикла задать начальное значение параметра;
  • внутри цикла изменять параметр цикла с помощью оператора присваивания;
  • проверять условие повторения или окончания цикла;
  • управлять циклом, т.е. переходить к его началу, если он не закончен, или выходить из цикла в противном случае.

Различают циклы с известным числом повторений (цикл с параметром) и итерационные (с пред- и постусловием).

В цикле с известным числом повторений параметр изменяется в заданном диапазоне.

Если в цикле изменяется простая переменная, то она является параметром цикла; если в цикле изменяется переменная с индексом, то индекс этой переменной является параметром цикла.

Для организации цикла с известным числом повторений в C++ используется оператор for.

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

for (выражение_1; выражение_2; выражение_3) тело_цикла

Здесь выражение_1 — инициализирующее; выражение_2 - аналог логического завершения (пока не равно нулю); выражение_3 - изменяет параметры цикла. Каждое выражение может состоять из нескольких операторов разделенных оператором запятой.

Все операторы "выражения" могут быть пропущены, но при этом внутри цикла должен иметься их аналог. Например конструкция

for(;;)

означает бесконечный цикл.

Задача 1. Дано натуральное n, действительное x. Вычислить

Разработаем алгоритм решения задачи:

  1. ввести данные - количество слагаемых n и число x;
  2. присвоить переменной, в которой будем хранить степени sin x, значение 1; S:= 0;
  3. присвоить параметру цикла значение 1;
  4. если значение параметра цикла меньше n, перейти к следующему пункту, иначе к п. 9;
  5. вычислить очередную степень sin x;
  6. добавить вычисленное значение к сумме;
  7. увеличить параметр цикла на 1;
  8. перейти к п.4;
  9. вывести на печать сумму S;
  10. конец.

function changeProof(proofobj) { if (proofobj.style.display=='none') {proofobj.style.display='inline'} else {proofobj.style.display='none'} } Листинг решения

// Программа вычисления суммы степеней sin x}   #include <iostream.h> #include <math.h>   void main() { float S, X, Pr; int N; cout << "Введите число слагаемых и x: "; cin >> N >> X; Pr = 1; S = 0; for(int i=1; i<=N; i++) { Pr *= sin(X); S += Pr; } cout.width(4); cout << "Сумма равна " << S; }

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

 

while (выражение) <тело цикла>;

 

do <тело цикла> while (выражение);

Для оператора цикла с предусловием проверяется значение логического выражения, если оно имеет значение отличное от нуля, то операторы, входящие в цикл, выполняются, в противном случае осуществляется выполнение оператора, следующего за циклом.

Цикл с постусловием выполняется хотя бы один раз. Затем проверяется значение логического выражения, если оно отлично от нуля, то операторы, входящие в цикл, выполняются, в противном случае осуществляется выход из цикла.

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

Задача 2. Найти наименьший номер члена последовательности, для которого выполняется условие |an-an-1| < e, где an=arctg an-1+1, a1=0. Вывести на экран этот номер и все элементы ai (i = 1, 2,..., n).

Поскольку по ходу решения задачи необходимо знать an и an-1, будем запоминать их соответственно в переменных ANew и AOld.

function changeProof(proofobj) { if (proofobj.style.display=='none') {proofobj.style.display='inline'} else {proofobj.style.display='none'} } Листинг решения

// программа последовательность   #include <iostream.h> #include <math.h>   void main() { int N; float Eps, AOld, ANew; AOld = 0; ANew = atan(AOld) + 1; N = 2; cout << AOld << " " << ANew; while(fabs(ANew - AOld) >= Eps) { AOld = ANew; ANew = atan(AOld) + 1; cout << " " << ANew; N++; } cout << "Искомый номер " << N; }

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

Задача 3. На интервале [2; n] найти натуральное число с максимальной суммой делителей.

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

Алгоритм решения задачи:

  1. ввести число n;
  2. переменной для хранения максимальной суммы делителей присвоить значение 1 (это сумма делителей числа 1);
  3. запомнить число с максимальной суммой делителей;
  4. параметру цикла I присвоить значение 2;
  5. если I больше n, перейти к п. 13, иначе - к следующему пункту;
  6. переменной для хранения очередной суммы делителей присвоить значение 0;
  7. параметру цикла K присвоить значение 1;
  8. если K больше I/2, перейти к п. 11, иначе - к следующему пункту;
  9. если I делится на K без остатка, добавить K к текущей сумме делителей;
  10. увеличить K на 1 и перейти к п. 8;
  11. сравнить текущую сумму делителей с максимальной, если максимальная меньше, запомнить новое значение и число, соответствующее этой сумме;
  12. увеличить I на 1 и перейти к п. 5;
  13. вывести число с максимальной суммой делителей и эту сумму;
  14. конец.

function changeProof(proofobj) { if (proofobj.style.display=='none') {proofobj.style.display='inline'} else {proofobj.style.display='none'} } Листинг решения

// программа максимальная сумма делителей #include <iostream.h> #include <math.h>   void main() { int N, Sum_Max, Sum, Ch; cout << "Введите число N: "; cin >> N; Sum_Max = 1; /*Максимальная сумма делителей*/ Ch = 1; /*Число с максимальной суммой делителей*/ for(int i = 2; i<= N; i++) /*Это цикл по количеству чисел*/ { Sum = 0; for (int k= 1; k<= i/2 + 1; k++) /*В этом цикле находим сумму делителей*/ if(i % k == 0) /*Если i нацело делится на k, то k - делитель i*/ Sum += k; Sum += i; if (Sum > Sum_Max) { Sum_Max = Sum; Ch = i; } } cout << "Максимальную сумму делителей " << Sum_Max << " имеет число " << Ch; }

Задача 4. Дано натуральное число n. Получить все простые делители этого числа.

function changeProof(proofobj) { if (proofobj.style.display=='none') {proofobj.style.display='inline'} else {proofobj.style.display='none'} } Листинг решения

// Программа отыскания простых делителей данного числа #include <iostream.h> #include <math.h>   void main() { int N, I, Vsp, Log_Per, Priznak; cout << "Введите натуральное число: "; cin >> N; Priznak = 1; /*Признак того, не является ли введенное число простым*/ /*Пока параметр цикла не превысил квадратного корня из данного числа, продолжаем поиск простых делителей*/ for(I = 2; I<= floor(sqrt(N)); I++) if (N % I == 0) { Priznak = 0; /*Введенное число не является простым*/ Log_Per = 0; /*Логическая переменная, принимающая значение True, если нашлись делители I, отличные от 1 и I*/ Vsp = 2; do { if (I % Vsp == 0) Log_Per = 1; Vsp++; } while ((Vsp < I) && (Log_Per!=1)); if ((Log_Per!=1)||(i==2)) cout << I; /*Если число I простое, печатаем его*/ } if (Priznak) cout << N; }

Предлагаем читателю самостоятельно разобраться с представленным решением.

 

Контрольные вопросы и задания

  1. Назовите отличия итерационных циклов и цикла с параметром.
  2. Какова структура оператора цикла с параметром? Как выполняется цикл с парметром?
  3. Какого типа должны быть пареметр цикла, его начальное и конечное значения в цикле с параметром в языке Pascal?
  4. Могут ли параметр цикла, его начальное и конечное значения в цикле с параметром в языке C++ быть разных типов? Обоснуйте ответ.
  5. Может ли один цикл быть вложен внутрь другого? Если да, то какова глубина этой вложенности?
  6. Какова структура циклов с пред- и постусловием? как выполняются эти циклы?
  7. Каково минимальное и максимальное количество исполнений циклов с пред- и постусловием? С чем это связано?
  8. Сколько раз исполнится фрагмент программы?

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

  1. Сколько раз исполнится фрагмент программы?

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

  1. Сколько раз исполнится фрагмент программы?

for (i = 1; i <= -1; i--) k = k * i;

  1. Сколько раз исполнится фрагмент программы?

M = 123; While (M!= 0) M = M % 10;

  1. Для цикла с параметром запишите его полный эквивалент с помощью циклов с пред- и постусловием.
  2. Для цикла с предусловием запишите его полный эквивалент с помощью цикла с постусловием.
  3. Для цикла с постусловием запишите его полный эквивалент с помощью цикла с предусловием.

Одномерные и двумерные массивы. Строки

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

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

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

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

Пример: числовая последовательность четных натуральных чисел 2, 4, 6,..., N представляет собой линейный массив, элементы которого можно обозначить А[1]=2, А[2]=4, А[3]=6,..., А[К]=2*(К+1), где К — номер элемента, а 2, 4, 6,..., N — значения. Индекс (порядковый номер элемента) записывается в квадратных скобках после имени массива.

Например, A[7] — седьмой элемент массива А; D[6] — шестой элемент массива D.

Для размещения массива в памяти ЭВМ отводится поле памяти, размер которого определяется типом, длиной и количеством компонент массива.

тип идентификатор[количество строк];

Например,

int B[5]; char R[34];

— описывается массив В, состоящий из 5 элементов и символьный массив R, состоящий из 34 элементов. Для массива В будет выделено 5*6=30 байт памяти, для массива R — 1*34=34 байта памяти.

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

Заполнить массив можно следующим образом:

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

 

Задача 1. Заполнить одномерный массив элементами, отвечающими следующему соотношению:

a 1=1; a 2=1; a i= ai -2+a i -1 (i = 3, 4,..., n).

cin >> N; /*Ввод количества элементов*/

A[0] = 1;

A[1] = 1;

for(int i=2; i<n; i++)

A[I] = A[I - 1] + A[I - 2];

Другой вариант присваисвания значений элементам массива — заполнение значениями, полученными с помощью датчика случайных чисел.

 

Задача 2. Заполнить одномерный массив с помощью датчика случайных чисел таким образом, чтобы все его элементы были различны.

function changeProof(proofobj) { if (proofobj.style.display=='none') {proofobj.style.display='inline'} else {proofobj.style.display='none'} } Листинг

// программа заполнение массива #include <iostream.h> #include <time.h> #include <stdlib.h>   void main() { int A[99]; /*Массив из 100 элементов*/ cout << "Введите количество элементов массива"; int N; cin >> N; randomize(); A[0] = -32768 + random(65535); for(int i=1; i<N; i++) { int log=1; do { A[i] = -32768 + random(65535); int j = 1; while((log==1) && (j <= i - 1)) { if(A[i]!= A[j]) log = 0; j++; } }while(log==1); } for(i=0;i<N;i++) cout << A[i] << " "; }

Второй способ ввод значений элементов массива с клавиатуры используется обычно тогда, когда между элементами не наблюдается никакой зависимости. Например, последовательность чисел 1, 2, -5, 6, -111, 0 может быть введена в память следующим образом:

int A[99], n;

cout << "Введите количество элементов массива ";

cin >> n;

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

{

cout << "Введите A[" << i << "]";

cin >> A[i];

}

Над элементами массива чаще всего выполняются такие действия, как

а) поиск значений;

б) сортировка элементов в порядке возрастания или убывания;

в) подсчет элементов в массиве, удовлетворяющих заданному условию.

Cумму элементов массива можно подсчитать по формуле S=S+A[I] первоначально задав S =0. Количество элементов массива можно подсчитать по формуле К = К +1, первоначально задав К =0. Произведение элементов массива можно подсчитать по формуле P = P * A[I], первоначально задав P = 1.

 

Задача 3. Дан линейный массив целых чисел. Подсчитать, сколько в нем различных чисел.

function changeProof(proofobj) { if (proofobj.style.display=='none') {proofobj.style.display='inline'} else {proofobj.style.display='none'} } Листинг

{Подсчет количества различных чисел в линейном массиве. ИДЕЯ РЕШЕНИЯ: заводим вспомогательный массив, элементами которого являются псевдологические величины (0 - если элемент уже встречался ранее, 1 - иначе)}   // программа различные числа #include <iostream.h>   void main() { int A[50], Lo[50], n; cout << "Введите количество элементов массива: "; cin >> n; for(int i=0; i<n; i++) { cout << "A[" << i << "]="; cin >> A[i]; Lo[i] = 1; } int kol = 0; /*переменная, в которой будет храниться количество различных чисел*/ for (i=0;i<n;i++) { if (Lo[i]==1) { kol++; for(int k=i; k<n; k++) { Lo[k] = (A[k]!= A[i]) && Lo[k]; } } } cout << "Количество различных чисел: " << kol; } Тест: N = 10; элементы массива - 1, 2, 2, 2, -1, 1, 0, 34, 3, 3. Ответ: 6.

 

Задача 4. Дан линейный массив. Упорядочить его элементы в порядке возрастания.

function changeProof(proofobj) { if (proofobj.style.display=='none') {proofobj.style.display='inline'} else {proofobj.style.display='none'} } Листинг

{Сортировка массива выбором (в порядке возрастания). Идея решения: пусть часть массива (по K-й элемент включительно) отсортирована. Нужно найти в неотсортированной части массива минимальный элемент и поменять местами с (K+1)-м}   // программа сортировка выбором #include <iostream.h>   void main() { int A[30], n; cout << "Введите количество элементов: "; cin >> n; for(int i=0; i<< i A[??Введите cout { i++)>> A[i]; } for(i=0; i<n-1; i++) { int k = i; for(int j=i+1; j<n; j++) if(A[j]<=A[k]) k = j; int buf = A[i]; A[i] = A[k]; A[k] = buf; } for(i=0; i<n; i++) { cout << A[i] << " "; } } Тест: N = 10; элементы массива - 1, 2, 2, 2, -1, 1, 0, 34, 3, 3. Ответ: -1, -1, 0, 1, 2, 2, 2, 3, 3, 34.

Демострации различных видов сортировок можно посмотреть здесь

 

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

Например, данные о планетах Солнечной системы представлены следующей таблицей:

Планета Расст. до Солнца Относ. обьем Относ. масса
Меркурий 57.9 0.06 0.05
Венера 108.2 0.92 0.81
Земля 149.6 1.00 1.00
Марс 227.9 0.15 0.11
Юпитер 978.3 1345.00 318.40
Сатурн 1429.3 767.00 95.20

Их можно занести в память компьютера, используя понятие двумерного массива. Положение элемента в массиве определяется двумя индексами. Они показывают номер строки и номер столбца. Индексы пишутся в отдельных квадратных скобках. Например: A[7][6], D[56][47].

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

void main()

{

int A[20][20];

for(int i=0; i<3; i++)

for(int j=0; j<2; j++)

A[i][j] = 456 + i;

}

элементы массива примут значения A[1][1] = 457; A[1][2] = 457; A[2][1] = 458; A[2][2] = 458; A[3][1] = 459; A[3][2] = 459.

При описании массива задается требуемый объем памяти под двумерный массив, указываются имя массива и в квадратных скобках максимальное значение индекса.

При выполнении инженерных и математических расчетов часто используются переменные более чем с двумя индексами. При решении



Поделиться:




Поиск по сайту

©2015-2024 poisk-ru.ru
Все права принадлежать их авторам. Данный сайт не претендует на авторства, а предоставляет бесплатное использование.
Дата создания страницы: 2016-02-16 Нарушение авторских прав и Нарушение персональных данных


Поиск по сайту: