Форматированный ввод данных




Функция scanf() (прототип содержится в файле stdio.h) обеспечивает форматированный ввод. Ее можно записать в следующем формальном виде:

scanf("управляющая строка", аргумент_1, аргумент_2,...);

Аргументы scanf() должны быть указателями на соответствующие значения. Для этого перед именем переменной записывается символ &. Назначение указателей будет рассмотрено далее.

Управляющая строка содержит спецификации преобразования и используется для установления количества и типов аргументов. В нее могут включаться:

  • пробелы, символы табуляции и перехода на новую строку (все они игнорируются);
  • спецификации преобразования, состоящие из знака %, возможно, символа * (запрещение присваивания), возможно, числа, задающего максимальный размер поля, и самого символа преобразования;
  • обычные символы, кроме % (считается, что они должны совпадать с очередными неизвестными символами во входном потоке).

Рассмотрим символы преобразования функции scanf() (указываются после символа %):

с - на входе ожидается появление одиночного символа;
d или i - на входе ожидается десятичное целое число и аргумент является указателем на переменную типа int;
D или l - на входе ожидается десятичное целое число и аргумент является указателем на переменную типа long;
е или Е - на входе ожидается вещественное число с плавающей точкой;
f - на входе ожидается вещественное число с плавающей точкой;
g или G - на входе ожидается вещественное число с плавающей точкой;
о - на входе ожидается восьмеричное целое число и аргумент является указателем на переменную типа int;
О - на входе ожидается восьмеричное целое число и аргумент является указателем на переменную типа long;
s - на входе ожидается появление строки символов;
х - на входе ожидается шестнадцатеричное целое число и аргумент является указателем на переменную типа int;
Х - на входе ожидается шестнадцатеричное целое число и аргумент является указателем на переменную типа long;
р - на входе ожидается появление указателя в виде шестнадцатеричного числа;
n - применяется в операциях форматирования. Аргумент, соответствующий этому символу спецификации, должен быть указателем на целое. В него возвращается номер позиции (после ввода), в которой записана спецификация %n;
u - на входе ожидается беззнаковое целое число и аргумент является указателем на переменную типа unsigned int;
U - на входе ожидается беззнаковое целое число и аргумент является указателем на переменную типа unsigned long;
[ ] - сканирует входную строку для получения символов.

Перед некоторыми символами преобразования могут записываться следующие модификаторы:

F - изменяет указатель, заданный по умолчанию, на указатель типа far;
N - изменяет указатель, заданный по умолчанию, на указатель типа near;
h - преобразует аргумент к типу short int (может записываться перед символами d, i, о, u, х);
l - преобразует аргумент к типу long int (может записываться перед символами d, i, o, u, x);
L - преобразует аргумент к типу long double (может записываться перед символами е, f, g).

Ввести целое число (int a;), символ (char b;) и вещественное число (float t;) можно так:

scanf("%d", &a);

scanf("%c", &b);

scanf("%d%c%f",&a, &b, &t);

 

РАЗДЕЛ 2. ОПЕРАЦИИ И ОПЕРАТОРЫ

Операции языка Си

Любое выражение языка состоит из операндов (переменных, констант и др.), соединенных знаками операций. Знак операции - это символ или группа символов, которые сообщают компилятору о необходимости выполнения определенных арифметических, логических или других действий.

Операции выполняются в строгой последовательности. Величина, определяющая преимущественное право на выполнение той или иной операции, называется приоритетом. В табл. 2 перечислены различные операции языка Си. Их приоритеты для каждой группы одинаковы (группы выделены цветом). Чем большим преимуществом пользуется соответствующая группа операций, тем выше она расположена в таблице. Порядок выполнения операций может регулироваться с помощью круглых скобок.

Таблица 2

Знак операции Назначение операции
() Вызов функции
[ ] Выделение элемента массива
. Выделение элемента записи
-> Выделение элемента записи
! Логическое отрицание
~ Поразрядное отрицание
- Изменение знака
++ Увеличение на единицу
-- Уменьшение на единицу
& Взятие адреса
* Обращение по адресу
(тип) Преобразование типа (т.е. (float) a)
sizeof() Определение размера в байтах
* Умножение
/ Деление
% Определение остатка от деления
+ Сложение
- Вычитание
<< Сдвиг влево
>> Сдвиг вправо
< Меньше, чем
<= Меньше или равно
> Больше, чем
>= Больше или равно
= = Равно
!= Не равно
& Поразрядное логическое "И"
^ Поразрядное исключающее "ИЛИ"
| Поразрядное логическое "ИЛИ"
&& Логическое "И"
|| Логическое "ИЛИ"
?: Условная (тернарная) операция
= Присваивание
+=, - =, *=, /=, %=, <<=, >>=, &=, |=, ^= Составные операции присваивания (например, а *= b (т.е. a = a * b) и т.д.)
, Операция запятая

Для исключения путаницы в понятиях "операция" и "оператор", отметим, что оператор - это наименьшая исполняемая единица программы. Различают операторы выражения, действие которых состоит в вычислении заданных выражений (например: a = sin(b)+c; j++;), операторы объявления, составные операторы, пустые операторы, операторы метки, цикла и т.д. Для обозначения конца оператора в языке Си используется точка с запятой. Что касается составного оператора (или блока), представляющего собой набор логически связанных операторов, помещенных между открывающей ({) и закрывающей (}) фигурными скобками ("операторными скобками"), то за ним точка с запятой не ставится. Отметим, что блок отличается от составного оператора наличием определений в теле блока.

Охарактеризуем основные операции языка Си. Сначала рассмотрим одну из них - операцию присваивания (=). Выражение вида

х = у;

присваивает переменной х значение переменной у. Операцию "=" разрешается использовать многократно в одном выражении, например:

x = y = z = 100;

Различают унарные и бинарные операции. У первых из них один операнд, а у вторых - два. Начнем их рассмотрение с операций, отнесенных к первой из следующих традиционных групп:

  1. Арифметические операции.
  2. Логические операции и операции отношения.
  3. Операции с битами.

Арифметические операции задаются следующими символами (табл. 2): +, -, *, /, %. Последнюю из них нельзя применять к переменным вещественного типа. Например:

a = b + c;

x = y - z;

r = t * v;

s = k / l;

p = q % w;

Логические операции отношения задаются следующими символами (см. табл. 2): && ("И"), || ("ИЛИ"),! ("НЕ"), >, >=, <, <=, = = (равно),!= (не равно). Традиционно эти операции должны давать одно из двух значений: истину или ложь. В языке Си принято следующее правило: истина - это любое ненулевое значение; ложь - это нулевое значение. Выражения, использующие логические операции и операции отношения, возвращают 0 для ложного значения и 1 для истинного. Ниже приводится таблица истинности для логических операций.

Таблица 3

x y x&&y x||y !x
         
         
         
         

Битовые операции можно применять к переменным, имеющим типы int, char, а также их вариантам (например, long int). Их нельзя применять к переменным типов float, double, void (или более сложных типов). Эти операции задаются следующими символами: ~ (поразрядное отрицание), << (сдвиг влево), >> (сдвиг вправо), & (поразрядное "И"), ^ (поразрядное исключающее "ИЛИ"), | (поразрядное "ИЛИ").

Примеры: если a = 0000 1111 и b = 1000 1000, то

~a = 1111 0000,

a << 1 = 0001 1110,

a >> 1 = 0000 0111,

a & b = 0000 1000,

a ^ b = 1000 0111,

a | b = 1000 1111.

В языке предусмотрены две нетрадиционные операции инкремента (++) и декремента (--). Они предназначены для увеличения и уменьшения на единицу значения операнда. Операции ++ и -- можно записывать как перед операндом, так и после него. В первом случае (++n или --n) значение операнда (n) изменяется перед его использованием в соответствующем выражении, а во втором (n++ или n--) - после его использования. Рассмотрим две следующие строки программы:

a = b + c++;

a1 = b1 + ++c1;

Предположим, что b = b1 = 2, c = c1 = 4. Тогда после выполнения операций: a = 6, b = 2, c = 5, a1 = 7, b1 = 2, c1 = 5.

Широкое распространение находят также выражения с еще одной нетрадиционной тернарной или условной операцией?:. В формуле

y = x? a: b;

y = a, если x не равно нулю (т.е. истинно), и y = b, если х равно нулю (ложно). Следующее выражение

y = (a>b)? a: b;

позволяет присвоить переменной у значение большей переменной (а или b), т.е. y = max(a, b).

Еще одним отличием языка является то, что выражение вида а = а + 5; можно записать в другой форме: a += 5;. Вместо знака + можно использовать и символы других бинарных операций (см. табл. 2).

Другие операции из табл. 2 будут описаны в последующих параграфах.

 

 

Преобразование типов

Если в выражении появляются операнды различных типов, то они преобразуются к некоторому общему типу, при этом к каждому арифметическому операнду применяется такая последовательность правил:

  1. Если один из операндов в выражении имеет тип long double, то остальные тоже преобразуются к типу long double.
  2. В противном случае, если один из операндов в выражении имеет тип double, то остальные тоже преобразуются к типу double.
  3. В противном случае, если один из операндов в выражении имеет тип float, то остальные тоже преобразуются к типу float.
  4. В противном случае, если один из операндов в выражении имеет тип unsigned long, то остальные тоже преобразуются к типу unsigned long.
  5. В противном случае, если один из операндов в выражении имеет тип long, то остальные тоже преобразуются к типу long.
  6. В противном случае, если один из операндов в выражении имеет тип unsigned, то остальные тоже преобразуются. к типу unsigned.
  7. В противном случае все операнды преобразуются к типу int. При этом тип char преобразуется в int со знаком; тип unsigned char в int, у которого старший байт всегда нулевой; тип signed char в int, у которого в знаковый разряд передается знак из сhar; тип short в int (знаковый или беззнаковый).

Предположим, что вычислено значение некоторого выражения в правой части оператора присваивания. В левой части оператора присваивания записана некоторая переменная, причем ее тип отличается от типа результата в правой части. Здесь правила преобразования очень простые: значение справа от оператора присваивания преобразуется к типу переменной слева от оператора присваивания. Если размер результата в правой части больше размера операнда в левой части, то старшая часть этого результата будет потеряна.

В языке Си можно явно указать тип любого выражения. Для этого используется операция преобразования ("приведения") типа. Она применяется следующим образом:

(тип) выражение

(здесь можно указать любой допустимый в языке Си тип).

Рассмотрим пример:

int a = 30000;

float b;

........

b = (float) a * 12;

(переменная a целого типа явно преобразована к типу float; если этого не сделать, то результат будет потерян, т.к. a * 12 > 32767).

Преобразование типа также может использоваться для преобразования типов аргументов при вызове функций.

 



Поделиться:




Поиск по сайту

©2015-2024 poisk-ru.ru
Все права принадлежать их авторам. Данный сайт не претендует на авторства, а предоставляет бесплатное использование.
Дата создания страницы: 2022-10-12 Нарушение авторских прав и Нарушение персональных данных


Поиск по сайту: