Переменные. Основные типы данных

Любая программа, суть которой не есть вывод на экран некоторой текстовой информации, содержит описание переменных. Переменная - это пара “имя” - “значение”. Имени соответствует адрес участка памяти, выделенной переменной, а значением является содержимое этого участка. Именем переменной служит идентификатор. В С++ идентификатор - это последовательность из букв латинского алфавита, десятичных цифр и символов подчеркивания, начинающаяся не с цифры. Прописные и строчные буквы различаются. Примеры идентификаторов:

i, i2, i_2, stroka, STROKA, F_I_O .

На длину различаемой части идентификатора конкретные реализации компилятора накладывают свои собственные ограничения. Например, компилятор фирмы Borland различают не более 32-х первых символов любого идентификатора.

Каждая переменная и каждое выражение в программе имеет тип, определяющий операции, которые могут над ними производиться. Все типы языка С++ делят на основные и производные. Переменные типизируются с помощью описаний. Для описания переменных основных типов используют ключевые слова, содержащиеся в таблице 2.

Описание переменных заданного типа имеет следующий формат:

тип имя1 [иницал._выражение1], имя2 [иницал._выражение2],…; где

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

Синтаксис инициализатора переменной:

= инициал._выражение

либо

(инициал._выражение).

Таблица 2. Основные типы данных

Тип данных Диапозон значений
char (символьный) -128...127
short (короткий целый) -32768...32767
int (целый) -32768...32767
long (длиный целый)

-2147483648…2147483647

unsigned char (беззнаковый символьный)

0...255

unsigned int (беззнаковый целый)

0…65535

unsigned long (беззнаковый длинный целый)

0…4294967295

float (вещественный)

3.4Е-38…3.4Е+38

double (вещественный с удвоенной точностью)

1.7Е-308…1.7Е+308

long double (длинный вещественный с удвоенной точностью)

3.4Е-4932…3.4Е+4932

Приведем несколько примеров.

int i,j,k,n=10;

Определены целые переменные i,j,k,n и только n инициализирована значением 10.

char simbol1= ‘\n’;

Определена символьная переменная simbol1 co значением ‘\n’

double pi=3,1415926535897932385;

Определена вещественная переменная pi с удвоенной точностью co значением 3,1415926535897932385

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

const float pi = 3,14;

const char plus = '+';

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

Кроме типов, приведенных в таблице 2, к основным типам относят логический тип bool, перечислимый тип enum и тип void (отсутствие значения).

Логические переменные (типа bool) могут принимать одно из двух значений: истина (true) или ложь (false). Логические переменные используются для выражения результатов логических операций. Например,

bool b1=a==b; //= означает присваивание, == проверка равенства

Если а и b имеют одинаковые значения, то b1 будет равно true, в противном случае – false. По определению true имеет значение 1 при преобразовании к целому типу, а false ‑ 0. При преобразовании целочисленного значения к логическому типу 0 преобразуется в false, а число, отличное от нуля – в true.

Перечислимый тип, который вводится с помощью служебного слова enum, по существу описывает целые константы (типа int), которым приписаны уникальные и удобные для использования имена. Например,

enum {one=1,two=2,three=3};

Здесь one, two, three – произвольным образом выбранные программистом идентификаторы для обозначения констант 1,2,3. После такого определения в программе наряду, например, с константой 2 можно использовать ее обозначение two. Если в определении перечислимых констант опустить знаки “=” и не указывать числовых значений, то они будут присваиваться идентификаторам по умолчанию следующим образом: самый левый в фигурных скобках идентификатор получит значение 0, а каждый последующий увеличивается на 1. Имена перечислимых констант должны быть уникальными, однако к значениям констант это не относится. Одно значение могут иметь разные константы. Для перечислимых констант можно ввести имя типа, соответствующего приведенному списку констант, например, определение

enum week {sunday, monday, tuesday, wednesday, thursday, friday, saturday};

не только определяет константы Sunday==0, Monday==1,…, но и вводит перечислимый тип с именем week, который может в дальнейшем использоваться в определениях и описаниях других типов.

Тип void можно использовать только для определений некоторых производных типов. Объектов типа void не существует, то есть описание void i; недопустимо.

Из основных типов с помощью операций *, &, [], () и механизмов определения структурированных типов (классов, структур, объединений) можно конструировать множество производных типов. Приведем несколько примеров:

  • int ar [5]; - массив, состоящий из пяти объектов типа int, доступ к которым обеспечивают индексированные переменные ar[0], ar[1], ar[2] ar[3], ar[4];
  • char t[]= “текст”; – массив, состоящий из пяти объектов типа char;
  • void a1 (double); – функция, не возвращающая никакого значения и имеющая аргумент типа double;
  • char *a2; – указатель на объекты типа char (значением указателей являются адреса участков памяти, выделенных для объектов конкретного типа);
  • long a3;
  • long &a4=a3; – инициализированная ссылка на объект типа long ;
  • int *a5[];– массив указателей на объекты типа int;
  • int (*a5)[]; – указатель на массив объектов типа int.

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

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

typedef unsigned char UC;

UC simbol;

Здесь вводится новый тип UC и переменная этого типа simbol, значениями которой являются беззнаковые числа в диапазоне от 0 до 255.

Для определения размера (в байтах) области памяти, выделяемой для переменной определенного типа, в С++ используется операция sizeof. Разрешены два формата операции

sizeof (имя_переменной)

или

sizeof (тип данных).

Например, пусть определена переменная int i. Тогда операция sizeof(i) определит, сколько байт выделено для переменой i.

Соотношение между основными типами можно записать так:

1==sizeof(char) <= sizeof(short) <= sizeof(int) <= sizeof(long) <=sizeof(float) <= sizeof(double)

Каждый, описанный в программе объект (в частности, переменная), имеет следующие основные характеристики:

  • область действия идентификатора – эта та часть программы, в которой идентификатор может быть использован для доступа к связанному с ним объекту (обычно имя переменной действует с места ее определения и до конца блока {}, в котором она была определена);
  • видимость объекта (данное понятие необходимо в связи с возможностью повторных определений идентификатора внутри вложенных блоков);
  • продолжительность существования, которая определяет период, в течение которого идентификаторам в программе соответствуют конкретные объекты в памяти. Определены три вида продолжительности: статическая, локальная и динамическая;
  • класс памяти – определяет размещение объекта в памяти и продолжительность его существования.

Ввод – вывод значений переменных

Значение переменной может быть указано при описании, а может быть введено с клавиатуры. Рассмотрим, как происходит ввод – вывод значений переменных в языке С++.

Для ввода значений переменных с клавиатуры используется выражение

cin >> имя_переменной;

где cin – имя объекта-потока, описание которого содержится в заголовочном файле iosteam.h, операция >> - операция извлечения из потока, заключающаяся в преобразовании символов входного потока в значение типизированного объекта, частным случаем которого является переменная основного типа.

Для вывода значений переменных и констант на экран используется уже знакомый нам оператор

cout << имя_переменной (константы);

Часто для ввода и вывода применяют последовательные операции, которые также называют “цепочками” операций ввода и вывода. Например, для переменной int x=2 результатом выполнения оператора

cout << “\nx*3=”<<x*3<< “, x*4=”<<x*4; // * - операция умножения

будет следующая строка на экране:

x*3=6, x*4=8.

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

Приведем пример использования “цепочек” операций при вводе данных. Для переменных int i, j, k оператор

cin>> i>>j>>k;

обеспечивает ввод последовательности целых значений переменных i, j, k. Элементы этой последовательности во входном потоке должны разделяться обобщенными пробельными символами (пробелами, знаками табуляции, символами перевода строки). Причем исходные данные можно ввести, размещая их либо в одну строку и только после этого нажимая клавишу Enter, либо помещая каждое значение на отдельной строке, то есть нажимая клавишу Enter после каждого введенного значения. Причем в первом случае количество чисел, набранных в строке, может превышать количество операций извлечения >>. При этом “лишние ” (последние) числа игнорируются.

Потоковые объекты cin и cout построены таким образом, что ввод и вывод выполняются по-разному в зависимости от типов правого операнда операций включения << и извлечения >>. При вводе данных, например, операция извлечения >> реализует по сути три операции: для целых чисел, для вещественных чисел и для строк.

При вводе целого значения его можно набирать на клавиатуре в десятичном, восьмеричном (начиная с символа 0) или шестнадцатеричном (начиная с символов 0x) виде, соблюдая ограничения на длину внешнего и внутреннего представления чисел для данного типа данных.

При вводе вещественных чисел допустимы все формы их записи. Например, при вводе значения переменной float pi можно использовать следующие наборы символов 3.141593, 3.141593e0, +3.141593, 0.3141593e+1.

Обычно значение вещественной переменной выводится на экран в форме с фиксированной точкой, однако, если его значащая часть выходит за разрядную сетку, то вывод происходит в форме с плавающей точкой. Например, при вводе с клавиатуры значения 0.00000000000000000000001 на экран будет выдано 1e‑23.

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

int k; float e;

cin >> k>>e;

cout << “k = ” <<k<< “ e= ” <<e;

набрав на клавиатуре

1234.567 89 <Enter>

получим следующие значения переменных:

k= 1234 e=0.567.

Здесь точка является недопустимым символом для переменной k, но корректно воспринята при вводе значения e. Символы 89 из входного потока проигнорированы, так как извлечение данных закончилось при достижении пробела, а операция >> больше не применяется.

Ввод - вывод массив и символьных массивов строк – это различные процедуры. Для операторов

char H1[]= “Это строка”;

int H2[]={1,2,3};

char H3 [255];

int H4 [5];

cout << “\n”<<H1;

cout << “\n”<<H2;

будет выведен текст Это строка и на следующей строке только адрес первого элемента массива, так как имя массива воспринимается как указатель со значением адреса начала массива. Чтобы вывести значения элементов массива, их надо явно обозначить с помощью индексов:

cout << H2[0]<< “   ”<< H2[1]<< “   ”<< H2[2];

Используя операторы

cin >> H3; cout << H3;

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

При попытке ввести значения элементов массива с помощью оператора cin >> H4; получим сообщение об ошибке на этапе компиляции.

Форматирование данных при обменах с потоками ввода-вывода

Данные при обмене с потоками ввода-вывода используют стандартный формат внешнего представления. Например, при выводе чисел каждое из них занимает ровно столько позиций, сколько необходимо для его представления: число 1/3 будет выведено на экран в виде 0.333333. Это не всегда удобно. Форматы представления выводимой информации и правила восприятия данных, вводимых из потока, могут быть изменены с помощью флагов форматирования. Эти флаги унаследованы всеми потоками библиотеки из базового класса ios. Перечислим некоторые флаги, объясняя их действие при значениях, принимаемых этими флагами по умолчанию:

  • left - вывод значения с левым выравниванием;
  • right – вывод значения с правым выравниванием;
  • dec – десятичная система счисления;
  • осt - восьмеричная система счисления;
  • hex – шестнадцатеричная система счисления;
  • showbase – напечатать при выводе признак системы счисления (0x - для шестнадцатеричных, 0 – для восьмеричных);
  • showpoint – при выводе вещественных чисел обязательно печатать точку и следующие за ней нули;
  • fixed – для вещественных чисел использовать представление в формате с фиксированной точкой.

Для изменения этих флагов используют функцию setf следующим образом: cout.setf (setbits, field) или cout.setf (setbits). Функция устанавливает флаги в соответствии со значением параметров. Биты, помещенные в параметре field, сбрасываются, а затем устанавливаются те биты, которые указаны в параметре setbits.

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

  • cout.width (x), где x- целое число, задающее минимальную ширину поля вывода;
  • cout.precision (x), где x – целое число, задающее точку представления вещественных чисел, то есть максимальное количество цифр дробной части при выводе;
  • cout.fill(x), где x определяет символ заполнения поля ввода до минимальной величины, определенной переменной width. По умолчанию fill имеет значение пробела.

Пример 1. Ввести с клавиатуры и вывести на экран два вещественных числа в формате 2 знака поле запятой и заполнить пространство между ними символом # следующим образом:

32.76#############################5.41##############################

#include <iostream.h>

#include <conio.h>

void main()

{

float a,b;

int i;

cout << "\nEnter numbers\n";

cin>>a>>b;

clrscr();                   //функция очистки экрана, описана в заголовочном

                               //файле conio.h

cout.setf(ios::fixed); //вывод вещественных чисел в формате с

                               //фиксированной точкой

cout.setf(ios::left);    //вывод значения с левым выравниванием

cout.width(40);        //установили ширину поля вывода 40 символов

                               //(половина ширины экрана)

cout.precision(2);     // установили число знаков после запятой

                               // при выводе вещественно числа

cout.fill('#');             // заполнитель поля вывода #

cout<<a;

cout.width(40);        // установили ширину поля вывода 40 символов

cout<<b;

getch();

}

Заметим, что если бы мы не использовали в программе функцию cout.setf(ios::fixed), то функция cout.precision(2) определяла бы количество всех разрядов выводимого числа, а не количество разрядов его дробной части. Кроме того, обратим внимание на повторное использование функции cout.width() перед выводом значения переменной b. Оно обязательно, так как по умолчанию ширина поля равна длине принятого представления выводимого значения.

Более простой способ изменения параметров и флагов форматирования обеспечивают манипуляторы - специальные функции, позволяющие программисту изменять состояния и флаги потока. Манипуляторы библиотеки классов ввода-вывода языка С++ делятся на 2 группы: манипуляторы с параметрами и манипуляторы без параметров. Примерами манипуляторов без параметров служат манипуляторы dec, hex, осt, которые при вводе и выводе устанавливают флаг десятичной, шестнадцатеричной, восьмеричной системы счисления соответственно (до следующего явного изменения) и манипулятор endl , который обеспечивает включение в выходной поток символа новой строки. Манипуляторы с параметрами определены в файле iomanip.h. Наиболее используемые манипуляторы:

  • setw (x), где x- целое число, задающее минимальную ширину поля вывода;
  • setfill (x), где x определяет символ заполнения поля ввода до минимальной величины, определенной переменной width;
  • setpresiction (x), где x – целое число, задающее точку представления вещественных чисел, то есть максимальное количество цифр дробной части при выводе.

Пример 2. Ввести с клавиатуры и вывести на экран целое число в десятичном, шестнадцатеричном и восьмеричном виде следующим образом:

$$$$$$$$$$$$$$$$$$$$$$$$$$$11   0xb  013$$$$$$$$$$$$$$$$$$$$$$$$$$$$

#include <iostream.h>

#include <iomanip.h>

#include <conio.h>

void main()

{

int i;

cout << "\nEnter number\n";

cin>>i;

clrscr();

cout.setf(ios::showbase); //выводить признак основания

                                      //системысчисления

cout<<setw (30)<<setfill('$')<<i<<'  '<<hex<<i;

cout<<"  "<<oct<<i<<setw(30)<<'\n';

getch();

}

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

Определенные операции могут в зависимости от их операндов вызывать преобразование значения операнда от одного типа к другому. Например,

char сh= ‘a’;

int k = ch;

символьный тип преобразуется к целому

cout k;

на экран выведется ASCII-код символа ch

Иногда необходимо явным образом преобразовывать типы, например, для вывода на экран ASCII-кода символа ch без использования вспомогательной переменной целого типа будем писать

cout (int) ch;

или

cout int (ch);

Добавить комментарий


Защитный код
Обновить

Мобильные устройства

Технологические системы

Программирование

Реклама

Яндекс.Метрика
© 2011-2016 pc-4you.ru Копирование материалов разрешено только с указанием активной ссылки на первоисточник