Студопедия — Опишите особенности задания параметров функций со значениями по умолчанию
Студопедия Главная Случайная страница Обратная связь

Разделы: Автомобили Астрономия Биология География Дом и сад Другие языки Другое Информатика История Культура Литература Логика Математика Медицина Металлургия Механика Образование Охрана труда Педагогика Политика Право Психология Религия Риторика Социология Спорт Строительство Технология Туризм Физика Философия Финансы Химия Черчение Экология Экономика Электроника

Опишите особенности задания параметров функций со значениями по умолчанию






Ф-ция задаётся так:

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 = ' ');

82. Как передать функции переменное число параметров?

Можно с помощью параметров по умолчанию, как в вопросе выше.

А можно с помощью неуказанного кол-ва аргументов вида:

void func(int a …)

Но обрабатывается это как-то не очень хорошо с помощью макросов и рекомендуется не использовать. Так что Дубкову наверное можно сказать, чтобы сам такое писал.(с)

double f(double n,...) //--заголовок с переменным числом параметров

{ double *p = &n; //--установились на начало списка параметров

double sum = 0, count = 0;

while (*p) //--пока аргумент не равен нулю

{ sum+=(*p); //--суммируем аргумент

p++; //--«перемещаемся на следующий аргумент

count++; //--считаем количество аргументов

}

return ((sum)?sum/count:0); } //--вычисляем среднее

83. Зачем перегружают функции? Как компилятор определяет какую из перегруженных функций вызывают?

Ф-ции перегружают, чтобы можно было выполнять одинаковые задачи для разных типов и при этом использовать только 1 имя ф-ции.

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

Пример:

struct Distance

{ int feet;

float inches; };

void engldisp(Distance); //прототипы

void engldisp(float);

int main(){

…}

void engldisp(Distance dd) //параметр dd типа Distance

{ cout << dd/feet << “\’-“ << “\”; }

void engldisp(floar dd) //параметр dd типа float

{ int feet = static_cast<int>(dd/12);

float inches = dd – feet*12;

cout << feet << “\’-“ << inches << “\”; }

84. Как определяется шаблон функции? Опишите процесс конкретизации шаблона. Что есть явная специализация шаблона?

Шаблоны позволяют использовать одни и те же функции или классы для обработки разных типов данных.

template <class Type>

Type min2(Type a, Type b) {

return a < b? a: b; }

Конкретизация

Шаблон функции описывает, как следует строить конкретные функции, если задано множество фактических типов или значений. Процесс конструирования называется конкретизацией шаблона. Выполняется он неявно, как побочный эффект вызова или взятия адреса шаблона функции. Например, в следующей программе min() конкретизируется дважды: один раз для массива из пяти элементов типа int, а другой – для массива из шести элементов типа double:

массива из шести элементов типа double:

// определение шаблона функции min()

// с параметром-типом Type и параметром-константой size

template <typename Type, int size>

Type min(Type (&r_array)[size])

{ Type min_val = r_array[0];

for (int i = 1; i < size; ++i)

if (r_array[i] < min_val)

min_val = r_array[i];

return min_val;}

// size не задан -- ok

// size = число элементов в списке инициализации

int ia[] = { 10, 7, 14, 3, 25 };

double da[6] = { 10.2, 7.1, 14.5, 3.2, 25.0, 16.8 };

#include <iostream>

int main()

{ // конкретизация min() для массива из 5 элементов типа int

// подставляется Type => int, size => 5

int i = min(ia);

if (i!= 3)

cout << "??oops: integer min() failed\n";

else cout << "!!ok: integer min() worked\n";

// конкретизация min() для массива из 6 элементов типа double

// подставляется Type => double, size => 6

double d = min(da);

if (d!= 3.2)

cout << "??oops: double min() failed\n";

else cout << "!!ok: double min() worked\n";

return 0;}

Вызов

int i = min(ia);

приводит к конкретизации следующего экземпляра функции min(), в котором Type заменено на int, а size на 5:

int min(int (&r_array)[5])

{ int min_val = r_array[0];

for (int i = 1; i < 5; ++i)

if (r_array[i] < min_val)

min_val = r_array[i];

return min_val;}

Аналогично вызов

double d = min(da);

конкретизирует экземпляр min(), в котором Type заменено на double, а size на 6.

Явное определение специализации – это такое определение, в котором за ключевым словом template следует пара угловых скобок <>, а за ними – определение специализированного шаблона. Здесь указывается имя шаблона, аргументы, для которых он специализируется, список параметров функции и ее тело.

#include <cstring>

// явная специализация для const char*: имеет приоритет над конкретизацией шаблона по обобщенному определению

typedef const char *PCC;

template<> PCC max< PCC >(PCC s1, PCC s2) {

return (strcmp(s1, s2) > 0? s1: s2);

ИЛИ

template <class Ttype> тип имя_функции(список_параметров) {тело_функции}

Когда компилятор создает конкретную версию этой ф-ии (вместо Ttype подставляет нужный тип) создается ее конкретизация. Явная специализация шаблона-вручную перегруженная версия шаблона







Дата добавления: 2015-04-19; просмотров: 708. Нарушение авторских прав; Мы поможем в написании вашей работы!



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

Расчетные и графические задания Равновесный объем - это объем, определяемый равенством спроса и предложения...

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

Обзор компонентов Multisim Компоненты – это основа любой схемы, это все элементы, из которых она состоит. Multisim оперирует с двумя категориями...

Различие эмпиризма и рационализма Родоначальником эмпиризма стал английский философ Ф. Бэкон. Основной тезис эмпиризма гласит: в разуме нет ничего такого...

Индекс гингивита (PMA) (Schour, Massler, 1948) Для оценки тяжести гингивита (а в последующем и ре­гистрации динамики процесса) используют папиллярно-маргинально-альвеолярный индекс (РМА)...

Методика исследования периферических лимфатических узлов. Исследование периферических лимфатических узлов производится с помощью осмотра и пальпации...

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

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

Случайной величины Плотностью распределения вероятностей непрерывной случайной величины Х называют функцию f(x) – первую производную от функции распределения F(x): Понятие плотность распределения вероятностей случайной величины Х для дискретной величины неприменима...

Studopedia.info - Студопедия - 2014-2024 год . (0.009 сек.) русская версия | украинская версия