Поможем написать учебную работу
Если у вас возникли сложности с курсовой, контрольной, дипломной, рефератом, отчетом по практике, научно-исследовательской и любой другой работой - мы готовы помочь.
Если у вас возникли сложности с курсовой, контрольной, дипломной, рефератом, отчетом по практике, научно-исследовательской и любой другой работой - мы готовы помочь.
Программирование на языке C
Лабораторная работа 1
Ознакомление со средой разработки. Консольная программа на языке C
Цель: Научиться работать в интегрированной среде разработки Dev C++, создавать простейшие консольные приложения, повторить синтаксис и принципы создания программ языка C.
Программа, разработанная в среде Dev C++, является проектом, состоящим из следующих основных файлов:
Пример файла программы на языке C, производящей расчет по закону Ома приведен ниже:
//---------------------------------------------------------------------------
#include <stdio.h>
//---------------------------------------------------------------------------
#define I 555
#define R 5.5
#pragma argsused
int main(int argc, char* argv[])
{
printf("Zakon Oma: U=I*R\n");
printf("I = %d; R = %f\n",I,R);
printf("U = %f\n",I*R);
return 0;
}
//---------------------------------------------------------------------------
Его можно условно разделить на три области:
Область включаемых файлов содержит команды препроцессора на включение файлов-заголовков (здесь включается файл работы со стандартным вводом/выводом - #include <stdio.h>), после окончания включения стандартных включаемых файлов следует команда прекращения кэширования файлов заголовков.
Далее записаны команды препроцессора для определения значений тока и сопротивления путем макроподстановок (#define I 555 и #define R 5.5), содержанием которых и исчерпывается область глобальных объявлений.
Перед основной функцией программы идет команда компилятору подавить вывод предупреждения о неиспользовании аргументов функции (#pragma argsused), которая служит для подавления сообщения о том, что аргументы функции main argc и argv не использованы в тексте функции. Сама основная функция состоит из трех функций форматированного вывода printf, определенных во включаемом файле stdio.h и оператора return, возвращающего 0 признак успешного выполнения программы. Первая из них служит для вывода заголовка, оканчивающегося символом перехода на новую строку (\n), вторая выводит значения I и R, третья результат расчета.
Более подробную информацию по каждому из операторов можно получить в среде Borland C++ Builder, установив курсор на этот оператор и нажав F1 или справочной системе Microsoft Development Network.
Для успешного выполнения работы необходимы следующие справочные сведения, изученные в курсе программирования. Нижеследующие разделы «Комментарии», «Типы и описания», «Выражения и операторы», «Основная функция программы main», «Стандартный ввод вывод», «Оператор возврата return», «Оператор условия if», а также «Операторы цикла» повторяют курс «Программирование» и приведены здесь в качестве материала для повторения его, а также в качестве справочника.
Комментарии могут быть двух типов:
Каждое имя и каждое выражение имеет тип, определяющий операции, которые могут над ними производиться. Например, описание
int inch;
определяет, что inch имеет тип int, то есть, inch является целой переменной.
Описание - это оператор, который вводит имя в программе. Описание задает тип этого имени. Тип определяет правильное использование имени или выражения. Для целых определены такие операции, как +, -, * и /. После того, как включен файл stream.h, объект типа int может также быть вторым операндом <<, когда первый операнд ostream.
Тип объекта определяет не только то, какие операции могут к нему применяться, но и смысл этих операций.
В C++ есть несколько основных типов и несколько способов создавать новые. Простейшие виды типов C++ описываются в следующих разделах, а более интересные оставлены на потом.
Основные типы, наиболее непосредственно отвечающие средствам аппаратного обеспечения, такие:
char символ (символьный)
short int короткий целый
int целый
long int длинный целый
float вещественный
double двойной вещественный
Первые четыре типа используются для представления целых, последние два - для представления чисел с плавающей точкой. Переменная типа char имеет размер, естественный для хранения символа на данной машине (обычно, байт), а переменная типа int имеет размер, соответствующий целой арифметике на данной машине (обычно, слово). Диапазон целых чисел, которые могут быть представлены типом, зависит от его размера. В C++ размеры измеряются в единицах размера данных типа char, поэтому char по определению имеет размер единица. Соотношение между основными типами можно записать так:
1 = sizeof(char) <= sizeof(short) <= sizeof(int) <= sizeof(long)
sizeof(float) <= sizeof(double)
В целом, предполагать что-либо еще относительно основных типов неразумно. В частности, то, что целое достаточно для хранения указателя, верно не для всех машин.
К основному типу можно применять прилагательное const. Это дает тип, имеющий те же свойства, что и исходный тип, за исключением того, что значение переменных типа const не может изменяться после инициализации.
const float pi = 3.14;
const char plus = '+';
Символ, заключенный в одинарные кавычки, является символьной константой. Заметьте, что часто константа, определенная таким образом, не занимает память; просто там, где требуется, ее значение может использоваться непосредственно. Константа должна инициализироваться при описании. Для переменных инициализация необязательна, но настоятельно рекомендуется. Оснований для введения локальной переменной без ее инициализации очень немного.
К любой комбинации этих типов могут применяться арифметические операции:
+ |
(плюс, унарный и бинарный) |
- |
(минус, унарный и бинарный) |
* |
(умножение) |
/ |
(деление) |
А также операции сравнения:
== |
(равно) |
!= |
(не равно) |
< |
(меньше) |
> |
(больше) |
<= |
(меньше или равно) |
>= |
(больше или равно) |
Заметьте, что целое деление дает целый результат: 7/2 есть 3. Над целыми может выполняться операция % получения остатка: 7%2 равно 1.
При присваивании и арифметических операциях C++ выполняет все осмысленные преобразования между основными типами, чтобы их можно было сочетать без ограничений:
double d = 1;
int i = 1;
d = d + i;
i = d + i;
Вот операции, создающие из основных типов новые типы:
* |
указатель на |
*const |
константный указатель на |
& |
ссылка на |
[] |
вектор |
() |
функция, возвращающая |
Например:
char* p |
// указатель на символ |
char *const q |
// константный указатель на символ |
char v[10] |
// вектор из 10 символов |
Все вектора в качестве нижней границы индекса имеют ноль, поэтому в v десять элементов: v[0] ... v[9]. Переменная указатель может содержать адрес объекта соответствующего типа:
char c;
// ...
p = &c; // p указывает на c
Унарное & является операцией взятия адреса.
В C++ имеется богатый набор операций, с помощью которых в выражениях образуются новые значения и изменяются значения переменных. Поток управления в программе задается с помощью операторов, а описания используются для введения в программе имен переменных, констант и т.д. Заметьте, что описания являются операторами, поэтому они свободно могут сочетаться с другими операторами.
В C++ имеется большое число операций, и они будут объясняться там, где (и если) это потребуется. Следует учесть, что операции
~ |
(дополнение) |
& |
(И) |
^ |
(исключающее ИЛИ) |
| |
(включающее ИЛИ) |
<< |
(логический сдвиг влево) |
>> |
(логический сдвиг вправо) |
применяются к целым, и что нет отдельного типа данных для логических действий.
Смысл операции зависит от числа операндов; унарное & является операцией взятия адреса, а бинарное & - это операция логического И. Смысл операции зависит также от типа ее операндов: + в выражении a+b означает сложение с плавающей точкой, если операнды имеют тип float, но целое сложение, если они типа int.
В C++ есть операция присваивания =, а не оператор присваивания, как в некоторых языках. Таким образом, присваивание может встречаться в неожиданном контексте; например, x=sqrt(a=3*x). Это бывает полезно. a=b=c означает присвоение c объекту b, а затем объекту a. Другим свойством операции присваивания является то, что она может совмещаться с большинством бинарных операций. Например, x[i+3]*=4 означает x[i+3]=x[i+3]*4, за исключением того факта, что выражение x[i+3] вычисляется только один раз. Это дает привлекательную степень эффективности без необходимости обращения к оптимизирующим компиляторам. К тому же это более кратко.
В большинстве программ на C++ широко применяются указатели. Унарная операция * разыменовывает указатель, т.е. *p есть объект, на который указывает p. Эта операция также называется косвенной адресацией. Например, если имеется char* p, то *p есть символ, на который указывает p. Часто при работе с указателями бывают полезны операция увеличения ++ и операция уменьшения --. Предположим, p указывает на элемент вектора v, тогда p++ делает p указывающим на следующий элемент.
Самый обычный вид оператора - оператор выражение. Он состоит из выражения, за которым следует точка с запятой. Например:
a = b*3+c;
cout << "go go go";
lseek(fd,0,2);
Простейшей формой оператора является пустой оператор:
;
Он не делает ничего. Однако он может быть полезен в тех случаях, когда синтаксис требует наличие оператора, а вам оператор не нужен.
Блок - это возможно пустой список операторов, заключенный в фигурные скобки:
{ a=b+2; b++; }
Блок позволяет рассматривать несколько операторов как один. Область видимости имени, описанного в блоке, простирается до конца блока. Имя можно сделать невидимым с помощью описаний такого же имени во внутренних блоках.
Каждая программа на C или C++ должна иметь функцию main; куда Вы поместите ее - дело вкуса. Некоторые программисты помещают функцию main в начало файла, другие - в конец. Вне зависимости от ее дислокации, следующие положения всегда применимы.
Аргументы главной функции.
Два параметра передаются в main процедурой начальной загрузки Dev C++: argc, argv.
Если Вы объявляете какие-либо из этих параметров, Вы
должны объявлять их строго в следующем порядке: argc, argv. Например, следующие объявления правильны:
main()
main(int argc)
main(int argc, char *argv[])
Объявление main(int argc) корректно, но маловероятно, что Вы будете использовать argc в Вашей программе без использования элементов argv.
argc и argv также доступны через глобальные переменные _argc и _argv.
Пример программы.
Приведем пример программы ARGS.EXE, демонстрирующей простой способ использования аргументов, передаваемых в main.
/* Программа ARGS.C */
#include <stdio.h>
#include <stdlib.h>
int main(int argc, char *argv[], char *env[])
{
int i;
printf("The value of argc is%d \n\n", argc);
printf("These are the %d command-line arguments passed to main: \n\n", argc);
for (i = 0; i < argc; i++);
printf(" argv[%d]: %s\n", i, argv[i]);
printf("\nThe environment string(s) on this system are:\n\n");
for (i = 0; env[i] !=NULL; i++);
printf(" env[%d]: %s\n", i, env[i]);
return 0;
}
Предположим, Вы выполняете ARGS.EXE со следующей командной строкой:
C:>args first_arg "arg with blanks" 3 4 "last but one" stop!
Заметим, что Вы можете передавать аргументы, содержащие пробелы, заключив их в двойные кавычки, как это сделано выше для "arg with blanks" и "last but one".
Вывод ARGS.EXE (предполагая, что переменные среды установлены, как здесь) может быть таким:
The value of argc is 7
These are the 7 command-line arguments passed to main:
argv[0]: C:\TC\TESTARGS.EXE
argv[1]: first_arg
argv[2]: arg with blanks
argv[3]:
argv[4]:
argv[5]: last but one
argv[6]: stop!
The environment string(s) on this system are:
env[0]: COMSPEC=C:\COMMAND.COM
env[1]: PROMPT=$p $q
env[2]: PATH= C:\SPRINT;C:\DOS;C:\TC
Максимальная общая длина аргументов командной строки, передаваемых в main (включая разделяющие их пробелы и само имя программы) - 128 символов (это - ограничение DOS, т.е. для Windows оно уже больше).
Самый простой механизм ввода заключается в чтении по одному символу за раз из "стандартного ввода", обычно с терминала пользователя, с помощью функции getchar. Функция getchar() при каждом к ней обращении возвращает следующий вводимый символ. В большинстве сред, которые поддерживают
язык "с", терминал может быть заменен некоторым файлом с помощью обозначения < : если некоторая программа prog использует функцию getchar то командная строка
PROG<INFILE
приведет к тому, что PROG будет читать из файла INFILE, а не с терминала. Переключение ввода делается таким образом, что сама программа PROG не замечает изменения
Функция getchar возвращает значение EOF, когда она попадает на конец файла, какой бы ввод она при этом не считывала. Стандартная библиотека полагает символическую константу EOF равной -1 (посредством #define в файле stdio.h), но проверки следует писать в терминах EOF, а не -1, чтобы избежать зависимости от конкретного значения.
Вывод можно осуществлять с помощью функции putchar(c), помещающей символ 'с' в "стандартный ввод", который по умолчанию является терминалом. Вывод можно направить в некоторый файл с помощью обозначения > : если PROG использует putchar, то командная строка
PROG>OUTFILE
приведет к записи стандартного вывода в файл OUTFILE, а не на терминал.
Вывод, осуществляемый функцией printf, также поступает в стандартный вывод, и обращения к putchar и printf могут перемежаться.
Поразительное количество программ читает только из одного входного потока и пишет только в один выходной поток; для таких программ ввод и вывод с помощью функций getchar, putchar и printf может оказаться вполне адекватным и для начала определенно достаточным. Это особенно справедливо тогда, когда имеется возможность указания файлов для ввода и вывода и поточный механизм для связи вывода одной программы с вводом другой. Рассмотрим, например, программу LOWER, которая преобразует прописные буквы из своего ввода в строчные:
#include <stdio.h>
main() /* convert input to lower case */
{
int c;
while ((c = getchar()) != EOF)
putchar(isupper(c) ? tolower(c) : c);
}
"Функции" isupper и tolower на самом деле являются макросами, определенными в stdio.h . Макрос isupper проверяет, является ли его аргумент буквой из верхнего регистра, и возвращает ненулевое значение, если это так, и нуль в противном случае. Макрос tolower преобразует букву из верхнего регистра в ту же букву нижнего регистра. Независимо от того, как эти функции реализованы на конкретной машине, их внешнее поведение совершенно одинаково, так что использующие их программы избавлены от знания символьного набора.
Кроме того отметим, что в стандартной библиотеке ввода/вывода "функции" getchar и putchar на самом деле могут быть макросами. Это позволяет избежать накладных расходов на обращение к функции для обработки каждого символа.
Две функции: printf для вывода и scanf для ввода позволяют преобразовывать численные величины в символьное представление и обратно. Они также позволяют генерировать и интерпретировать форматные строки. Мы уже всюду в предыдущих главах неформально использовали функцию printf; здесь приводится более полное и точное описание. Функция
printf(control, arg1, arg2, ...)
преобразует, определяет формат и печатает свои аргументы в стандартный вывод под управлением строки control. Управляющая строка содержит два типа объектов: обычные символы, которые просто копируются в выходной поток, и спецификации преобразований, каждая из которых вызывает преобразование и печать очередного аргумента printf.
Строка формата используется при каждом обращении к функциям семейства ...printf для указания того, как функция должна преобразовать, сформатировать и вывести свои аргументы.
Аргументов не должно быть меньше спецификаторов формата. В противном случае результаты непредсказуемы и, возможно, катастрофические. Лишние аргументы (сверх количества, требуемого строкой формата) просто игнорируются.
Строка формата - символьная строка, содержащая объекты двух типов: основные символы и спецификаторы формата.
Спецификаторы формата функций семейства ...printf имеют следующую форму:
% [flags] [width] [.prec] [F|N|h|l|L] type
Каждый спецификатор формата начинается с символа процента (%). После % следуют, в указанном порядке:
Символ |
Воздействие # на arg |
c,s,d,i,u |
Не влияет. |
o |
В начало ненулевого arg добавляется 0. |
x или X |
В начало arg добавляется 0х (или 0Х) |
e,E или f |
Результат всегда содержит десятичную точку, даже если после нее нет цифр. Обычно десятичная точка появляется, только если после нее есть цифры. |
g или G |
То же, что е и Е; кроме того, незначащие нули не удаляются. |
d,i,o,u,x,X |
.n указывает, что по крайней мере n цифр будут выведены. Если входной аргумент имеет менее n цифр, выводимое значение дополняется слева нулями. Если входной аргумент имеет более n цифр, выводимое значение не усекается. |
e,E,f |
.n указывает, что после десятичной точки выводятся n символов, и последняя выводимая цифра округляется. |
g,G |
.n указывает, что выводится не более n значащих цифр. |
c |
.n не влияет на выводимое поле. |
s |
.n указывает, что выводится не более n символов. |
Модификатор длины аргумента |
Как интерпретируется arg |
F |
arg интерпретируется как дальний указатель. |
N |
arg интерпретируется как ближний указатель. N не может быть использовано ни для каких преобразований в модели памяти huge. |
h |
arg интерпретируется как short int для d, i, o, u, x или X |
l |
arg интерпретируется как long int для d, i, o, u, x или X; arg интерпретируется как double для e, E, f, g или G. |
L |
arg интерпретируется как long double для e, E, f, g или G. |
Символ типа |
Входной аргумент |
Формат вывода |
Числовые |
||
d |
integer |
Десятичное целое (с учетом знака) |
i |
integer |
Десятичное целое (с учетом знака) |
o |
integer |
Беззнаковое восьмеричное целое |
u |
integer |
Беззнаковое десятичное целое |
x |
integer |
Беззнаковое шестнадцатеричное целое (с цифрами a,b,c,d,e,f) |
X |
integer |
Беззнаковое шестнадцатеричное целое (с цифрами A,B,C,D,E,F) |
f |
floating-point |
Значение (с учетом знака) в виде [-]dddd.dddd..., где количество цифр после десятичной точки равно значению точности (если задано ненулевое значение точности). |
e |
floating-point |
Значение (с учетом знака) в виде [-]d.ddd...e[+/-]ddd где одна цифра предшествует десятичной точке; количество цифр после десятичной точки равно значению точности; порядок всегда содержит по крайней мере две цифры |
g |
floating-point |
Значение (с учетом знака) либо в виде e, либо в виде f, исходя из заданного значения и точности, причем значение точности определяет количество значащих цифр. Незначащие нули и десятичная точка выводятся, только если это необходимо. Формат е используется, только если порядок результата преобразования превышает значение точности или меньше -4. |
E |
floating-point |
То же, что и е, но для экспоненты используется символ E |
G |
floating-point |
То же, что и g, но для экспоненты используется символ E, если выводится формат e |
Символьные |
||
c |
Character |
Одиночный символ |
s |
Указатель на строку |
Символы выводятся, пока не встретится нуль-символ (\0) или пока не будет выведено максимальное число символов (значение спецификатора точности) |
% |
нет |
Выводится символ % |
Указатели |
||
n |
Указатель на int |
Записывыает (по адресу, на который указывает аргумент) счетчик выведенных ранее символов |
p |
pointer |
Выводит аргумент в виде указателя. Формат зависит от используемой модели памяти: XXXX:YYYY или YYYY (только смещение) |
!!! Бесконечные числа с плавающей точкой выводятся как +INF и -INF. Не-Число (в смысле IEEE) выводится как +NAN или -NAN.
Следующая таблица демонстрирует влияние задания различных спецификаций на печать "HELLO, WORLD" (12 символов). Мы поместили двоеточия вокруг каждого поля для того, чтобы вы могли видеть его протяженность.
:%10s: :HELLO, WORLD:
:%10-s: :HELLO, WORLD:
:%20s: : HELLO, WORLD:
:%-20s: :HELLO, WORLD :
:%20.10s: : HELLO, WOR:
:%-20.10s: :HELLO, WOR :
:%.10s: :HELLO, WOR:
Предостережение: printf использует свой первый аргумент для определения числа последующих аргументов и их типов. Если количество аргументов окажется недостаточным или они будут иметь несоответственные типы, то возникнет путаница и вы получите бессмысленные результаты.
Функция возвращает количество выведенных символов или EOF в случае ошибки.
Осуществляющая ввод функция scanf является аналогом printf и позволяет проводить в обратном направлении многие из тех же самых преобразований. Функция
scanf(control, arg1, arg2, ...)
читает символы из стандартного ввода, интерпретирует их в соответствии с форматом, указанном в аргументе control, и помещает результаты в остальные аргументы. Управляющий аргумент описывается ниже; другие аргументы, каждый из которых должен быть указателем, определяют, куда следует поместить соответствующим образом преобразованный ввод.
Управляющая строка обычно содержит спецификации преобразования, которые используются для непосредственной интерпретации входных последовательностей. Управляющая строка может содержать:
Спецификация преобразования управляет преобразованием следующего поля ввода. нормально результат помещается в переменную, которая указывается соответствующим аргументом. Если, однако, с помощью символа * указано подавление присваивания, то это поле ввода просто пропускается и никакого присваивания не производится. Поле ввода определяется как строка символов, которые отличны от символов простых промежутков; оно продолжается либо до следующего символа пустого промежутка, либо пока не будет исчерпана ширина поля, если она указана. Отсюда следует, что при поиске нужного ей ввода, функция scanf будет пересекать границы строк, поскольку символ новой строки входит в число пустых промежутков.
Символ преобразования определяет интерпретацию поля ввода; согласно требованиям основанной на вызове по значению семантики языка "с" соответствующий аргумент должен быть указателем. Допускаются следующие символы преобразования:
Перед символами преобразования d, o и x может стоять l, которая означает , что в списке аргументов должен находиться указатель на переменную типа long, а не типа int. Аналогично, буква l может стоять перед символами преобразования e или f, говоря о том, что в списке аргументов должен находиться указатель на переменную типа double, а не типа float.
Например, обращение
int i;
float x;
char name[50];
scanf("&d %f %s", &i, &x, name);
со строкой на вводе
25 54.32e-1 THOMPSON
приводит к присваиванию i значения 25,x - значения 5.432 и name - строки "THOMPSON", надлежащим образом законченной символом \ 0. эти три поля ввода можно разделить столькими пробелами, табуляциями и символами новых строк, сколько вы пожелаете. Обращение
int i;
float x;
char name[50];
scanf("%2d %f %*d %2s", &i, &x, name);
с вводом
56789 0123 45A72
присвоит i значение 56, x - 789.0, пропустит 0123 и поместит в name строку "45". При следующем обращении к любой процедуре ввода рассмотрение начнется с буквы A. В этих двух примерах name является указателем и, следовательно, перед ним не нужно помещать знак &.
В качестве другого примера перепишем теперь элементарный калькулятор из главы 4, используя для преобразования ввода функцию scanf:
#include <stdio.h>
main() /* rudimentary desk calculator */
{
double sum, v;
sum =0;
while (scanf("%lf", &v) !=eof)
printf("\t%.2f\n", sum += v);
}
выполнение функции scanf заканчивается либо тогда, когда она исчерпывает свою управляющую строку, либо когда некоторый элемент ввода не совпадает с управляющей спецификацией. В качестве своего значения она возвращает число правильно совпадающих и присвоенных элементов ввода. Это число может быть использовано для определения количества найденных элементов ввода. При выходе на конец файла возвращается EOF; подчеркнем, что это значение отлично от 0, что следующий вводимый символ не удовлетворяет первой спецификации в управляющей строке. При следующем обращении к scanf поиск возобновляется непосредственно за последним введенным символом.
Заключительное предостережение: аргументы функции scanf должны быть указателями. Несомненно наиболее распространенная ошибка состоит в написании
scanf("%d", n);
вместо
scanf("%d", &n);
Здесь указаны не все тонкости работы функции scanf. За более подробными сведениями обращайтесь в соответствующие справочники и учебники.
Функция возвращает количество прочитанных символов или EOF в случае ошибки.
Если тип type возвращаемой функции не void, тело функции должно содержать по крайней мере один оператор return:
return возвращаемое-выражение;
где возвращаемое-выражение должно быть типа type или типа, который преобразуется в type присваиванием. Значение возвращаемое-выражение - это значение, которое возвращает функция. Это значение rvalue, а не lvalue:
t = func(arg);
func(arg) = t; // неверно в Си; верно в C++, если функция
// возвращает ссылку.
(func(arg))++; // неверно в Си; верно в C++, если функция
// возвращает ссылку.
При достижении оператора return функция завершается; если return не встречен, выполнение заканчивается при достижении последней тела функции.
Если возвращаемый тип - void, оператор return может быть записан
...
return;
Формат оператора:
if (выражение) оператор-1; [else оператор-2;]
Выполнение оператора if начинается с вычисления выражения.
Далее выполнение осуществляется по следующей схеме:
После выполнения оператора if значение передается на следующий оператор программы, если последовательность выполнения операторов программы не будет принудительно нарушена использованием операторов перехода.
Пример:
if (i < j) i++:
else { j = i-3; i++; }
Этот пример иллюстрирует также и тот факт, что на месте оператор-1, так же как и на месте оператор-2 могут находиться сложные конструкции.
Допускается использование вложенных операторов if. Оператор if может быть включен в конструкцию if или в конструкцию else другого оператора if. Чтобы сделать программу более читабельной, рекомендуется группировать операторы и конструкции во вложенных операторах if, используя фигурные скобки. Если же фигурные скобки опущены, то компилятор связывает каждое ключевое слово else с наиболее близким if, для которого нет else.
Примеры:
int main ( )
{
int t=2, b=7, r=3;
if (t>b)
{
if (b < r) r=b;
}
else r=t;
return (0);
}
В результате выполнения этой программы r станет равным 2.
Если же в программе опустить фигурные скобки, стоящие после оператора if, то программа будет иметь следующий вид:
int main ( )
{
int t=2,b=7,r=3;
if ( a>b )
if ( b < c ) t=b;
else r=t;
return (0);
}
В этом случае r получит значение равное 3, так как ключевое слово else относится ко второму оператору if, который не выполняется, поскольку не выполняется условие, проверяемое в первом операторе if.
Следующий фрагмент иллюстрирует вложенные операторы if:
char ZNAC;
int x,y,z;
:
if (ZNAC == '-') x = y - z;
else if (ZNAC == '+') x = y + z;
else if (ZNAC == '*') x = y * z;
else if (ZNAC == '/') x = y / z;
else ...
Оператор цикла while называется циклом с предусловием и имеет следующий формат:
while(выражение) тело ;
В качестве выражения допускается использовать любое выражение языка Си, а в качестве тела любой оператор, в том числе пустой или составной. Схема выполнения оператора while следующая:
В операторе while вначале происходит проверка условия. Поэтому оператор while удобно использовать в ситуациях, когда тело оператора не всегда нужно выполнять.
Внутри оператора while можно использовать локальные переменные, которые должны быть объявлены с определением соответствующих типов.
Оператор цикла do while называется оператором цикла с постусловием и используется в тех случаях, когда необходимо выполнить тело цикла хотя бы один раз. Формат оператора имеет следующий вид:
do тело while(выражение);
В качестве выражения допускается использовать любое выражение языка Си, а в качестве тела любой оператор, в том числе пустой или составной.
Схема выполнения оператора do while:
Операторы while и do while могут быть вложенными.
Пример:
int i,j,k;
...
i=0; j=0; k=0;
do { i++;
j--;
while (a[k] < i) k++;
}
while (i<30 && j<-30);
Чтобы прервать выполнение цикла до того, как условие станет ложным, можно использовать оператор break. (см. ниже).
Оператор for - это наиболее общий способ организации цикла. Он имеет следующий формат:
for ([выражение 1]; [выражение 2]; [выражение 3]) тело
Выражение 1 обычно используется для установления начального значения переменных, управляющих циклом (может отсутствовать).
Выражение 2 - это выражение, определяющее условие, при котором тело цикла будет выполняться (может отсутствовать).
Выражение 3 определяет изменение переменных, управляющих циклом после каждого выполнения тела цикла (может отсутствовать).
В качестве тела может быть использован пустой или составной (блочный) оператор.
Схема выполнения оператора for:
Существенно то, что проверка условия всегда выполняется в начале цикла. Это значит, что тело цикла может ни разу не выполниться, если условие выполнения сразу будет ложным.
Пример:
int main()
{ int i,b;
for (i=1; i<10; i++) b=i*i;
return 0; }
В этом примере вычисляются квадраты чисел от 1 до 9.
Оператор цикла for может быть заменен оператором while следующим образом:
выражение-1;
while(выражение-2)
{ тело
выражение-3;
}
Некоторые варианты использования оператора for повышают его гибкость за счет возможности использования нескольких переменных, управляющих циклом.
Пример:
int main()
{ int top, bot;
char string[100], temp;
for ( top=0, bot=100 ; top < bot ; top++, bot--)
{ temp=string[top];
string[bot]=temp;
}
return 0;
}
В этом примере, реализующем запись строки символов в обратном порядке, для управления циклом используются две переменные top и bot. Отметим, что на месте выражение 1 и выражение 3 здесь используются несколько выражений, записанных через запятую, и выполняемых последовательно.
Чтобы прервать выполнение цикла до того, как условие выхода из цикла станет ложным, можно использовать оператор break. (см. ниже).
Внутри оператора for можно использовать локальные переменные, которые должны быть объявлены с определением соответствующих типов.
Так как согласно синтаксису языка Си оператор может быть пустым, тело оператора for также может быть пустым. Такая форма оператора может быть использована для организации поиска.
Пример:
for (i=0; t[i]<10 ; i++) ;
В данном примере переменная цикла i принимает значение номера первого элемента массива t, значение которого больше 10.
Оператор break обеспечивает прекращение выполнения самого внутреннего из объединяющих его операторов switch, do, for, while. После выполнения оператора break управление передается оператору, следующему за прерванным.
Одним из вариантов использования оператора break в цикле for является бесконечный цикл. Для организации такого цикла можно использовать пустое условное выражение, а для выхода из цикла обычно используют дополнительное условие и оператор break.
Пример:
for (;;)
{ ...
... break;
...
}
Аналогичный способ может быть использован и для циклов while и do…while.
Оператор continue, как и оператор break, используется только внутри операторов цикла, но в отличие от него выполнение программы продолжается не с оператора, следующего за прерванным оператором, а с начала прерванного оператора. Формат оператора следующий:
continue;
Пример:
int main()
{ int a,b;
for (a=1,b=0; a<100; b+=a,a++)
{ if (b%2) continue; ... /* обработка четных сумм */ }
return 0;
}
Когда сумма чисел от 1 до а становится нечетной, оператор continue передает управление на очередную итерацию цикла for, не выполняя операторы обработки четных сумм.
Оператор continue, как и оператор break, прерывает самый внутренний из объемлющих его циклов.
Составить программу циклического вычисления таблицы площади круга или длины окружности (в зависимости от варианта задания) начиная от значения радиуса R0 до Rn с шагом Rs (либо вместо шага задается количество выводимых точек N, в этом случае шаг должен быть одинаков между ними). Значения R0, Rn, Rs (или N) вводить с клавиатуры (все вещественного типа). Предусмотреть анализ всей введенной информации на ошибки. Программа должна работать циклически и в качестве выхода из цикла использовать условие R0=0. Типы внешнего и внутреннего циклов выбираются по варианту. Вывести исходные данные и результат в виде:
Sкруга(R0) = rez0;
…
Sкруга(Rn) = rezn;
Где rez0…rezn результаты вычисления (вещественные).
Вариант задания рассчитывается по номеру студента в журнале преподавателя.
Вариант |
Внешний цикл (программа) |
Внутренний цикл (таблица) |
Вводи-мый пар-р |
Функция |
Вариант |
Внешний цикл (программа) |
Внутренний цикл (таблица) |
Вводи-мый пар-р |
Функция |
1 |
for |
while |
Rs |
Sкруга |
15 |
for |
for |
Rs |
Lокружн. |
2 |
for |
do…while |
N |
Sкруга |
16 |
do…while |
while |
N |
Lокружн. |
3 |
while |
for |
Rs |
Sкруга |
17 |
do…while |
do…while |
Rs |
Lокружн. |
4 |
while |
do…while |
N |
Sкруга |
18 |
do…while |
for |
Rs |
Lокружн. |
5 |
while |
while |
Rs |
Sкруга |
19 |
for |
while |
N |
Sкруга |
6 |
for |
for |
Rs |
Sкруга |
20 |
for |
do…while |
Rs |
Sкруга |
7 |
do…while |
while |
N |
Sкруга |
21 |
while |
for |
N |
Sкруга |
8 |
do…while |
do…while |
Rs |
Sкруга |
22 |
do…while |
while |
Rs |
Sкруга |
9 |
do…while |
for |
N |
Sкруга |
23 |
for |
while |
N |
Lокружн. |
10 |
for |
while |
Rs |
Lокружн. |
24 |
for |
do…while |
Rs |
Lокружн. |
11 |
for |
do…while |
N |
Lокружн. |
25 |
while |
for |
N |
Lокружн. |
12 |
while |
for |
N |
Lокружн. |
26 |
do…while |
while |
Rs |
Lокружн. |
13 |
while |
do…while |
Rs |
Lокружн. |
27 |
for |
while |
N |
Lокружн. |
14 |
while |
while |
N |
Lокружн. |
28 |
for |
for |
N |
Sкруга |
Отчет должен содержать следующие пункты:
Турбо С++. Начальное руководство
Borland C++. Руководство программиста
Керниган Б.В. , Ричи Д.М. Язык С.
Марченко А.Л. C++. Бархатный путь
Бьярн Страустрап Введение в язык Си++
Бьярн Страустрап Справочное руководство по Си++
Borland C++ Builder