Нижегородский государственный университет им. Н.И.Лобачевского
Опубликован: 25.11.2008 | Доступ: свободный | Студентов: 9592 / 1296 | Оценка: 4.06 / 3.66 | Длительность: 21:16:00
Лекция 4:

Системные данные числового типа

< Лекция 3 || Лекция 4: 12345 || Лекция 5 >

3.4. Объявление и инициализация числовых переменных

Переменные числового типа, используемые в программе, обязательно должны быть объявлены до их использования в тех или иных исполняемых операторах. В отличие от языка Pascal алгоритмические языки C, C++ позволяют вводить такие описания не только в начале программных единиц (функций), но и по ходу формирования программы:

int main(void)
{ int i,j;
...........
  s=0;
  for(int k=0; k<10; k++)
........................

В приведенном примере переменные i и j объявлены в начале функции, а объявление переменной k встретилось в операторе цикла. По стандарту языка C++ место объявления переменной определяет сферу ее действия. Переменные, описанные в начале функции (такие как i и j в приведенном выше примере), считаются локализованными в данной функции и могут быть использованы в любой части тела этой функции. Повторное объявление переменных с такими же именами считается ошибкой (дублирование имен переменных). В отличие от этого действие переменных, объявленных в некотором внутреннем блоке функции (в нашем примере переменная k объявлены в цикле for ), распространяется только на время работы этого блока. Т.е после выхода из цикла память, выделенная под переменную k, возвращается системе, и без повторного переобъявления этой переменной пользоваться уже нельзя. Следует отметить, что это положение стандарта языка C++ в системе BC 3.1 реализовано не так. Повторное объявление такой переменной в следующем внутреннем блоке в системе BC 3.1 приводит к сообщению об ошибке, т.к. при выходе из цикла переменная k продолжает свою жизнь. В средах визуального программирования Borland C++ Builder этот пассаж исправлен.

Объявлению любой переменной предшествует служебное слово, определяющее диапазон допустимых значений - тип переменной. Имена базовых типов числовых данных и соответствующие им характеристики, приведены в табл. 3.1 (BC 3.1) и 3.2 (BCB). Для вещественных чисел указаны минимальные по модулю значения.

Таблица 3.1.
Тип Длина Минимальное значение Максимальное значение
char, signed char 1 байт -128 127
unsigned char 1 байт 0 255
short int, short 2 байта -32768 32767
unsigned short 2 байта 0 65535
int, signed 2 байта -32768 32767
unsigned int, unsigned 2 байта 0 65535
long, long int 4 байта -2147483648 2147483647
unsigned long 4 байта 0 4294967265
float 4 байта 3.4*e-38 3.4*e38
double 8 байт 1.7e-308 1.7e308
long double 10 байт 3.4e-4932 1.1e4932
Таблица 3.2.
Тип Длина Минимальное значение Максимальное значение
char, __int8 1 байт -128 127
unsigned char 1 байт 0 255
short int, short, __int16 2 байта -32768 32767
unsigned short 2 байта 0 65535
int, signed, __int32 4 байта -2147483648 2147483647
unsigned int, unsigned 4 байта 0 4294967265
long, long int 4 байта -2147483648 2147483647
unsigned long 4 байта 0 4294967265
int64, __int64 8 байт -4611686018427387904 4611686018427387903
__uint64 8 байт 0 9223372036854775807
float 4 байта 3.4*e-38 3.4*e38
double 8 байт 1.7e-308 1.7e308
long double 10 байт 3.4e-4932 1.1e4932

Объявление переменной можно совместить с присвоением ей начального значения ( инициализацией ):

int x=18,y=-5;
  float a=5F;

В отличие от языка Pascal инициализация локальных переменных в функциях на языках C, C++ происходит при каждом вызове функции.

3.5. Ввод числовых данных по запросу программы

3.5.1. Потоковый ввод данных числового типа

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

cin >> d;
...........
  cin >> x1 >> x2 >> x3;

Первая строка соответствует запросу на ввод значения единственной переменной d. Следующая строка программы представляет запрос на ввод трех числовых значений, первое из которых будет присвоено переменной x1, второе значение предназначается для переменной x2, третье значение - для переменной x3. В ответ на запрос программы пользователь должен набрать на клавиатуре затребованные числа, разделяя их, по крайней мере, одним пробелом. Набор строки завершается нажатием клавиши Enter. Количество числовых значений, набираемых пользователем в пределах строки, может оказаться как меньше, так и больше, чем требуется программе. В первом случае продолжение программы задержится до тех пор, пока пользователь не введет дополнительные строки с недостающими значениями. Если пользователь наберет слишком много значений в вводимой строке, то лишние числовые данные сохранятся в буфере ввода и будут переданы программе при выполнении следующего оператора cin.

Тип набираемого числового значения и его величина должны соответствовать типу переменной, в которую это значение должно быть введено. Забота об этом целиком возлагается на пользователя.

Для обеспечения потокового ввода к программе следует подключить заголовочный файл iostream.h:

#include <iostream.h>
  int main()
{ int i;
  float f;
  double d;
..........
  cin >> i >> f >> d;

В переменные типа char или unsigned char из потока числовые значения ввести невозможно, т.к. они в данном случае воспринимаются системой не как числовые данные, а как символьные. В такие переменные попадет только первый символ набранного значения.

3.5.2. Форматный ввод

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

#include <stdio.h>
  int main()
{ int i;
  float f;
  double d;
..........
  scanf("%d %f %lf",&i,&f,&d);

Строка вводимых данных поступает со стандартного устройства ввода ( stdin ), которым по умолчанию считается клавиатура. Завершение набора строки ввода - нажатие клавиши Enter.

Первый аргумент функции scanf представляет форматную строку, управляющую процессом преобразования числовых данных, набранных пользователем в строке ввода, в машинный формат, соответствующий типам переменных, адреса которых указаны вслед за форматной строкой. Числовые значения в строке ввода рекомендуется разделять одним или несколькими пробелами.

В приведенном примере переменной i (в списке ввода указан ее адрес - &i ), объявленной с помощью спецификатора типа int, соответствует форматный указатель %d. Это означает, что первым числовым значением в строке ввода может быть только целое десятичное число со знаком ( d - от decimal, десятичный). Вещественной переменной f типа float в форматной строке соответствует указатель %f. Это означает, что второе числовое значение в строке ввода должно принадлежать диапазону, предусмотренному для коротких вещественных данных. Для переменной d типа double использован форматный указатель %lf ( l - от long ).

Как правило, количество форматных указателей, перечисленных в первом аргументе функции scanf, должно совпадать с количеством адресов переменных, следующих за форматной строкой. Исключение составляет случай, когда форматный указатель предписывает программе пропустить очередное значение из введенной строки. В этом случае количество адресов в списке ввода уменьшается соответствующим образом. Например:

scanf("%d %*l %lf",&i,&d);

При выполнении такого оператора ввода программа проигнорирует второе числовое значение, набранное пользователем. Конечно, при ручном наборе вводимых значений, нелепо заставлять пользователя набирать данные, которые программе не понадобятся. Но такая возможность может оказаться полезной, когда строка ввода поступает не с клавиатуры, а из других источников (считана с диска, сформирована другой программой в оперативной памяти).

Вообще говоря, функция scanf возвращает числовое значение, равное количеству правильно обработанных полей из строки ввода. Это полезно помнить при организации проверки правильности ввода, т.к. сообщения об ошибках ввода функция scanf не выдает, но после первой же ошибки прерывает свою работу.

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

%[*][ширина][{l|h|L}]{d|i|u|o|x|X|f|e|E|g|G}

Квадратные скобки здесь означают, что соответствующий элемент форматного указателя может отсутствовать. В фигурных скобках указаны символы, один из которых может быть выбран. Обязательными элементами любого форматного указателя являются начальный символ % и последний символ, определяющий тип вводимого значения.

Символ * после начального символа является указанием о пропуске соответствующего значения из строки ввода. Необязательное, и, как правило, не используемое при вводе, поле ширина задает количество символов во вводимом значении. Дополнительные признаки l, h и L уточняют длину машинного формата соответствующей переменной ( l, L - long; h - short ). Значение последнего обязательного символа форматного указателя расшифровано в табл. 3.3.

Таблица 3.3.
Символ формата Допустимое значение в строке ввода
d целое десятичное число со знаком
i целое число
u целое число без знака
o целое восьмеричное число без знака
x,X целое шестнадцатеричное число без знака
f вещественное число
e,E вещественное число
g,G вещественное число

Форматный ввод также как и потоковый не позволяет вводить числовые значения в переменные типа char. Дело в том, что минимальная длина числового значения вводимого с помощью функции scanf - 2 байта. И значение введенного старшего байта затирает в памяти еще один байт вслед за переменной типа char. Заметить такую ошибку удается не каждому, но на работу программы такой ввод может повлиять довольно серьезно. Поэтому возьмите за правило - в однобайтовые переменные типа char числовую информацию вводить нельзя.

В системе BC 3.1 для ввода значений переменных типа short или int можно использовать один из следующих форматных указателей - %d, %i, %u, %o, %x или %X. Ввод целочисленных данных типа long требует одного из следующих форматных указателей - %ld, %li, %lu, %lo, %lx или %lX.

В системе BCB для двухбайтовых числовых переменных следует использовать форматные указатели в сочетании с символом h - %hd, %hi, %hu, %ho, %hx или %hX. Форматные указатели %d и %ld здесь эквивалентны.

Такое обилие целочисленных форматных указателей объясняется тем, что при наборе целых чисел можно добавлять префиксы - 0x или 0X для шестнадцатеричных значений, лидирующий 0 для восьмеричных значений. При использовании форматного указателя %d вводимые данные не могут содержать указанные префиксы, все значения интерпретируются только как целые десятичные числа со знаком. При использовании форматного указателя %i ( i - от integer ) можно вводить числа в любой нотации, но обязательно с соответствующим префиксом. Форматные указатели %o, %x или %X позволяют вводить восьмеричные или шестнадцатеричные числа как с соответствующими префиксами, так и без них.

Ввод коротких вещественных данных типа float может быть осуществлен с использованием любого из следующих форматных указателей - %f, %e, %E, %g или %G. На вводе все они эквивалентны, их специфика проявляется только при выводе числовых результатов. Для восьмибайтовых данных типа double к каждому из этих указателей добавляется буква l - %lf, %le, %lE, %lg или %lG. Десятибайтовым числовым данным типа long double соответствуют форматные указатели %Lf, %Le, %LE, %Lg или %LG.

< Лекция 3 || Лекция 4: 12345 || Лекция 5 >
Alexey Ku
Alexey Ku

Попробуйте часть кода до слова main заменить на 

#include "stdafx.h" //1

#include <iostream> //2
#include <conio.h>

using namespace std; //3

Александр Талеев
Александр Талеев

#include <iostream.h>
#include <conio.h>
int main(void)
{
int a,b,max;
cout << "a=5";
cin >> a;
cout <<"b=3";
cin >> b;
if(a>b) max=a;
else max=b;
cout <<" max="<<max;
getch();
return 0;
}

при запуске в visual express выдает ошибки 

Ошибка    1    error C1083: Не удается открыть файл включение: iostream.h: No such file or directory    c:\users\саня\documents\visual studio 2012\projects\проект3\проект3\исходный код.cpp    1    1    Проект3

    2    IntelliSense: не удается открыть источник файл "iostream.h"    c:\Users\Саня\Documents\Visual Studio 2012\Projects\Проект3\Проект3\Исходный код.cpp    1    1    Проект3

    3    IntelliSense: идентификатор "cout" не определен    c:\Users\Саня\Documents\Visual Studio 2012\Projects\Проект3\Проект3\Исходный код.cpp    6    1    Проект3

    4    IntelliSense: идентификатор "cin" не определен    c:\Users\Саня\Documents\Visual Studio 2012\Projects\Проект3\Проект3\Исходный код.cpp    7    1    Проект3

при создании файла я выбрал пустой проект. Может нужно было выбрать консольное приложение?