Лабораторная работа №1.
Тема: Основні оператори: присвоєння, розгалуження, множинний вибір, цикл. Типи циклів та принципи їх застосування.
Цель: Изучить структуру простейшей С-программы. Освоить программирование ввода-вывода с помощью стандартных библиотек. Приобрести навыки программирования вычислений.
Литература:
П. Франка С++: Учебный курс.– СПб: Питер Ком, 1999.
И. М. Двоеглазов Язык программирования С++. Справочное руководство. – Киев, 1993.
Теоретические сведения.
Структура программы
Программа на C++ обычно состоит из большого числа исходных файлов, каждый из которых содержит описания типов, функций, переменных и констант. Чтобы имя можно было использовать в разных исходных файлах для ссылки на один и тот же объект, оно должно быть описано как внешнее. Например:
extern double sqrt(double);
extern instream cin;
Самый обычный способ обеспечить согласованность исходных файлов – это поместить такие описания в отдельные файлы, называемые заголовочными (или header) файлами, а затем включить, то есть скопировать, эти заголовочные файлы во все файлы, где нужны эти описания. Например, если описание sqrt хранится в заголовочном файле для стандартных математических функций math.h, и вы хотите извлечь квадратный корень из 4, можно написать:
#include "math.h"
//...
x = sqrt(4);
Поскольку обычные заголовочные файлы включаются во многие исходные файлы, они не содержат описаний, которые не должны повторяться. Например, тела функций даются только для inline-подставляемых функций и инициализаторы даются только для констант. За исключением этих случаев, заголовочный файл является хранилищем информации о типах. Он обеспечивает интерфейс между отдельно компилируемыми частями программы. В команде включения include имя файла, заключенное в угловые скобки, например, относится к файлу с этим именем в стандартном каталоге (часто это /usr/include/CC); на файлы, находящиеся в каких-либо других местах ссылаются с помощью имен, заключенных в двойные кавычки. Например:
#include "math1.h"
#include "/usr/bs/math2.h"
включит math1.h из текущего пользовательского каталога, а math2.h из каталога /usr/bs.
Здесь приводится очень маленький законченный пример программы, в котором строка определяется в одном файле, а ее печать производится в другом. Файл header.h определяет необходимые типы:
// header.h
extern char* prog_name;
extern void f();
В файле main.c находится главная программа:
// main.c
#include "header.h"
char* prog_name = "программирование";
main()
{
f();
}
а файл f.c печатает строку:
// f.c
#include
#include "header.h"
void f()
{
cout << prog_name << "\n";
}
main() { ... }
определяет функцию, названную main. Каждая программа должна содержать функцию с именем main, и работа программы начинается с выполнения этой функции.
Вывод
Функция printf предназначена для вывода информации на экран, формат ее прост и гибок:
printf(<форматная строка>,<аргумент>,<аргумент>,…);
Форматная строка – это строка, которая начинается и заканчивается двойными кавычками (“вот так”). Целью функции printf является вывод этой строки на экран. До вывода аргументы, указанные в строке, преобразуются в соответствии со спецификаторами формата, указанными в самой строке. Все спецификаторы формата начинаются со знака % (процента), за которым обычно следует одна буква, указывающая тип данных и способ форматирования этих данных.
Для каждого спецификатора формата должен быть указан один и только один аргумент. Если аргумент принадлежит типу данных, который не соответствует указанному в спецификаторе формата, то С попытается проделать соответствующее преобразование. Аргументами могут быть переменные, константы, выражения, вызовы функций.
Спецификатор %d означает, что аргумент является целым. Ниже приведены наиболее часто используемые спецификаторы форматов:
%u беззнаковое целое;
%p значение указателя;
%f с плавающей точкой;
%e с плавающей точкой в экспоненциальном формате;
%c символ;
%s строка;
%x или %X целое в шестнадцатеричном формате.
Ширина поля может быть указана цифрой, помещенной между знаком % и буквой.
Например, десятичное поле шириной 4 символа будет указано так: %4d. Значение будет напечатано выровненным вправо (с ведущими нулями), так что общая длина поля будет равна 4 символам.
В форматной строке указываются также управляющие символы:
\n – символ перехода на новую строку;
\f – перевод формата или очистка экрана;
\t – табуляция;
\b – забой;
\xhhh – вставить символ с шестнадцатеричным кодом hhh, где hhh – от одной до трех шестнадцатеричных цифр.
Для вывода знака процента вставьте %%; для вывода обратной косой черты напечатайте две косых черты \\.
Например:
printf( “сумма %d \n”,sum);
Другие функции вывода: puts и putchar
Функция puts выводит на экран строку, оканчивающуюся символом перехода на новую строку.
Например:
puts(“Я изучаю С++”);
Внимание: Символ \n в конце строки отсутствует, т. к. он добавляется самой функцией puts.
Вторая функция, putchar, выводит на экран один символ и не добавляет \n. Оператор putchar(ch) эквивалентен printf(“%c”,ch), использование этих функций сделает вашу программу меньше и быстрее.
Замечание: Функции printf( ), puts(), putchar() описаны в заголовочном файле stdio.h, а функция putch () – в заголовочном файле conio.h.
Ввод
В языке Си имеется несколько функций, обеспечивающих ввод информации, некоторые из них принимают входную информацию из файла, или из входного потока, другие – с клавиатуры.
Функция scanf
Основное назначение этой функции – интерактивный ввод информации. Вид функции scanf эквивалентен виду функции printf:
scanf(<форматная строка>, <адрес>, <адрес>, …)
Функция scanf использует многие из тех спецификаторов формата со знаком %, что и функция printf: %d для целых чисел, %f для чисел с плавающей точкой, %s для строк и т. д.
Однако, у этой функции есть важная отличительная черта: за форматной строкой следуют не значения, а адреса.
Например:
scanf(“%d %d”,&a,&b);
эта строка означает, что программа ожидает ввода двух десятичных целых значений, разделенных пробелом: первое значение будет присвоено переменной a, а второе – переменной b. Обратите внимание на то, что для передачи значений применяется адресный оператор &, при помощи которого функции scanf передаются адреса переменных a и b.
Чтобы передавать в программу значения, разделяя их запятой, изменим строку таким образом:
scanf(“%d,%d”,&a,&b);
Использование для ввода функций gets и getch
Функция gets воспринимает любую информацию до тех пор, пока вы не нажмете клавишу Enter. Код, соответствующий этой клавише, в строку не вводится, но в конце строки добавляется нулевой символ \0.
Функция getch считывает с клавиатуры один символ, не отображая его на экране. Эта функция не передает символ в качестве параметра; она сама имеет тип char, и ее значение может быть непосредственно присвоено переменной типа char.
Замечание: Функция scanf () описана в заголовочном файле stdio.h, а функция getch () – в заголовочном файле conio.h.
Потоки ввода/ вывода в С++
Управлять вводом/ выводом в С++ можно двумя способами: с помощью функций и с помощью объектов. Объекты ввода/ вывода были специально разработаны в С++, и работать с ними гораздо проще и эффективнее, чем с функциями. Для вывода данных программа направляет данные в поток. Все данные, предназначенные для вывода, передаются в специальный объект (cout), который и отображает их на экране. Аналогично можно вызвать другой объект (cin), который будет собирать данные, набираемые на клавиатуре. Затем данные извлекаются из этого объекта и передаются переменным программы.
Синтаксис потокового вывода строится из объекта cout, оператора << и переменной (или константы):
cout <<идентификатор_переменной;
Пример1: вывод на экран значения целой переменной number
cout<<number;
Если выводятся значения нескольких переменных, то перед каждой из них должен стоять свой оператор вывода (<<).
Пример2: вывод на экран строки и значения целой переменной number
cout<<”The result is: ”<<number;
Пример3: вывод на экран строки и значения целой переменной number и переход на новую строку с помощью управляющего символа \n:
cout<<”The result is: ”<<number<<”\n”;
переход на новую строку с помощью манипулятора endl:
cout<<”The result is: ”<<number<<endl;
Синтаксис потокового ввода строится из объекта cin, оператора >> и переменной, которой присваивается вводимое значение:
cin >>имя_переменной;
Пример4: ввод значения целой переменной number
cin>>number;
С помощью одной инструкции ввода можно присвоить значения более чем одной переменной, например:
cin>>number>>i>>j;
Примечание Имена cin и cout произошли от слов C input (ввод С) и C output(вывод С).
Чтобы использовать потоковый ввод и вывод, в программу необходимо включить заголовочный файл iostream.h. Это делается следующим образом:
# include <iostream.h>
Именно с помощью угловых скобок в программу включаются файлы из каталогов компилятора. В заголовочном файле iostream.h находятся объявления и определения классов для объектов cin и cout.
Потоковый ввод/ вывод обрабатывает все встроенные типы данных С++. Непосредственно могут использоваться следующие типы данных:
int
char
float
double
Сводка операций С++
Приоритет операций убывает с увеличением номера категории. Все операции одной категории имеют одинаковый приоритет.

Категория
Операция
Название или действие


Наивысшего приоритета
( )
[ ]
->
::
.
Вызов функции
Индексирование
Косвенное обращение к члену класса
Спецификации доступа
Прямое обращение к члену класса


Унарные
!
`
+
-
++
--
&
*
sizeof
new
delete
Логическое отрицание
Дополнение до единицы
Унарный плюс
Унарный минус
Преинкремент или постинкремент
Предекремент или постдекремент
Адрес
Обращение
Размер
Создание динамического объекта
Удаление динамического объекта


Мультипликативные
*
/
%
Умножение
Деление
Деление по модулю


Косвенного обращения через указатель на член класса
.*
->*
Прямое косвенное обращение через указатель
Косвенное косвенное обращение через указатель


Аддитивные
+
-
Бинарный плюс
Бинарный минус


Сдвига
<<
>>
Сдвиг влево
Сдвиг вправо


Отношения
<
<=
>
>=
Меньше
Меньше или равно
Больше
Больше или равно


Равенства
= =
!=
Равно
Не равно



&
Побитовое И



^
Побитовое исключающее ИЛИ



|
Побитовое включающее ИЛИ



&&
Логическое И



||
Логическое ИЛИ



?:
Условная


Присваивания
=
*=
/=
%=
+=
-=
&=
^=
|=
<<=
>>=
Простое присваивание
Присваивание с умножением
Присваивание с делением
Присваивание с делением по модулю
Присваивание с суммой
Присваивание с разностью
Присваивание с побитовым И
Присваивание с побитовым исключающим ИЛИ
Присваивание с побитовым включающим ИЛИ
Присваивание с левым сдвигом
Присваивание с правым сдвигом


Запятая
,
Последовательное выполнение


Блоки
Блок - это возможно пустой список операторов, заключенный в фигурные скобки:
{ a=b+2; b++; }
Блок позволяет рассматривать несколько операторов как один. Область видимости имени, описанного в блоке, простирается до конца блока. Имя можно сделать невидимым с помощью описаний такого же имени во внутренних блоках.
Операторы if
Условный оператор имеет вид
if (выражение) оператор [else оператор]
Выражение может иметь следующие типы: целое, указатель или класс, для которого определено преобразование в целый тип или в указатель. Вычисляется выражение, и если оно не ноль, то выполняется первый подоператор. Если используется else, то второй подоператор выполняется, если выражение есть ноль. Неоднозначность else разрешается посредством того, что else связывается с последним встреченным if, не имеющим else.
Пример:
if (x>1)
if (y<=4) z=1;
else z=2;
Часть else относится ко второму if.
Программа в следующем примере осуществляет преобразование дюймов в сантиметры и сантиметров в дюймы; предполагается, что вы укажете единицы измерения вводимых данных, добавляя i для дюймов и c для сантиметров:
#include
main()
{
const float fac = 2.54;
float x, in, cm;
char ch = 0;
cout << "введите длину: ";
cin >> x >> ch;
if (ch == 'i') { // inch - дюймы
in = x;
cm = x*fac;
}
else if (ch == 'c') // cm - сантиметры
in = x/fac;
cm = x;
}
else
in = cm = 0;
cout << in << " in = " << cm << " cm\n";
}
Заметьте, что условие в операторе if должно быть заключено в круглые скобки.
Операторы switch
Оператор switch производит сопоставление значения с множеством констант. Проверки в предыдущем примере можно записать так:
switch (ch) {
case 'i':
in = x;
cm = x*fac;
break;
case 'c':
in = x/fac;
cm = x;
break;
default:
in = cm = 0;
break;
}
Операторы break применяются для выхода из оператора switch. Константы в вариантах case должны быть различными, и если проверяемое значение не совпадает ни с одной из констант, выбирается вариант default. Программисту не обязательно предусматривать default.
Оператор while
Оператор while имеет вид:
while (выражение) оператор
Выполнение оператора повторяется, пока значение выражения остается ненулевым. Проверка производится перед каждым выполнением оператора. Выражение обрабатывается как в условном операторе.
Рассмотрим копирование строки, когда заданы указатель p на ее первый символ и указатель q на целевую строку. По соглашению строка оканчивается символом с целым значением 0.
while (p != 0) {
*q = *p; // скопировать символ
q = q+1;
p = p+1;
}
*q = 0; // завершающий символ 0 скопирован не был
Следующее после while условие должно быть заключено в круглые скобки. Условие вычисляется, и если его значение не ноль, выполняется непосредственно следующий за ним оператор. Это повторяется до тех пор, пока вычисление условия не даст ноль.
Этот пример слишком пространен. Можно использовать операцию ++ для непосредственного указания увеличения, и проверка упростится:
while (*p) *q++ = *p++;
*q = 0;
где конструкция *p++ означает: "взять символ, на который указывает p, затем увеличить p."
Пример можно еще упростить, так как указатель p разыменовывается дважды за каждый цикл. Копирование символа можно делать тогда же, когда производится проверка условия:
while (*q++ = *p++) ;
Здесь берется символ, на который указывает p, p увеличивается, этот символ копируется туда, куда указывает q, и q увеличивается. Если символ ненулевой, цикл повторяется. Поскольку вся работа выполняется в условии, не требуется ни одного оператора. Чтобы указать на это, используется пустой оператор.
Оператор do-while
Оператор do-while имеет вид
do оператор while (выражение);
Выполнение оператора повторяется до тех пор, пока значение остается не нулем. Проверка выполняется после каждого выполнения оператора. Выражение обрабатывается так же, как в условном операторе.
Пример:
x=1;
do
cout<<”x=”<<x<<”\n”;
while (++x<10);
Содержание и требования к оформлению протокола работы
Протокол работы должен содержать:
краткий конспект теоретических сведений;
файлы с исходными текстами программ и файлы с расширениями .exe(в соответствующих каталогах).
Ход работы.
Задача 1. Напишите программу, которая считывает символ и выводит соответствующий код. (Используйте различные способы ввода и вывода).
Задача 2. Напишите программу, которая по введенным координатам двух точек на плоскости выводит уравнение прямой в виде ax+by+c=0.
Задача 3. Дано действительное число x. Не пользуясь никакими другими арифметическими операциями, кроме умножения, сложения и вычитания, вычислить 2x4-3x3+4x2-5x+6. Разрешается использовать не более 4 умножений и 4 сложений и вычитаний. (Можно использовать только заголовочный файл iostream.h).
Задача 4. Даны действительные числа x, y. Не пользуясь никакими другими арифметическими операциями, кроме умножения, сложения и вычитания, вычислить
3x2y2-2xy2-7x2y-4y2+15xy+2x2-3x+10y+6. Разрешается использовать не более 8 умножений и 8 сложений и вычитаний. (Можно использовать только заголовочный файл stdio.h).
Задача 5. Дано действительное число x. Не пользуясь никакими другими арифметическими операциями, кроме умножения, сложения и вычитания, вычислить 1-2x+3x2-4x3 и 1+2x+3x2+4x3. Разрешается использовать не более 8 операций.
Задача 6. Даны действительные положительные числа x, y, z.
а) Выяснить, существует ли треугольник с длинами сторон x, y, z.
б) Если треугольник существует, то ответить – является ли он остроугольным.
Задача 7. Даны действительные числа a, b, c, d, s, t, u (s и t одновременно не равны нулю). Известно, что точки (a,b) и (c,d) не лежат на прямой l, заданной уранением sx+ty+u=0. Прямая l разбивает координатную плоскость на две полуплоскости. Выяснить, верно ли, что точки (a,b) и (c,d) принадлежат разным полуплоскостям.
Задача 8. Даны действительные числа a, b, c, d, e, f, g, h. Известно, что точки (a,b) и (c,d) не лежат на прямой l, проходящей через точки (e,f) и (g,h). Прямая l разбивает координатную плоскость на две полуплоскости. Выяснить, верно ли, что точки (a,b) и (c,d) принадлежат одной и той же полуплоскости.
Задача 9. Даны действительные числа x1, x2, x3, y1, y2, y3. Принадлежит ли начало координат треугольнику с вершинами (x1, y1), (x2, y2), (x3, y3)?
Задача 10. Дано натуральное число (меньше 100), определяющее возраст человека в годах. Дать для этого числа наименования “год”, “года” или “лет”: например, 1 год, 23 года, 45 лет.
Задача 11.
Реализовать метод хорд для решения уравнения с заданной точностью.
Реализовать метод касательных для решения уравнения.
Реализовать метод хорд и касательных.
Реализовать метод Симпсона численного интегрирования функции F(x) на отрезке [a, b] с заданной точностью Epsilon.