Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
Книга_2013_1_часть+.doc
Скачиваний:
0
Добавлен:
01.05.2025
Размер:
813.57 Кб
Скачать

4.2. Тернарная операция

Этой операции также нет в других языках, и без неё можно обойтись. С её помощью в более компактном виде в некоторых случаях можно записать полную форму оператора if. Например, вместо if (k>9) R=100; else R=x*y; можно записать R=k>9 ? 100 : x*y;.

Это единственная трёхместная операция, так как для неё требуется три операнда. Общий вид операции: выражение1 ? выражение2 : выражение3.

Операция выполняется следующим образом: вычисляется выражение1; если оно истинно (любое ненулевое значение), то вычисляется выражение2, и всё выражение получает это значение; если выражение 1 ложно (нулевое значение), то вычисляется выражение3, и всё выражение получает это значение.

Эта операция не обязательно должна быть связана с присваиванием. Например, известно, что в cout можно записать выражение, а в нём эту операцию без дополнительного присваивания значения выражения. Например:

cout<<(x>0 && y>x ? x*y : x+y); в зависимости от значений x и y выведут их произведение или сумму. Это равносильно

if (x>0 && y>x) cout<<(x*y);

else cout<<(x+y).

Не для любого оператора if можно записать тернарную операцию. Её можно использовать для замены только полной формы условного оператора. В одной и другой ветвях операции (после символов “?” и “:” ) можно использовать по одному выражению, то есть это соответствует такому оператору if, в котором в каждой ветви по одному оператору.

Эта операция, как и любая другая, в выражении не обязательно должна быть единственной. Аналогично, как и другие операции тернарную можно использовать с другой операцией. Допустимо, например, следующее присваивание: r=a+b*(x>y ? x : y); которое вычисляет r= a+b*max(x, y);

Эта операция может быть вложенной. Например, вычисление r= min(x,y), если a>b и r=x*a+y*b в противном случае можно выполнить так:

r=a>b ? (x<y ? x : y) : x*a+y*b;

4.3. Оператор выбора switch

Аналогичный оператор есть и в других языках (case в Pascal). Он используется, если уровень вложенности if достаточно большой.

Пример 4. Вывести целое однозначное число z прописью.

Это можно сделать с помощью if:

int z; cin>>z; if (z==0) cout<<”нуль”;

else if (z==1) cout <<” один”;

else if (z==2) cout <<” два”;

/* и т.д. записываем if для 3, 4, 5, 6, 7, 8 */

else if (z==9) cout <<”девять”;

else cout<<”Ошибка”;

Второй вариант с оператором switch вместо вложенного if нагляднее и легче для понимания и отладки.

int z; cin>>z;

switch (z)

{ 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;

default: cout<<”Ошибка ”;

} // Конец оператора switch.

// Здесь оператор, следующий после switch.

Работает оператор так. Пусть, например, z=3. Тогда первые две ветви пропускаются, выполняется cout <<”три”; и break передаёт управление на оператор, следующий после switch. Если z не является однозначным числом, например, числом 30, то первые десять ветвей пропускаются, выводится “Ошибка” и выполняется оператор, следующий после switch.

Оператор switch имеет следующий общий вид:

switch (выражение)

{ case константное_выражение1:

последовательность_операторов1; break;

case константное_выражение2:

последовательность_операторов2; break;

case константное_выражениеN:

последовательность_операторовN; break;

default: последовательность_операторов;

}

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

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

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

Пример 5. Анализ оценки z будет выглядеть так:

switch (z)

{ case 1:

case 2:

case 3: cout <<”не удовл.” ; break;

case 4: case 5: cout <<”удовл.”; break;

case 6: case 7: case 8: cout <<”хор.”; break;

case 9:

case 10: cout <<”отл.” ; break;

default: cout<<”Ошибка ”;

}

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

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

char flag1, flag2; ……

switch (flag1)

{ case ‘A’: switch (flag2)

{ case ‘A’: cout<<”AA”; break;

case ‘B’: cout<<”AB”;

} break;

caseX’: …

}

Упражнения и тесты

        1. Дано x. Вычислить y = x*x, если x > 0, иначе y = 100.

Предлагаются следующие три варианта решения:

a) if (x>0) y=x*x; else y=100; cout<<"y= "<<y;

б) y = x>0?x*x:100; cout<<"y= "<<y;

в) cout<<"y= "<<(x>0?x*x:100);

2. Даны х, y. Вывести “+++” или “– – –” в зависимости от того, x>y или нет.

Решение: а) if (x>y) cout<<”+++”; else cout<<“– – –”;

б) x>y? cout<<" +++ " : cout<<“– – –”;

3. Вывести “Yes” или “No” в зависимости от того, точка с координатами x, y принадлежит области, ограниченной линиями y= –x, x=0 и y= –1, или нет.

Решение:

if (y<=–x && x>=0 && y>–1 ) cout<<"Yes"; else cout<<"No";

  1. Нарисовать область плоскости, в которой и только в которой следующее логическое выражение истинно:

а) x>y && x<2 && y>-1; б) x>y || x<2 && y>-1; в) x>y && x<2 || y>-1; г) x>y || x<2 || y>-1; д) x>y && (x<2 || y>-1); е) x>y && !(x<2 || y>-1).

5. Определить результат, то есть значения переменных a, b и r, после выполнения оператора if. Даны, например, следующие начальные значения этих переменных: a) int a=2, b=3, r=4; b) int a=5, b=5, r=4; c) int a=-5, b=5, r=4; d) int a=0, b=3, r=4;. Варианты оператора if:

1) if (a>=1) r=a+b; else if (b>0) r=a-b;

else if (b<-5) r=a*b; else r=a;

2) if (a>=1) r=a+b; else if (b>0) r=a-b;

else if (b<-5) r=a*b;

3) if (a=b) if (b) r=a+b; else r=a-b;

4) if (a>=1) { if (b>0) r=a+b; } else r=a-b;

5) if (a>=1) if (b>0) r=a+b; else r=a-b;

6) if (a+b) if (a-b) {a*=b; b*=a++; }

else { a*=(--b); b*=(a--); }

else { a--; b=a; ++b; }

7) if (a+b) if (a-b) {a*=b; b*=a++; }

else { a*=(--b); b*=(a--); }

else a--; b=a; ++b;

8) if (a=b) { if (b) r=a+b; } else r=a-b;

9) if (a==b) if (b) r=a+b; else r=a-10;

10) if (a==b) { if (b) r=a+b; } else r=a-10;

11) if (a+b) if (a-b) {a*=b; b*=a++; } else { a*=(--b); b*=(a--); }

else { a--; b=a; ++b; }

12) if (a+b) if (a-b) {a*=b; b*=a++; } else { a*=(--b); b*=(a--); }

else a--; b=a; ++b;

6. Пусть float x=… , y=…, a=… , b=…, где a>0, b>0 (на месте многоточия конкретные числовые константы). Определить результат (true или false) для каждого логического выражения

1) y>fabs(x) && fabs(x)<a && y<b; 2) y>fabs(x) || fabs(x)<a && y<b;

3) y>fabs(x) && fabs(x)<a || y<b; 4) y>fabs(x) || fabs(x)<a || y<b;

5) (y>fabs(x) || fabs(x)<a) && y<b; 6) y>fabs(x) || ( fabs(x)<a && y<b);

7) ! (y>fabs(x) || fabs(x)<a) && y<b;

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

7. Записать номера логических выражений, для которых получим true, если int x=…, y=…;(на месте многоточия конкретные числа).

Уровень А. Используются логические выражения, составленные по образцу предыдущего типа теста.

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

true = = true; false = = false ; true > false.

Примеры таких логических выражений:

1) (y>x) = = (x>0); 2) (y>x) ! = (x>0); 3) (y>x) > (x>0);

4) (y>x) < (x>0); 5) (y>x) >= (x>0); 6) (y>x) <= (x>0);

7) (y > x) > !(x > 0) и т. п.

8. Пусть float x=…, y=…, r; (x и y проинициализированы конкретными значениями). Записать в указанном порядке значения x, y, r, которые получатся после выполнения операции присваивания и тернарной операции

1) r= x>1 || y<=0 ?++x:y- -; 2) r= !(x>1 || y<=0) ? x++: - -y;

3) r= x>1 &&|| y<=0 ? x+1: y+1-; 4) !(x>1 && y<=0) ? r=++x: r=--y;

  1. Сравнить оператор switch с оператором case языка Pascal.

  2. Что будет выведено, если введём

1) 1 2) 5 3) 8 4) 0 5) 22 ?

int m; cin>>m;

switch (m)

{case 1:case 2: case 3: cout<<2; break;

case 4: case 5: cout<<3; break;

case 6: case 7: case 8: cout<< 4;

case 9: case 10: cout<< 5; break;

default: cout<<"Error";

}

Оператор break может отсутствовать в одной или нескольких других ветвях.

11. В каких строках ( //1 -- //6) есть ошибки компиляции?

#define ONE 1

int m; const n=4, float k=1; cin>>m;

switch (m+k) //1

{ case ONE: //2

case т: cout<< 2; break; //3

case ONE+2: cout<<3; //4

case n: cout<<4; //5

case k+n: cout<<"Five"; break; //6

}

12. В каких строках ( //1 — //7) есть ошибки компиляции?

char C, B='B'; C=getch();

switch (C) //1

{ case 'A': cout<<"А"; //2

case “B”: switch (B) //3

{ case 'A': cout<< " BA "; break; //4

case B : cout << " BB "; break; //5

case ‘C’ : cout<< " BC "; break; //6

}

case С: cout<<" C "; } //7

Задачи

  1. Ввести число. Вывести 0 или 1 в зависимости от того, положительное число или неположительное. Выполнить это двумя способами:

#include <iostream.h>

#include <conio.h>

int main() { float x; int result;

cout<<"The number "; cin>>x;

cout<<"The first variant " ; cout<<(x>0)<<endl;

cout<<"The second variant " ;

if (x>0) result=1; else result=0;

cout<<result<<endl; getch(); return 0; }

2. Найти наибольшее из трех введенных чисел:

main() { int x, y, z, res1, res2, res3;

cout<<"The first number "; cin>>x;

cout<<"The second number "; cin>>y;

cout<<"The third number "; cin>>z;

cout<<"Max of numbers (" <<x<<" , "<<y<<" , "<<z<<" ) ";

// Полная форма оператора if:

if (x>y) res1=x; else res1=y;

if (z>res1) res1=z;

cout<<”\nVariant 1 “<<res1<<endl;

// Сокращённая форма оператора if:

res2= x; if (y > res2) res2= y;

if (z > res2) res2= z;

cout<<" Variant 2 "<< res2<<endl;

// Тернарная операция :

res3=x>y?x:y; res3=z>res3?z:res3;

cout<<" Variant 3 "<<res3;

getch(); return 0; }

Указания. Одну и ту же задачу по возможности решить несколькими способами, используя, например, сокращенную и полную формы if, if и switch, if и тернарную операцию.

Уровень А

  1. Вычислить r = max(min(x, y), z).

  2. Вычислить r = max(x, 0) + min(y, z).

  3. Вычислить r = min(x, y, 0) + max(y, z).

  4. Найти произведение двух наименьших из трех чисел.

  5. Найти действительные корни квадратного уравнения, если заданы его коэффициенты. Предусмотреть следующие варианты: два различных корня; один корень; нет действительных корней.

  6. Ввести часы, минуты и секунды. Определить корректность момента времени.

  7. Даны длины трех отрезков A, B, C. Определить возможность построения треугольника и его вид (разносторонний, равнобедренный, равносторонний).

  8. Расположить два числа a, b в порядке убывания их значений.

  1. Вычислить значение функции в соответствии с заданным графиком для произвольного одного фиксированного значения аргумента.

  2. Даны a, b, c, K, P. Вычислить значение функции

  1. Даны два вещественных числа x, y. Если точка плоскости с координатами (x, y) принадлежит треугольнику с вершинами в точках (–2, 0), (0, 2), (2, 0), то обе координаты увеличить в 10 раз, в противном случае уменьшить их на число 10.

  2. Даны два вещественных числа x, y. Вывести “Yes” или “No” в зависимости от того, точка плоскости с координатами (x, y) принадлежит кольцу, ограниченному окружностями, радиусы которых 1 и 3 c общим центром в точке с координатами (a, b), или не принадлежит этому же кольцу.

Решить задачи, аналогичные 11, 12, для других областей, параметры которых — конкретные числа.

  1. В зависимости от номера месяца вывести одно из слов: зима, весна, лето или осень.

  2. В зависимости от номера месяца получить номер квартала.

  3. Дано целое число. В зависимости от его значения вывести в правильном падеже какоенибудь заданное слово. Например, 563 символа, 1713 символов, 91 символ и т. п.

  4. Вывести заданное целое положительное число a прописью, если

а) a<100; b) a<1000. Например, 7 — семь, 26 — двадцать шесть, 145 — сто сорок пять, 13 — тринадцать.

Уровень B

  1. Расположить четыре числа a, b, c, d в порядке возрастания их значений. Массив и операторы цикла не использовать.

  2. Ввести вещественные a и k. Вывести на экран одночлен a*x^k. При этом если a=1, выводить только x^k, где k — введенное число, а 1 не выводить. Если A=-1, выводить x^k, если A=0, x^2 не выводить. Аналогично предусмотреть следующие варианты для k: k=1, k=-1, k=0.

  3. Ввести коэффициенты квадратного уравнения A, B и C. Вывести на экран

A*x^2+B*x+C=0. При этом если A=1, выводить только x^2, то есть 1 не выводить, если A=-1, выводить x^2, если A=0, x^2 не выводить. Аналогично для B. Не выводится также нулевое значение С.

  1. Ввести два числа: номер месяца и день. Выполнить проверку корректности этой даты. Например, 3 и 31 определяют дату, а 4 и 31, 20 и 5 — нет. Вывести слово “да” или “нет”.

  2. Даны два вещественных числа x, y. Вывести 0, если точка плоскости с координатами (x, y) не принадлежит кольцу, ограниченному окружностями, радиусы которых r и R (r<R) c общим центром в начале координат. Если точка (x, y) принадлежит этому кольцу, вывести 1, 2, 3 или 4 в зависимости от того, в какой четверти находится соответствующая часть кольца. Выполнить контроль ввода двух радиусов, которые в этом примере являются параметрами области. Если r>R или один из радиусов или оба неположительные, то вывести соответствующее сообщение, x, y не вводить, не анализировать и закончить программу.

    1. Задачи 15 и 16 уровня А решить вместе в одном проекте.

    2. Дано целое положительное число a<1000000. Вывести это число, отделив пробелом каждую тысячу, а также в скобках вывести его прописью, добавив слово рубль (рубля, рублей). Например, для числа 514230 вывод такой 514 230 (пятьсот четырнадцать тысяч двести тридцать рублей); для 4002 выводим 4 002 (четыре тысячи два рубля);для числа 51 выводим 51 (пятьдесят один рубль).