- •Программирование на языке c
- •Ознакомление со средой разработки. Консольная программа на языке c
- •Основные теоретические сведения
- •Пример простейшей программы
- •Комментарии
- •Типы и описания
- •Основные типы
- •Производные Типы
- •Выражения и операторы
- •Выражения
- •Стандартный ввод и вывод Функции getchar и putchar
- •Форматный вывод - функция printf
- •Форматный ввод - функция scanf
- •Оператор возврата – return
- •Оператор условия - if
- •Операторы цикла Оператор цикла с предусловием - while
- •Оператор цикла с постусловием – do…while
- •Оператор цикла - for
- •Оператор прерывания выполнения операторов - break
- •Оператор продолжения выполнения – continue
- •Ход работы
- •Задание
- •Варианты задания
- •Содержание отчета
- •Литература
Стандартный ввод и вывод Функции 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 для указания того, как функция должна преобразовать, сформатировать и вывести свои аргументы.
Аргументов не должно быть меньше спецификаторов формата. В противном случае результаты непредсказуемы и, возможно, катастрофические. Лишние аргументы (сверх количества, требуемого строкой формата) просто игнорируются.
Строка формата - символьная строка, содержащая объекты двух типов: основные символы и спецификаторы формата.
Основные символы просто копируются в выходной поток без изменений.
Спецификаторы формата вызывают применение определяемого ими форматирования к значениям аргументов перед выводом их в поток.
Спецификаторы формата функций семейства ...printf имеют следующую форму:
% [flags] [width] [.prec] [F|N|h|l|L] type
Каждый спецификатор формата начинается с символа процента (%). После % следуют, в указанном порядке:
необязательная последовательность символов-флагов, [flags] - Выравнивание при выводе, отображение знака числа, десятичной точки, незначащих нулей, восьмеричные и шестнадцатеричные префиксы
- Результат выравнивается влево и дополняется пробелами справа. Если не задан, результат выравнивается вправо и дополняется слева пробелами или нулями.
+ Результат преобразования с учетом знака всегда начинается со знака плюс (+) или минус (-).
Пробел Если значение неотрицательно, вывод начинается с пробела вместо плюса; отрицательные значения начинаются с минуса. Плюс (+) имеет приоритет над пробелом ( ), если заданы оба.
# Определяет, что arg преобразуется с помощью "альтернативной формы". Смотри следующую таблицу.
Символ
Воздействие # на arg
c,s,d,i,u
Не влияет.
o
В начало ненулевого arg добавляется 0.
x или X
В начало arg добавляется 0х (или 0Х)
e,E или f
Результат всегда содержит десятичную точку, даже если после нее нет цифр. Обычно десятичная точка появляется, только если после нее есть цифры.
g или G
То же, что е и Е; кроме того, незначащие нули не удаляются.
необязательный спецификатор ширины, [width] - Минимальное количество символов для печати, дополнение пробелами или нулями. Ширина задается одним из двух способов: непосредственно - строкой десятичных цифр, или косвенно - звездочкой (*). Если вы используете звездочку, минимальная ширина поля вывода определяется значением очередного аргумента (который должен иметь тип int). Ни при каких обстоятельствах спецификатор ширины, его отсутствие или неверное значение не будет вызывать усечения выводимого поля. Если результат преобразования оказывается шире установленного спецификатором, поле вывода просто расширяется, чтобы поместить результат преобразования.
n По крайней мере n символов будут напечатаны. Если выводимое значение содержит менее n символов, поле вывода дополняется пробелами (справа - если указан символ-флаг "минус"(-), слева - в остальных случаях).
0n По крайней мере n символов будут напечатаны. Если выводимое значение содержит менее n символов, поле вывода дополняется нулями слева.
* Значение спецификатора ширины содержится в списке аргументов и предшествует форматируемому аргументу.
необязательный спецификатор точности, [.prec] - Максимальное количество символов для печати; для целых чисел - минимальное количество цифр для печати. Спецификатор точности всегда начинается с точки точности (.), которая отделяет его от предшествующего спецификатора ширины. Как и ширина, точность задается либо непосредственно - строкой десятичных цифр, либо косвенно - звездочкой (*). Если вы используете звездочку, точность поля вывода определяется значением очередного аргумента (который интерпретируется как int). Если вы используете звездочки для ширины, точности, или для того и другого, аргумент ширины должен соответствовать текущему спецификатору, за ним должен следовать аргумент точности, а затем - аргумент с данными, которые должны быть преобразованы.
(не задан) Точность устанавливается по умолчанию: 1 - для типов d, i, o, u, x, X; 6 - для типов e, E, f; все значащие цифры - для типов g, G; выводятся все символы до первого нуль-символа - для типа s; не влияет - на тип с.
.0 Для типов d,i,o,u,x точность устанавливается по умолчанию; для типов e,E,f - не выводится десятичная точка.
.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 символов.
* Значение спецификатора точности содержится в списке аргументов и предшествует форматируемому аргументу.
!!! Если явно задана нулевая точность, И спецификатор формата для данного поля относится к целочисленным (т.е., d,i,o,u,x), И значение, которое должно быть выведено, равно 0, - ни одной цифры не будет выведено в это поле (т.е. поле будет заполнено пробелами).
необязательный модификатор длины аргумента, [F|N|h|l|L] - Изменяет принимаемое по умолчанию значение длины аргумента влияют на то, как функции семейства ...printf интерпретируют тип данных соответствующего аргумента arg. F и N применяются только к аргументам, которые являются указателями (%p, %s и %n). h, l, и L применяются к числовым аргументам (целым и с плавающей точкой).:
N = near pointer. Изменяют интерпретацию arg. Обычно длина arg для преобразований %p, %s или %n соответствует принимаемой по умолчанию для указателей в используемой модели памяти. N требует: "Интерпретировать arg как ближний указатель".
F = far pointer. изменяют интерпретацию arg. Обычно длина arg для преобразований %p, %s или %n соответствует принимаемой по умолчанию для указателей в используемой модели памяти. F требует: "Интерпретировать arg как дальний указатель".
h = short int. Замещает установленную по умолчанию длину числовых аргументов: применяется только к целым типам, не влияют на символьные типы (c,s) или на указатели (p,n).
l = long. Замещает установленную по умолчанию длину числовых аргументов: l применяется к целым типам (d,i,o,u,x,X) и типам с плавающей точкой (e,E,f,g и G), не влияют на символьные типы (c,s) или на указатели (p,n).
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.
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 в случае ошибки.