- •1. Приведите определение одного и того же числа в 10-ной и 16-ной системах счисления.
- •4. Приведите примеры определения строковых литералов. Как разместить длинную строковую константу в нескольких строках? Что такое «пустая строка»? Ее внутреннее представление.
- •6. Как явно указать, что константа должна иметь некоторый требуемый тип?
- •7. Как определяется переменная булевского типа? Ее значения и внутреннее представление.
- •33. Определите назначение операций ? , (тип)
- •73. Укажите способы доступа к полям структуры. Можно ли присвоить одну структуру другой?
- •74. Можно ли структуру возвратить из функции?
- •75. Как определить битовые поля?
- •76. Приведите синтаксис объявления и определения функции. Укажите область действия параметров функций.
- •77. Какие типы возвращаемых значений недопустимы для функций?
- •78. Как вернуть массив из функции? Укажите особенности передачи массивов как параметров.
- •79. Укажите особенности передачи параметров функций по значению, по адресу, по ссылке.
- •80. Можно ли объявить параметры функции с модификаторами?
- •81. Опишите особенности задания параметров функций со значениями по умолчанию.
- •82. Как передать функции переменное число параметров?
- •83. Зачем перегружают функции? Как компилятор определяет какую из перегруженных функций вызывают?
- •84. Как определяется шаблон функции? Опишите процесс конкретизации шаблона. Что есть явная специализация шаблона?
- •90. Как инициализировать, изменить поля класса, определенные как константные?
- •91. Опишите синтаксис определения метода класса вне описания класса.
- •92. Опишите синтаксис конструктора.
- •97. Можно ли построить класс без конструктора? Как в этом случае описать объекты класса?
- •99. Определите понятие «дружественная функция ».
- •100. Опишите синтаксис деструктора.Зачем виртуализировать деструктор? Можно ли наследовать деструктор?Можно ли явно вызвать деструктор?
- •101. Все ли операции могут быть перегружены? Можно ли перегрузить операции для базовых стандартных типов данных?
- •102. Зачем используют ключевое слово operator?
- •103. Укажите различные способы перегрузки операторов.
- •114. Определите понятие «абстрактный класс». Определите понятие «чистый виртуальный метод».
- •115. Опишите понятие «множественное наследование». Какие проблемы возникают при множествен-ном наследовании?
- •116. Опишите использование ключевых слов try, throw,catch.
- •117. Как определяется, какому блоку catch передается исключение для обработки?(стр.665)
- •118. Куда передается управление после обработки исключения?
- •119. Как организуется передача исключения в объемлющий блок?
79. Укажите особенности передачи параметров функций по значению, по адресу, по ссылке.
Переменные, в которых сохраняются параметры, передаваемые функции, также являются локальными для этой функции. Эти переменные создаются при вызове функции и в них копируются значения, передаваемые функции в качестве параметров. Эти переменные можно изменять, но все изменения этих переменных будут "забыты" после выхода из функции. Рассмотрим это на примере следующей функции, "меняющей" значения двух переданных ей переменных:
#include<iostream>
using namespace std;
void swap(int a, int b)
{ int t;
t=b;
b=a;
a=t; }
int main()
{ int p=3,q=5;
swap(p,q);
cout<<p<<" "<<q<<endl;
return 0; }
При вызове функции swap создаются новые переменные a и b, им присваиваются значения 3 и 5. Эти переменные никак не связаны с переменными p и q и их изменение не изменяет значения p и q. Такой способ передачи параметров называется передачей параметров по значению.
Чтобы функция могла изменять значения переменных, объявленных в других функциях, необходимо указать, что передаваемый параметр является не просто константной величиной, а переменной, необходимо передавать значения по ссылке. Для этого функцию swap следовало бы объявить следующим образом:
void swap(int & a, int & b)
Амперсанды перед именем переменной означают, что эта переменная является не локальной переменной, а ссылкой на переменную, указанную в качестве параметра при вызове функции. Теперь при вызове swap(p,q) переменные a и b являются синонимами для переменных p и q, и изменение их значений влечет изменение значений p и q. А вот вызывать функцию в виде swap(3,5) уже нельзя, поскольку 3 и 5 — это константы, и сделать переменные синонимами констант нельзя.
Однако в языке C (не C++) вообще не было такого понятия, как передача параметров по ссылке. Для того, чтобы реализовать функцию, аналогичную swap в рассмотренном примере, необходимо было передавать адреса переменных p и q, а сама функция при этом должна быть объявлена, как
void swap(int * a, int * b)
Поскольку в этом случае функция swap знает физические адреса в оперативной памяти переменных p и q, то разыменовав эти адреса функция swap сможет изменить значения самих переменных p и q.
80. Можно ли объявить параметры функции с модификаторами?
Да, можно. Например, с модификатором const (можно передать константный указатель – его нельзя будет изменять внутри ф-ции). Void func(const int * p ) { * p = 20; // ERROR! }
81. Опишите особенности задания параметров функций со значениями по умолчанию.
Ф-ция задаётся так:
int func(int a = 0, int b = 12, int c = 666)
{…}
При этом при вызове это ф-ции с кол-вом параметров меньшим, чем перечислено,то параметры по умолчанию будут браться справа налево, т.к. сначала c, потом b, потом a
Поэтому нельзя задавать ф-цию вида:
int func(int a = 0, int b) т.к. в ф-цию всегда должен передваться параметр b, а значит и a
Значение параметра по умолчанию – это значение, которое разработчик считает подходящим в большинстве случаев употребления функции, хотя и не во всех. Оно освобождает программиста от необходимости уделять внимание каждой детали интерфейса функции.
Значения по умолчанию для одного или нескольких параметров функции задаются с помощью того же синтаксиса, который употребляется при инициализации переменных. Например, функция для создания и инициализации двумерного массива, моделирующего экран терминала, может использовать такие значения для высоты, ширины и символа фона экрана:
char *screenInit( int height = 24, int width = 80,
char background = ' ' );
Функция, для которой задано значение параметра по умолчанию, может вызываться по-разному. Если аргумент опущен, используется значение по умолчанию, в противном случае – значение переданного аргумента. Все следующие вызовы screenInit() корректны:
char *cursor;
// эквивалентно screenInit(24,80,' ')
cursor = screenInit();
// эквивалентно screenInit(66,80,' ')
cursor = screenlnit(66);
// эквивалентно screenInit(66,256,' ')
cursor = screenlnit(66, 256);
cursor = screenlnit(66, 256, '#');
Фактические аргументы сопоставляются с формальными параметрами позиционно (в порядке следования), и значения по умолчанию могут использоваться только для подстановки вместо отсутствующих последних аргументов. В нашем примере невозможно задать значение для
background, не задавая его для height и width.
// эквивалентно screenInit('?',80,' ')
cursor = screenInit('?');
// ошибка, неэквивалентно screenInit(24,80,'?')
cursor = screenInit( , ,'?');
При разработке функции с параметрами по умолчанию придется позаботиться об их расположении. Те, для которых значения по умолчанию вряд ли будут употребляться, необходимо поместить в начало списка. Функция screenInit() предполагает (возможно, основываясь на опыте применения), что параметр height будет востребован пользователем наиболее часто.
Значения по умолчанию могут задаваться для всех параметров или только для некоторых. При этом параметры без таких значений должны идти раньше тех, для которых они указаны.
// ошибка: width должна иметь значение по умолчанию,
// если такое значение имеет height
char *screenlnit( int height = 24, int width,
char background = ' ' );
