Вы находитесь на странице: 1из 15

Программирование на языке C

Лабораторная работа 1

Ознакомление со средой разработки. Простейшая


программа на языке C
Цель: Научиться работать в интегрированной среде разработки Dev C++, создавать простейшие консольные
приложения, ознакомиться с функциями вывода информации.

Основные теоретические сведения


Программа, разработанная в среде Dev C++, является проектом, состоящим из следующих основных
файлов:
1 Файла проекта *.dev, который содержит имя будущей программы, списки всех необходимых
модулей и все настройки компилятора и линковщика;
2 Одного или нескольких модулей *.c, *.cpp – текстовых файлов, написанных на языке C или C++,
один из которых содержит основную функцию main (или WinMain);
3 Файлов заголовков (включаемых файлов) *.h, *.hpp, содержащих обычно описания типов данных и
прототипов функций;
4 Файла(ов) ресурсов *.res (скомпилированных), *.rc (исходных), содержащих необходимые ресурсы
проекта (иконки, картинки, и др.);

Пример простейшей программы


Пример файла программы на языке 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;
}
//---------------------------------------------------------------------------

Его можно условно разделить на три области:


5 Область включаемых файлов;
6 Область объявлений глобальных определений (макросов), переменных, функций;
7 Область основной функции main.
Область включаемых файлов содержит команды препроцессора на включение файлов-заголовков (здесь
включается файл работы со стандартным вводом/выводом - #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.

Для успешного выполнения работы необходимы следующие справочные сведения.

Комментарии
Комментарии могут быть двух типов:
8 /*Комментарий*/ – комментарием являются все символы, заключенные между символами «/*» и
«*/» (т.е. независимо от количества строк).
9 //Комментарий – комментарием являются все символы, начиная от символов «//» и до конца
текущей строки.

Типы и описания
Каждое имя и каждое выражение имеет тип, определяющий операции, которые могут над ними
производиться. Например, описание
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++; }

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

Основная функция программы – main


Каждая программа на C или C++ должна иметь функцию main; куда Вы поместите ее - дело вкуса.
Некоторые программисты помещают функцию main в начало файла, другие - в конец. Вне зависимости от ее
дислокации, следующие положения всегда применимы.
Аргументы главной функции.
Два параметра передаются в main процедурой начальной загрузки Dev C++: argc, argv.
10 argc, целое, содержащее число аргументов командной строки, передаваемых в main.
11 argv - массив указателей на строки (char *[]).
o В DOS 3.x и выше arg[0] - это полное имя выполняемой программы.
o argv[1] указывает на первую строку, набранную в команде DOS после имени программы.
o argv[2] указывает на вторую строку, набранную после имени программы.
o argv[argc - 1] указывает на последний аргумент, передаваемый в main.
o argv[argc] содержит ноль.
Если Вы объявляете какие-либо из этих параметров, Вы
должны объявлять их строго в следующем порядке: 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]: 3
argv[4]: 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 и putchar
Самый простой механизм ввода заключается в чтении по одному символу за раз из "стандартного
ввода", обычно с терминала пользователя, с помощью функции 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
Две функции: printf для вывода и scanf для ввода позволяют преобразовывать численные величины в
символьное представление и обратно. Они также позволяют генерировать и интерпретировать форматные
строки. Мы уже всюду в предыдущих главах неформально использовали функцию printf; здесь приводится
более полное и точное описание. Функция

printf(control, arg1, arg2, ...)

преобразует, определяет формат и печатает свои аргументы в стандартный вывод под управлением строки
control. Управляющая строка содержит два типа объектов: обычные символы, которые просто копируются
в выходной поток, и спецификации преобразований, каждая из которых вызывает преобразование и печать
очередного аргумента printf.
Строка формата используется при каждом обращении к функциям семейства ...printf для указания того,
как функция должна преобразовать, сформатировать и вывести свои аргументы.
Аргументов не должно быть меньше спецификаторов формата. В противном случае результаты
непредсказуемы и, возможно, катастрофические. Лишние аргументы (сверх количества, требуемого
строкой формата) просто игнорируются.
Строка формата - символьная строка, содержащая объекты двух типов: основные символы и
спецификаторы формата.
12 Основные символы просто копируются в выходной поток без изменений.
13 Спецификаторы формата вызывают применение определяемого ими форматирования к значениям
аргументов перед выводом их в поток.
Спецификаторы формата функций семейства ...printf имеют следующую форму:

% [flags] [width] [.prec] [F|N|h|l|L] type


Каждый спецификатор формата начинается с символа процента (%). После % следуют, в указанном
порядке:
14 необязательная последовательность символов-флагов, [flags] - Выравнивание при выводе,
отображение знака числа, десятичной точки, незначащих нулей, восьмеричные и
шестнадцатеричные префиксы
o - Результат выравнивается влево и дополняется пробелами справа. Если не
задан, результат выравнивается вправо и дополняется слева пробелами или
нулями.
o + Результат преобразования с учетом знака всегда начинается со знака плюс (+)
или минус (-).
o Пробел Если значение неотрицательно, вывод начинается с пробела вместо плюса;
отрицательные значения начинаются с минуса. Плюс (+) имеет приоритет над
пробелом ( ), если заданы оба.
o # Определяет, что arg преобразуется с помощью "альтернативной формы".
Смотри следующую таблицу.
Символ Воздействие # на arg

c,s,d,i,u Не влияет.

o В начало ненулевого arg добавляется 0.


x или X В начало arg добавляется 0х (или 0Х)

e,E или f Результат всегда содержит десятичную точку,


даже если после нее нет цифр. Обычно десятичная
точка появляется, только если после нее есть
цифры.

g или G То же, что е и Е; кроме того, незначащие нули не


удаляются.
15 необязательный спецификатор ширины, [width] - Минимальное количество символов для печати,
дополнение пробелами или нулями. Ширина задается одним из двух способов: непосредственно -
строкой десятичных цифр, или косвенно - звездочкой (*). Если вы используете звездочку,
минимальная ширина поля вывода определяется значением очередного аргумента (который
должен иметь тип int). Ни при каких обстоятельствах спецификатор ширины, его отсутствие или
неверное значение не будет вызывать усечения выводимого поля. Если результат преобразования
оказывается шире установленного спецификатором, поле вывода просто расширяется, чтобы
поместить результат преобразования.
o n По крайней мере n символов будут напечатаны. Если выводимое значение
содержит менее n символов, поле вывода дополняется пробелами (справа - если
указан символ-флаг "минус"(-), слева - в остальных случаях).
o 0n По крайней мере n символов будут напечатаны. Если выводимое значение
содержит менее n символов, поле вывода дополняется нулями слева.
o * Значение спецификатора ширины содержится в списке аргументов и предшествует
форматируемому аргументу.
16 необязательный спецификатор точности, [.prec] - Максимальное количество символов для печати;
для целых чисел - минимальное количество цифр для печати. Спецификатор точности всегда
начинается с точки точности (.), которая отделяет его от предшествующего спецификатора
ширины. Как и ширина, точность задается либо непосредственно - строкой десятичных цифр,
либо косвенно - звездочкой (*). Если вы используете звездочку, точность поля вывода
определяется значением очередного аргумента (который интерпретируется как int). Если вы
используете звездочки для ширины, точности, или для того и другого, аргумент ширины должен
соответствовать текущему спецификатору, за ним должен следовать аргумент точности, а затем -
аргумент с данными, которые должны быть преобразованы.
o (не задан) Точность устанавливается по умолчанию: 1 - для типов d, i, o, u, x, X; 6 - для
типов e, E, f; все значащие цифры - для типов g, G; выводятся все символы до
первого нуль-символа - для типа s; не влияет - на тип с.
o .0 Для типов d,i,o,u,x точность устанавливается по умолчанию; для типов e,E,f -
не выводится десятичная точка.
o .n Выводится n символов или n десятичных позиций. Если выводимое значение
содержит более n символов, оно может быть усечено или округлено (в
зависимости от символа типа).
d,i,o,u,x,X .n указывает, что по крайней мере n цифр будут
выведены. Если входной аргумент имеет менее n
цифр, выводимое значение дополняется слева
нулями. Если входной аргумент имеет более n цифр,
выводимое значение не усекается.

e,E,f .n указывает, что после десятичной точки выводятся


n символов, и последняя выводимая цифра
округляется.

g,G .n указывает, что выводится не более n значащих


цифр.
c .n не влияет на выводимое поле.

s .n указывает, что выводится не более n символов.


o * Значение спецификатора точности содержится в списке аргументов и
предшествует форматируемому аргументу.
o !!! Если явно задана нулевая точность, И спецификатор формата для данного
поля относится к целочисленным (т.е., d,i,o,u,x), И значение, которое должно
быть выведено, равно 0, - ни одной цифры не будет выведено в это поле (т.е.
поле будет заполнено пробелами).
17 необязательный модификатор длины аргумента, [F|N|h|l|L] - Изменяет принимаемое по
умолчанию значение длины аргумента влияют на то, как функции семейства ...printf
интерпретируют тип данных соответствующего аргумента arg. F и N применяются только к аргу-
ментам, которые являются указателями (%p, %s и %n). h, l, и L применяются к числовым аргумен-
там (целым и с плавающей точкой).:
o N = near pointer. Изменяют интерпретацию arg. Обычно длина arg для
преобразований %p, %s или %n соответствует принимаемой по умолчанию для указателей
в используемой модели памяти. N требует: "Интерпретировать arg как ближний ука-
затель".
o F = far pointer. изменяют интерпретацию arg. Обычно длина arg для
преобразований %p, %s или %n соответствует принимаемой по умолчанию для указателей
в используемой модели памяти. F требует: "Интерпретировать arg как дальний указатель".
o h = short int. Замещает установленную по умолчанию длину числовых
аргументов: применяется только к целым типам, не влияют на символьные типы (c,s) или
на указатели (p,n).
o l = long. Замещает установленную по умолчанию длину числовых аргументов:
l применяется к целым типам (d,i,o,u,x,X) и типам с плавающей точкой (e,E,f,g и G), не
влияют на символьные типы (c,s) или на указатели (p,n).
o L = long double. Замещает установленную по умолчанию длину числовых
аргументов: применяется к целым типам (d,i,o,u,x,X) и типам с плавающей точкой (e,E,f,g
и G).
Модификатор длины Как интерпретируется 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.


18 type - символ типа преобразования.
Символ Входной Формат вывода
типа аргумент

Числовые

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
Осуществляющая ввод функция scanf является аналогом printf и позволяет проводить в обратном
направлении многие из тех же самых преобразований. Функция

scanf(control, arg1, arg2, ...)

читает символы из стандартного ввода, интерпретирует их в соответствии с форматом, указанном в


аргументе control, и помещает результаты в остальные аргументы. Управляющий аргумент описывается
ниже; другие аргументы, каждый из которых должен быть указателем, определяют, куда следует поместить
соответствующим образом преобразованный ввод.
Управляющая строка обычно содержит спецификации преобразования, которые используются для
непосредственной интерпретации входных последовательностей. Управляющая строка может содержать:
19 Пробелы, табуляции или символы новой строки ("символы пустых промежутков"), которые
игнорируются.
20 Обычные символы (не %), которые предполагаются совпадающими со следующими отличными от
символов пустых промежутков символами входного потока.
21 Спецификаторы формата имеют следующую форму: % [*] [width] [F/N] [h/l/L] type_character
состоящие из
o символа %
o необязательного символа подавления присваивания [*] - Подавляет запись в память
следующего входного поля.
o необязательного числа, задающего максимальную ширину поля [width] - Максимальное
количество читаемых символов; меньшее количество может быть прочитано, если ...scanf
встречает символ-разделитель или непреобразуемый символ.
o необязательный модификатор размера указателя, [F/N] – Изменяет принимаемоепо
умолчанию значение длины адреса:
 N = near pointer
 F = far pointer
o необязательный модификатор типа аргумента, [h/l/L] – Изменяет принимаемое по
умолчанию значение типа аргумента
 h = short int
 l = long int (если символ типа определяет преобразование в целый тип)
 l = double (если символ типа определяет преобразование в тип с плавающей
точкой)
 L = long double (допустимо только для преобразования в тип с плавающей
точкой)
o - type_character - символ типа
Спецификация преобразования управляет преобразованием следующего поля ввода. нормально результат
помещается в переменную, которая указывается соответствующим аргументом. Если, однако, с помощью
символа * указано подавление присваивания, то это поле ввода просто пропускается и никакого
присваивания не производится. Поле ввода определяется как строка символов, которые отличны от
символов простых промежутков; оно продолжается либо до следующего символа пустого промежутка, либо
пока не будет исчерпана ширина поля, если она указана. Отсюда следует, что при поиске нужного ей вво да,
функция scanf будет пересекать границы строк, поскольку символ новой строки входит в число пустых
промежутков.
Символ преобразования определяет интерпретацию поля ввода; согласно требованиям основанной на
вызове по значению семантики языка "с" соответствующий аргумент должен быть указателем. Допускаются
следующие символы преобразования:
22 d - на вводе ожидается десятичное целое; соответствующий аргумент должен быть указателем на
целое.
23 - На вводе ожидается восьмеричное целое (с лидирующим нулем или без него); соответствующий
аргумент должен быть указателем на целое.
24 x - На вводе ожидается шестнадцатеричное целое (с лидирующими 0X или без них);
соответствующий аргумент должен быть указателем на целое.
25 h - На вводе ожидается целое типа short; соответсвующий аргумент должен быть указателем на
целое типа short.
26 c - Ожидается отдельный символ; соответствующий аргумент должен быть указателем на символы;
следующий вводимый символ помещается в указанное место. Обычный пропуск символов пустых
промежутков в этом случае подавляется; для чтения следующего символа, который не является
символом пустого промежутка, пользуйтесь спецификацией преобразования %1s.
27 s - Ожидается символьная строка; соответствующий аргумент должен быть указателем символов,
который указывает на массив символов, который достаточно велик для принятия строки и
добавляемого в конце символа \0.
28 f - Ожидается число с плавающей точкой; соответствующий аргумент должен быть указателем на
переменную типа float.
29 е - символ преобразования E является синонимом для f. Формат ввода переменной типа float
включает необязательный знак, строку цифр, возможно содержащую десятичную точку и нео-
бязательное поле экспоненты, состоящее из буквы e, за которой следует целое, возможно имеющее
знак.
Перед символами преобразования 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 в случае ошибки.

Оператор возврата – return


Если тип type возвращаемой функции не void, тело функции должно содержать по крайней мере
один оператор return:
return возвращаемое-выражение;
где возвращаемое-выражение должно быть типа type или типа, который преобразуется в type
присваиванием. Значение возвращаемое-выражение - это значение, которое возвращает функция. Это
значение rvalue, а не lvalue:
t = func(arg);
func(arg) = t; // неверно в Си; верно в C++, если функция
// возвращает ссылку.
(func(arg))++; // неверно в Си; верно в C++, если функция
// возвращает ссылку.
При достижении оператора return функция завершается; если return не встречен, выполнение
заканчивается при достижении последней тела функции.
Если возвращаемый тип - void, оператор return может быть записан

...
return;

Ход работы
30 Ознакомиться с необходимым теоретическим материалом.
31 Запустить Dev C++ Builder.
32 Выбрать команду File->Close all для закрытия проекта по умолчанию.
33 Выбрать команду File->Create->Project… В появившемся диалоговом окне выбрать на вкладке
Basic.
34 Также выбрать C-project (не С++!!!); Console Application и изменить имя проекта таким образом,
чтобы он не содержал русских символов (только латинские и цифры) (глюк среды).
35 В появившемся окне кода проконтролировать наличие тела основной функции.
36 При желании использовать прекомпиляцию файлов заголовков по команде Project->Options…
вкладка Compiler проверить установку параметра Generate Debug Information из набора Linker – он
должен быт включен (Yes) для включения возможности отладки программы встроенным
отладчиком.
37 Выбрать команду File->Save all… и сохранить проект в своей рабочей папке в каталоге С:\Work. Не
пытаться сохранять в папке по умолчанию для избежания нарушения прав доступа! Попытка
сохранения проекта в папках с наличием символов не английского алфавита приведет к
невозможности сборки исполняемого файла (глюк среды).
38 В соответствии с вариантом задания составить и отладить программу.
39 Оформить отчет.

Задание
Составить программу вычисления среднего значения из 10 чисел. Вывести исходные данные и результат с
заданной точностью в виде:
Aishod[arg] = znach;

Aishod[arg] = znach;
Rezultat = rez
Где arg – номер числа (целое); znach – его значение (вещественное); rez – результат вычисления
(вещественное).

Варианты задания
Вариант задания рассчитывается по номеру студента в журнале преподавателя.
Вариант Длина rez Точность rez Вариант Длина rez Точность rez
(поле [width]) (поле [.prec]) (поле [width]) (поле [.prec])
1 8 5 15 10 3
2 7 4 16 10 4
3 7 3 17 10 5
4 7 2 18 10 6
5 7 1 19 10 7
6 8 4 20 11 7
7 8 3 21 11 6
8 8 2 22 11 5
9 8 1 23 11 4
10 9 7 24 11 3
11 9 6 25 11 2
12 9 5 26 11 1
13 9 4 27 12 5
14 9 3 28 12 7

Содержание отчета
Отчет должен содержать следующие пункты:
40 Титульный лист с темой работы, номером варианта.
41 Цель работы.
42 Задание по варианту.
43 Блок-схема алгоритма программы.
44 Текст программы с комментариями.
45 Результаты работы программы (контрольный пример).
46 Выводы, отражающие трудности и результаты, достигнутые в ходе работы над программой и
алгоритмом, а также возможный анализ путей альтернативного выполнения поставленной задачи.

Литература
Турбо С++. Начальное руководство
Borland C++. Руководство программиста
Керниган Б.В. , Ричи Д.М. Язык С.
Марченко А.Л. C++. Бархатный путь
Бьярн Страустрап Введение в язык Си++
Бьярн Страустрап Справочное руководство по Си++
Borland C++ Builder

Вам также может понравиться