Практикум на ЭВМ: I курс
2011/2012 учебный год
Тема 1. Ввод/вывод, переменные и типы данных, присваивание, условный оператор, оператор выбора
Занятие 1 (16 сентября) — Ввод/вывод, переменные и типы данных, присваивание
Запустите среду программирования PascalABC.NET (Пуск / Программирование и ППП / Программирование / PascalABC.NET).
Выполните в классе задания из разделов I-III (повышенной сложности — по желанию). Задания раздела IV нужно выполнить дома.
Рекомендации к выполнению
а) Следует уделять внимание оформлению собственных решений (пустые строки, отступы, комментарии), ориентируясь на предоставленные образцы.
б) Переменные следует объявлять непосредственно перед их использованием (переменные для исходных данных в блоке ввода данных, вспомогательные переменные — в блоке вычислений).
в) Решения большинства заданий из этого пункта имеют следующую структуру:
- Ввод исходных данных
- Вычисление результата
- Вывод результата
Блоки решения можно выделять пустыми строками и сопровождать комментариями.
I. Простейший ввод/вывод, оператор присваивания, вычисление значения выражения
1. Рассмотрите пример, создайте файл с этой программой и запустите ее на выполнение:
// Программа, печатающая приветствие - это комментарий к программе
program Hello;
begin
Writeln('Привет, мир');
end.
2. Изучите пример, демонстрирующий использование вещественных переменных:
// Использование вещественных переменных
begin
// Объявление переменной с одновременным присваиванием значения
var a:real := 10.1;
// Вывод значения переменной
Writeln('a = ', a);
// Присваивание переменной нового значения
a := 5;
// Увеличение значения переменной
a += 0.6;
// Вывод значения переменной
Writeln('a = ', a);
end.
3. Рассмотрите примеры с вычислением периметра квадрата и периметра и длины гипотенузы прямоугольного треугольника:
// Вычисление периметра квадрата по заданной стороне
begin
Writeln('Введите длину стороны квадрата:');
// Объявление переменной для хранения длины стороны
var a: real;
// Ввод длины стороны
Read(a);
// Вычисление периметра
var P: real := 4 * a;
Writeln('Периметр P = ', P);
end.
// Вычисление гипотенузы и периметра прямоугольного треугольника по заданным катетам
begin
Writeln('Введите длины катетов (два числа, разделенные пробелом):');
// Объявление переменных для хранения катетов
var a, b: real;
Read(a, b);
// Тип переменной c определяется автоматически, как результат вычислений
// sqrt - функция вычисления квадратного корня
var c := sqrt(a*a + b*b);
Writeln('Гипотенуза c = ', c);
// Вычисление периметра треугольника
var P := a + b + c;
Writeln('Периметр P = ', P);
end.
4. Вычислите синус и косинус угла, заданного в радианах.
5. Найдите наибольшее целое число, которое не превышает корня заданного числа.
6. Вычислите значение выражения по заданным a, b и c: <math>\frac{a+b}{a-b}+\sqrt{\frac{c}{2}}</math>.
7. Вычислите значение функции y = 4(x–3)6 – 7(x–3)3 + 2 для нескольких заданных x. Воспользуйтесь вспомогательной переменной для (x–3)3.
II. Операции с целыми числами
Используемые понятия: тип integer, операции div (вычисление частного от деления) и mod (вычисления остатка от деления), стандартный вид числа (напр. 123 = 1*100 + 2*10 + 3*1).
Основные задания
- Определить возраст человека в годах по возрасту, заданному в месяцах.
- Дано двузначное целое число. Вывести его правую и левую цифры.
- Дано трехзначное число. Вывести сумму и произведение его цифр.
- Даны две цифры. Пользуясь стандартным видом числа, сформируйте число, разрядами которого являются заданные цифры. Первая заданная цифра должна соответствовать второму разряду (разряды числа нумеруются справа налево).
- Дано двузначное число. Поменяйте в нем местами разряды десяток и единиц.
- Дано трехзначное число. Выполните в нем циклический сдвиг разрядов влево (разряд единиц становится разрядом десятков, разряд десятков — разрядом сотен, а разряд сотен — разрядом единиц).
Задания повышенной сложности
Используемые понятия: битовые операции.
К битовым относятся бинарные операции and, or, not, xor, shl, shr. Они производят побитовые манипуляции с операндами целого типа. Битовые операции and, or, not и xor осуществляются следующим образом: с каждым битом (0 принимается за False, 1 — за True) производится соответствующая логическая операция. Операции shl и shr выполняют сдвиг разрядов влево или вправо, при этом недостающие разряды дополняются нулями. Например:
00010101 and 00011001 = 00010001 00010101 or 00011001 = 00011101 00010101 xor 00011001 = 00001100 not 00010101 = 11101010 00010101 shl 310 = 10101000 00010101 shr 310 = 00000010
(по умолчанию операнды и результат представлены в двоичной форме).
В решениях удобно пользоваться функцией перевода целого положительного числа в строковое двоичное представление (в самой функции пока разбираться необязательно, ее можно скопировать в свою программу). Следует также помнить, что правила сложения и вычитания чисел «в столбик» работают вне зависимости от того, в какой системе счисления представлено (например, в двоичном представлении: 00001000 – 00000001 = 00000111).
Замечание: для упрощения работы и проверки результата используйте тип byte (8-битное беззнаковое целое: 0..255) вместо integer.
- Дано целое число. Вывести в двоичном и десятичном видах результат операции not над ним. (Для сравнения удобно вывести само число в двоичном виде предварительно.)
- Даны два целых числа. Вывести в двоичном и десятичном видах результаты операций and, or и xor над ними. Что если исходные числа равны?
- Сдвинуть число 1 влево на 1, 2, 3, 5 и 10 разрядов. Сформулировать (и записать в комментарии в программе) смысл этой операции.
- Сдвинуть число 10000 вправо на 1, 2, 3, 5 и 10 разрядов. Сформулировать смысл этой операции.
- Дано целое число. Обнулить его младший бит (крайний правый бит в двоичном представлении).
- Дано целое число. Обнулить его младший бит. Установить его младший бит.
- Даны два целых числа. Сформировать число, каждый бит которого является наименьшим из соответствующих битов исходных чисел.
- Сформировать число с установленными третьим, пятым и седьмым битами, считая слева.
- Установить третий, пятый и седьмой биты в заданном числе.
- Дано целое число. Обнулить его крайний справа единичный бит (например, 00100100 ↦ 00100000). На основе этого проверить, является ли число степенью двойки.
- Проверить, имеет ли заданное целое число вид 2n – 1.
- Заполнить крайнюю справа непрерывную последовательность нулевых битов заданного числа единицами (например: 00100100 ↦ 00100111).
- Обнулить крайнюю справа непрерывную последовательность единичных битов заданного числа (например: 1001100 ↦ 10000000). На основе этого проверить, является ли данное число (положительной) разностью степеней двойки.
III. Операции с символами
- Определить код заданного символа
- Вывести символ, следующий за данным
IV. Задания на дом
- Дана длина ребра куба a. Найти объем куба и площадь его поверхности.
- Вычислите значение логарифма числа 1024 по основанию 2, пользуясь функцией ln, вычисляющей натуральный логарифм заданного числа, и формулой: <math>\log_a b = \frac{\ln b}{\ln a}</math>.
- Известна скорость лодки и пройденный ею путь. Вычислите время движения лодки.
- Вычислите длину окружности и площадь круга заданного радиуса. Используйте константу (const Pi=3.14159265;) для числа π.
- Найти расстояние между двумя точками с заданными координатами <math>(x_1, y_1)</math> и <math>(x_2, y_2)</math> на плоскости. Расстояние вычисляется по формуле <math>d=\sqrt{(x_1-x_2)^2+(y_1-y_2)^2}</math>.
- Даны длины сторон треугольника. Вычислите его площадь, пользуясь формулой Герона <math>S=\sqrt{p(p-a)(p-b)(p-c)}</math>, где p — полупериметр.
- Дана температура в градусах Цельсия, вычислите соответствующую ей температуру в градусах Фаренгейта. Шкалы Цельсия и Фаренгейта связаны соотношением <math>t^{\circ}C = \frac{5}{9}(t^{\circ}F-32)</math>.
- Даны радиусы двух концентрических окружностей. Вычислите площадь кольца, заключенного между ними.
- Известны периметр прямоугольника и длина его диагонали. Найти стороны прямоугольника.
- Поменять местами значение переменных. То же, не используя вспомогательную переменную.
- Вывести символ, предшествующий данному
- Определить, сколько месяцев осталось до дня рождения человека, если известен его возраст в месяцах.
- Определить последнюю цифру заданного целого числа.
- Даны три цифры, построить соответствующее трехзначное число.
- Дано трехзначное число. Выполнить циклический сдвиг его разрядов вправо.
- Дано трехзначное число. Поменять в нем местами разряды десятков и единиц.
- Дано трехзначное число. Обнулить в нем разряд десятков.
- Дано трехзначное число. Сформировать новое число, каждый разряд которого больше на единицу. Если разряд данного числа равен 9, то он должен стать равным 0.
Занятие 2 (17 сентября) — Сравнения и логические операции
Во всех заданиях пользоваться условным оператором нельзя, ответ выводится как результат сравнения или логической операции.
Используемые понятия: логические операции not, and, or.
I. Основные задания
- Даны два целых числа. Вывести значение True, если первое число больше второго, и False в противном случае.
- Даны два целых числа. Вывести значение True, если первое число не равно второму, и False в противном случае.
- Даны три целых числа: A, B, C. Вывести значение True, если справедливо двойное неравенство A < B < C, и False в противном случае.
- Даны три целых числа. Вывести значение True, если они все равны, и False в противном случае.
- Даны два целых числа. Вывести значение True, если хотя бы одно из этих чисел является нечетным (нужно использовать функцию odd), и False в противном случае.
- Даны три вещественных числа. Вывести значение True, если все эти числа являются положительными, и False в противном случае.
- Даны три вещественных числа. Вывести значение True, если хотя бы одно из этих чисел является положительным, и False в противном случае.
- Даны числа x, y. Вывести значение True, если точка с координатами (x, y) лежит в четвертой координатной четверти, и False в противном случае.
- Даны числа x, y. Вывести значение True, если точка с координатами (x, y) лежит выше оси абсцисс, и False в противном случае.
- Даны целые числа a, b, c, являющиеся сторонами некоторого треугольника. Вывести значение True, если треугольник со сторонами a, b, c является равнобедренным, и False в противном случае.
II. Задания повышенной сложности
- Даны два целых числа: A, B. Вывести значение True, если числа A и B имеют одинаковую четность, и False в противном случае.
- Даны три целых числа: A, B, C. Вывести значение True, если число C находится между числами A и B, и False в противном случае. Указание: Следует рассмотреть два случая: A < B и A > B.
- Дано трехзначное число. Вывести значение True, если цифры данного числа образуют возрастающую последовательность, и False в противном случае.
- Даны числа A, B, C (число A не равно 0). Рассмотрев дискриминант D = B2 − 4·A·C, вывести значение True, если квадратное уравнение A·x2 + B·x + C = 0 имеет вещественные корни, и False в противном случае.
- Даны целые числа a, b, c, являющиеся сторонами некоторого треугольника. Вывести значение True, если треугольник со сторонами a, b, c является прямоугольным, и False в противном случае.
- Даны целые числа a, b, c. Вывести значение True, если существует треугольник со сторонами a, b, c, и False в противном случае.
- Даны координаты поля шахматной доски x, y (целые числа, лежащие в диапазоне 1–8). Учитывая, что левое нижнее поле доски (1, 1) является черным, вывести значение True, если данное поле является белым, и False в противном случае.
- Даны координаты двух различных полей шахматной доски x1, y1, x2, y2 (целые числа, лежащие в диапазоне 1–8). Вывести значение True, если ладья за один ход может перейти с одного поля на другое, и False в противном случае.
- Даны координаты двух различных полей шахматной доски x1, y1, x2, y2 (целые числа, лежащие в диапазоне 1–8). Вывести значение True, если конь за один ход может перейти с одного поля на другое, и False в противном случае.
III. Задания на дом
- Даны два целых числа. Вывести значение True, если первое число не меньше, чем второе, и False в противном случае.
- Даны два целых числа. Вывести значение True, если первое совпадает со вторым, и False в противном случае.
- Даны два целых числа. Вывести значение True, если ровно одно из этих чисел является четным (функция odd и операция not), и False в противном случае.
- Дано трёхзначное число. Вывести значение True, если все цифры данного числа различны, и False в противном случае.
- Даны числа x, y. Вывести значение True, если точка с координатами (x, y) лежит во второй или третьей координатной четверти, и False в противном случае.
- Даны целые числа a, b, c, являющиеся сторонами некоторого треугольника. Вывести значение True, если треугольник со сторонами a, b, c является равносторонним, и False в противном случае.
Не знаю, что
Поиск ошибок
Ошибки в программах — довольно частое явление. Нужно уметь находить и исправлять ошибки. К самым простым можно отнести ошибки синтаксиса.
Внимательно изучите эту страницу. Там приведены самые распространенные ошибки начинающих программистов. Но ошибки могут быть самыми разнообразными. Часто в их устранении помогает компилятор, он выдает сообщение об ошибке. Но ожидания компилятора не всегда соответствуют нашим желаниям!
Рассмотрим такую программу:
var
a real;
begin
end.
Компиляция приводит к ошибке: Ожидалось ':=' во второй строке. Если броситься исправлять эту ошибку, не подумав, мы получим следующее:
var
a := real;
begin
end.
Ошибка: Ожидалась переменная. Может быть и не переменная (а выражение, например), но ожидался точно не тип. Вернемся к предыдущей программе и подумаем.
Очевидно, мы хотели описать переменную типа real, но пропустили знак «:».
var
a: real;
begin
end.
Отлично, работает.
Не забыть
Именование, форматирование
Конечно, когда программист пишет программу, он в первую очередь хочет, чтобы она работала и работала правильно (если программист этого не хочет, значит это либо неправильный программист, который делает неправильные программы, либо хочет досадить начальству). Но еще программистам «иногда» приходится читать чужие программы. И вот тогда им хочется, чтобы эти программы читались легко.
Вряд ли Вы сильно обрадуетесь, если коллеге вздумается вот так над Вами подшутить:
var _1_,_1__,_1___,_1____,_2_,_2__,_:real;
begin read(_1_,_1___,_1__,_1____,_2_,_2__);
_:=(5-_1_)/10;_*=_2_*_2_;
var __:=_1_+_1___;
__*=(_2_-3)*(_2_-3)*(_2_-3);_+=__*_2_;
_+=((_1____-_1__)/7)*_2__*(_2__+1)*(_2__+1);
_+=(_1____*_1____+_1__*_1__*_1__)*(3-_2__);
write(_);end.
Между прочим, это еще ничего! Могло быть и хуже. Но все равно, более говорящие имена переменных не помешали бы.
Если коллега добрый, он признается, что программа могла выглядеть так:
var a,b,c,d,x,y,f:real;
begin read(a,c,b,d,x,y);
f:=(5-a)/10;f*=x*x;
var f1:=a+c;
f1*=(x-3)*(x-3)*(x-3);f+=f1*x;
f+=((d-b)/7)*y*(y+1)*(y+1);
f+=(d*d+b*b*b)*(3-y);
write(f);end.
Теперь это стало похоже на вычисление некоторой странной функции двух переменных. Но читать это не очень-то удобно. Добавим простейшее форматирование:
var
a,b,c,d,x,y,f: real;
begin
read(a,c,b,d,x,y);
f:=(5-a)/10;f*=x*x;
var f1:=a+c;
f1*=(x-3)*(x-3)*(x-3);f+=f1*x;
f+=((d-b)/7)*y*(y+1)*(y+1);
f+=(d*d+b*b*b)*(3-y);
write(f);
end.
Если разбить процесс вычисления функции на более очевидные шаги и использовать пробелы при форматировании операторов, можно получить, например, такой код:
var
a, b, c, d: real;
x, y: real;
f: real;
begin
read(a, b, c, d);
read(x, y);
var add1 := ((5 - a) / 10) * x*x;
var x1 := x - 3;
var add2 := (a + c) * x * x1*x1*x1;
var y1 := y + 1;
var add3 := ((d - b) / 7) * y * y1*y1;
var add4 := (d*d + b*b*b) * (3 - y);
f := add1 + add2 + add3 + add4;
write(f);
end.
Варианты могут быть разными. При желании можно даже использовать дополнительные переменные для x13 или b3. Неплохо бы еще добавить комментарий, в котором будет написано, что это за загадочная функция.
Хорошие имена переменных (а также процедур, функций и типов), форматирование и комментирование кода упрощают процесс чтения и понимания кода. Начинать писать читабельный и понятный код надо с учебных программ. И не только потому, что преподавателю не очень-то хочется разбираться в стройных рядах закорючек, но и потому, что потом заниматься этим будет некогда. А самое страшное — это то, что, возможно, однажды придется разбираться в собственном коде.
Примечание. Для разных языков программирования приняты разные правила форматирования и именования. Работа в команде разработчиков часто предполагает следование подобным правилам. Это не прихоть, а хороший способ упростить работу программистов с кодом. Это как бумажные письма! Гораздо приятней и проще читать письмо, написанное одним (причем понятным) почерком, чем перескакивать с одного на другой.
Хорошая книга — Стив Макконелл, «Совершенный код».