Ссылки
Альтернативой указателям являются ссылки.
Ссылка- это переменная, которая является альтернативным именем другой переменной. Ссылка при объявлении должна быть инициализирована и только один раз. После инициализации ее значение изменять нельзя, т.е. нельзя, чтобы такая ссылка ссылалась на другую переменную. Отличие ссылки от указателя рассмотрим на примере.
Пример: ссылка указатель
int tabn=1000; int tabn=1000;
int &r=tabn; int *p=&tabn;
cout<<r<<'\n';//r=1000 cout<<*p<<'\n';//*p=1000
tabn=2000; tabn=2000;
cout<<r<<'\n';//r=2000 cout<<*p<<'\n';//*p=2000
r=3000; *p=3000;
cout<<tabn<<'\n';//tabn=3000 cout<<tabn<<'\n';//tabn=3000
Результаты примеров с ссылкой и указателем одинаковы. Но использование ссылки по сравнению с указателем более удобно, так как ссылка пишется как обычная переменная и не требует операций адресации(&) и разадресации(*). Ссылка r определяет местоположение в памяти переменной tabn. При изменении значения tabn (tabn=2000;) ссылка r получает это новое значение. При изменении значения ссылки (r=3000) переменная tabn получает это новое значение. Более точнее можно сказать следующее об операциях над ссылкой. Операция присваивания ссылке r значения 3000 не изменяет ссылку, т.е. ссылка r всегда ссылается на int tabn, а операция присваивания применяется к переменной tabn.
Таким образом, операции выполняются не над ссылками, а над переменными, на которые они ссылаются. Ссылку образно можно рассматривать, как константный указатель, который всегда разадресован. Необходимо подчеркнуть, что ссылка не является копией переменной, а является вторым именем (алиасом, псевдонимом) этой переменной.
Ссылки используются в качестве формальных параметров функций при передаче агрегированных данных (структур, объединений). При вызове функции автоматически вычисляется адрес фактического параметра (переменной вызывающей функции) и помещается в стек, затем копия адреса присваивается формальному параметру (ссылке). Аналогично выполняется возврат значения функции по ссылке. Возвращать ссылку, как и указатель, на локальную переменную нельзя.
Преимущества ссылок заключаются в следующем:
- эффективное выполнение программы при использовании ссылок в качестве параметров функций при передаче агрегированных данных (как и указатели);
- возможность изменения значений переменных вызывающей функции при изменении значений параметров вызываемой функции, т.е. возможность использования ссылок для возврата значений помимо оператора return (как и указатели);
- по сравнению с указателями, ссылки более удобны при программировании, т.к. используются обычные имена переменных и не требуются операции адресации и разадресации.
Типы данных, определяемые пользователем:
Структура - это поименованная совокупность данных, состоящая из фиксированного числа компонентов разных типов. Компоненты структуры называются полями.
Пример:
struct tip_rab //Объявление типа структура tip_rab
{
int tabn;
char fio[20];
float zarp;
};
tip_rab rab1,rab2,brigada[10];//Объявление переменных типа
//структура tip_rab
Типы полей структуры - это любые типы, включая тип структура. Таким образом, возможно создание иерархической структуры данных.
Доступ к полям структуры осуществляется с помощью составного идентификатора:
per.pole
,где pole – идентификатор (имя) поля структуры;
символ (.) - операция выбора поля структуры.
Пример:
rab1.tabn=1200;
Над целыми структурами, имеющими один и тот же идентификатор типа, возможна операция присваивания.
Пример:
rab1=rab2;
Тип структура является основным типом данных в экономических и управленческих задачах. В качестве параметров функций используются ссылки на тип структура.
Пример:
//Вызываемая функция //Вызывающая функция
void vyvod(tip_rab &x) tip_rab rez;
{ //rez имеет значение
cout<<x.tabn<<'\n'...
<<x.fio<<'\n' vyvod(rez);
<<x.zarp<<'\n';
}
Если необходимо заблокировать изменение переменной rez от функции vyvod, то необходим модификатор const: const tip_rab &x.
Объединение - это поименованная совокупность данных, состоящая из фиксированного числа компонентов разных типов, но активным может быть только один компонент (одно поле). Многие синтаксические и функциональные свойства объединений совпадают со структурами.
Пример:
union tip_rab //Объявление типа объединение
{
int tabn; //Размер 2 байта
char fio[20]; //размер 20 байт
float zarp; //размер 4 байта
};
...
tip_rab rab1,rab2;//Объявление переменных типа tip_rab
Размер объединения равен максимальному размеру всех его полей, в нашем примере - 20 байт. Одновременно в памяти может находиться значение только одного поля. Переменная rab1 может одновременно хранить в 20 байтах либо значение int, либо массив char, либо значение float.
Доступ к полям объединения такой же, как и в структуре. Объединение может быть инициализировано только одним значением.
Перечисление - это упорядоченная последовательность идентификаторов пользователя (перечисляемых констант), принимаемых переменной, причём каждому идентификатору назначается целое значение.
Упорядоченность идентификаторов пользователя определяется возрастающей последовательностью целочисленных значений идентификаторов. По умолчанию идентификаторы инициализируются значениями 0,1 и т.д.
Примеры:
enum selector {vyhod,sozd,prosm,ud,zam};//vyhod=0,sozd=1,...
enum dni {pn,vt,sr,cht,pt,sb,vs};//pn=0,vt=1,...
selector sel1;//Объявление переменной типа selector
dni d; //объявление переменной типа dni
При объявлении перечисления можно явно инициализировать идентификаторы пользователя целыми значениями.
Пример:
enum dni {pn=1,vt,sr,cht=pn+7,pt,sb,vs};//pn=1,vt=2,sr=3,
//cht=8,pt=9,sb=10,vs=11
Пример неименованного перечисления:
enum {false,true}; //символические константы false=0,true=1
Над переменной перечисляемого типа возможны операции:
- операция присваивания, например, sel1=sozd; d=vs;
- операции отношения, например, if (sel1==sozd)...;
- любые операции, выполняемые над типом int.
Преимущество перечислений - возможность использования идентификаторов, несущих смысл, вместо числовых значений, в результате чего облегчается программирование и повышается читабельность программы.