§2 Типы данных. Переменные. Поток ввода и операция извлечения. Потоковый объект cin. Указатели

Переменные

Компьютерная память устроена так, что данные разного типа хранятся в ней различным образом. Блок памяти называется байтом (не путать с единицей измерения информации). Все байты пронумерованы, т. е. имеют адреса. Существует множество различных типов данных: целые числа, действительные числа, символы, строки. Каждый из этих типов занимает в памяти различное количество байтов. Отсюда следует, что для каждого типа определен свой диапазон возможных принимаемых значений данных этого типа и возможный набор операций с этими данными. Например, для типа целое число (тип int, занимает в памяти 4 байта) диапазон принимаемых значений от -2147483648 до 2147483647 и могут выполняться с данными этого типа такие операции: +, -, *, /, %, <<, >>. Для действительного типа (тип double, занимает в памяти 8 байтов) диапазон значительно "шире" (до максимального положительного значения 1.797693134862316e+308), но количество операций (из приведенных выше) будет значительно меньше, только: +, -, * и /.
18-1Для записи данных в память и извлечения их из памяти используются переменные. Переменные — это именованная область памяти, к которой можно обращаться из программы. С каждой переменной связан адрес памяти (адрес первого байта с наименьшим значением). Для программиста - это не имеет значения, так как от него скрыта информация в каком адресном пространстве будет работать программа. Для программиста важно - какой тип данных будет связан с именем переменной. Имена переменных в C++ регистрозависимы. Т. е., Name, NAME или name - разные имена. Имя переменной называют идентификатором. Имена имеют не только переменные, но и функции, массивы, классы и другие объекты программы. Существуют ограничения в выборе идентификатора. Так, имя не должно начинаться с цифры или иметь пробелы. Нельзя использовать в качестве имен служебные слова С++. Существует целый ряд соглашений об именах и несколько стилей написания имен.

Определение переменных

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

int a;

Тип int является стандартным типом для целых переменных, так как имеет размер равный машинному слову (4 байта для 32-битной архитектуры). Если нет веских причин для использования иного какого-либо целого типа, то необходимо (для целой переменной) использовать именно этот тип.
Если используется несколько переменных одного типа, то они могут быть перечислены через запятую в одной инструкции:

int a, b, c, other;

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

int a = 10;
int b = a;
int c = 0, d, e, other = 1000;

Если переменная, объявленная в теле главной функции main(), не имеет начального значения, то её значением будет мусор (т. е. неопределенное состояние памяти).

Поток ввода. Потоковый объект cin

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

int var_A;
cin >> var_A;

1
Можно вводить значения нескольких переменных за раз, но тогда, при вводе, в окне терминала, значения переменных должны разделяться пробелами (или иными пробельными символами). Пример ввода нескольких переменных:

int a = 10, b, c;
cin >> a >> b >> c;

Здесь вводятся переменные одного типа, но в потоке cin можно вводить значения переменным разного типа. В этом случае нужно следить за тем, чтобы вводимые значения переменных соответствовали требованиям предъявляемым к литералам данных типов. Если переменная имела уже какое-то значение (a), то оно будет заменено на новое. Данные в поток отправляются нажатием клавиши Enter на клавиатуре. Для потоков ввода также могут быть использованы манипуляторы, например, setw(). Этим мы ограничим количество вводимых символов.
Данные не должны вводиться "в слепую", т. е. для ввода тех или иных данных необходимо приглашение. Такие приглашения называются диалогами с пользователем или дружественными интерфейсами. Для создания диалогов потоки ввода/вывода используются совместно. Приведем пример. Создадим программу приветствия, опрашивающую пользователя и выводящую полученную информацию.
Программа 2.1

//============================================================================
// Name        : lesson-2-1.cpp
//============================================================================
#include <iostream>
#include <string>
using namespace std;

int main() {
	int Y;
	string S;
	cout << "Как тебя зовут?\n";
	cin >> S;
	cout << "Сколько тебе лет?\n";
	cin >> Y;
	cout << "Здравствуй, " << S
	     << "! Тебе всего " << Y
	     << " лет." << endl;
	return 0;
}

Обратите внимание, что поток вывода, например, на стр. 11 не завершается endl. Дело в том, что последующий поток ввода автоматически завершает предыдущий поток с установкой признака завершения строки.
Примечание. В этой программе подразумевается, что имя не будет содержать пробелов. В противном случае, строка должна вводится с помощью функции getline(cin, S), т. к. cin не игнорирует пробелы в строке! Если функция getline() следует за потоком ввода, то необходимо предусмотреть очистку потока ввода от нулевого символа с помощью методов потокового класса cin.ignore() или cin.get().

Указатели

Указатель - это специальный вид переменной, который хранит адрес памяти другого объекта. Указатели могут иметь разные типы (и даже абстрактные), а также вовсе не иметь типа (void). С указателями можно производить различные операции, но перечень таких операций невелик. Чтобы описать переменную-указатель используется операция * или разыменования:

int *p;

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

int a = 10;
int *p = &a;

Операция & называется операцией взятия адреса. После описания указателям присваивается значение также, как и обычным переменным:

int a, *p, *c;
p = &a;
c = p;

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

int a = 10, *p, c;
p = &a;
c = *p + 10;
cout << "a = " << a << endl;
cout << "c = " << c << endl;
cout << "p = " << p << endl;

Обратите внимание, что значение указателя в C++ представлено в виде шестнадцатеричного числа. С помощью указателей можно получать доступ к памяти и использовать динамические переменные, которые создаются на время, для выполнения каких-либо задач, с последующим их уничтожением. Для выделения памяти используется операция new, а для уничтожения delete. Например:

int *p = new int(10);
int *c = new int(40);
*p = *c / 2;
cout << "*c = " << *c << endl;
cout << "*p = " << *p << endl;
delete p, c;

Более подробно работу с указателями мы обсудим позднее.


Comments are closed