Встроенные функции. Ссылочные переменные. Передача функции аргументов по ссылке. Аргументы по умолчанию. Перегрузка функций. Шаблоны функций. Спецификации шаблонов функций.
// inline.cpp — использование встроенной функции
#include <iostream>
inline double square(double x) { return x * x; } // Определение встроенной функции
int main ()
{
using namespace std;
double a, b;
double с = 13.0;
a = square(5.0);
b = square(4.5 +7.5); // допускается передача выражений
cout «"a = " «a «", b = " «b «"\n";
cout «"c = " «c;
cout << ", с squared = " << square (c+ +) << "\n";
cout << "Now с = " << с << "\n";
return 0;
}
// swaps.срр — обмен значениями с помощью ссылок и указателей
#include <iostream>
void swapr(int & a, int & b); // a, b - псевдонимы для int
void swapp(int * p, int * q); // p, q - адреса int
void swapv(int a, int b); // a, b - новые переменные
int main()
{
using namespace std;
int walletl = 300;
int wallet2 = 350;
cout «"walletl = $" «walletl;
cout «" wallet2 = $" «wallet2 «endl;
// Использование ссылок для обмена содержимого
cout << "Using references to swap contents:\n";
swapr(walletl, wallet2); // передача переменных
cout «"walletl = $" «walletl;
cout << " wallet2 = $" << wallet2 << endl;
// Использование указателей для обмена содержимого
cout «"Using pointers to swap contents again:\n";
swapp(&walletl, &wallet2); // передача адресов переменных
cout «"walletl = $" «walletl;
cout << " wallet2 = $" << wallet2 << endl;
// Попытка использования передачи по значению
cout «"Trying to use passing by value:\n";
swapv(walletl, wallet2); // передача значений переменных
cout «"walletl = $" «walletl;
cout << " wallet2 = $" << wallet2 << endl;
return 0;
}
void swapr(int & a, int & b) // использование ссылок
{
int temp;
temp = a; // использование a, b для получения значений переменных
а = b;
b = temp;
}
void swapp(int * p, int * q) // использование указателей
{
int temp;
temp = *p; // использование *р, *q для получения значений переменных
|
*р = *q;
*q = temp;
}
void swapv(int a, int b) // попытка использования значений
{
int temp;
temp = a; // использование a, b для получения значений переменных
а = b;
b = temp;
}
// left.срр -- строковая функция с аргументом по умолчанию
#include <iostream>
const int ArSize = 80;
char * left (const char * str, int n = 1);
int main ()
{
using namespace std;
char sample[ArSize];
cout << "Enter a string:\n";
cin.get(sample,ArSize);
char *ps = left (sample, 4);
cout «ps «endl;
delete [] ps; // освободить старую строку
ps = left(sample);
cout «ps «endl;
delete [] ps; // освободить новую строку
return 0;
}
// Эта функция возвращает указатель на новую строку,
// состоящую из первых n символов строки str.
char * left (const char * str, int n)
{
if (n < 0)
n = 0;
char * p = new char[n+l];
int i;
for (i = 0; i < n && str[i]; i + +)
p[i] = str[i]; // копирование символов
while (i <= n)
p[i++] = '\0'; // установка остальных символов строки в ' \0'
return p;
}
// leftover.срр — перегрузка функции left() из предыдущей программы
#include <iostream>
unsigned long left (unsigned long num, unsigned ct);
char * left (const char * str, int n = 1);
int main()
{
using namespace std;
char * trip = "Hawaii!!”; // тестовое значение
unsigned long n = 12345678; // тестовое значение
int i;
char * temp;
for (i = 1; i < 10; i + +)
{
cout «left(n, i) «endl;
temp = left(trip,i);
cout «temp «endl;
delete [] temp; // указатель на временную область хранения
}
return 0;
}
// Возвращает первых ct цифр числа num
unsigned long left(unsigned long num, unsigned ct)
{
unsigned digits = 1;
unsigned long n = num;
if (ct == 0 | | num == 0)
return 0; // возврат 0 в случае отсутствия цифр
while (n /= 10)
digits++;
if (digits > ct)
{
ct = digits - ct;
while (ct--)
num /= 10;
return num; // возврат ct знаков слева
}
else // если ct >= количества цифр
return num; // возврат числа целиком
}
// Возвращает указатель на новую строку, состоящую
// из n первых символов строки str
|
char * left (const char * str, int n)
{
if (n < 0)
n = 0;
char * p = new char[n+l];
int i;
for (i = 0; i < n && str[i]; i + +)
p[i] = str[i]; // копирование символов
while (i <= n)
p[i++] = '\0'; // установка остальных символов строки в '\0*
return p;
}
// funtemp.cpp -- использование шаблона функции
#include <iostream>
// Прототип шаблона функции
template <typename T> // или class Т
void Swap(T &а, Т &b);
int main()
{
using namespace std;
int i = 10;
int j = 20;
cout «"i, j = " «i «", " «j «".\n";
cout «"Using compiler-generated int swapper:\n";
Swap(i,j); // генерирует void Swap(int &, int &)
cout << "Now i, j = " <<i<<", " << j << ".\n";
double x = 24.5;
double у = 81.7;
cout «"x, у = " «x «", " << у «".\n";
cout «"Using compiler-generated double swapper:\n";
Swap(x,y); // генерирует void Swap(double &, double &)
cout << "Now x, y="<<x<<", " <<y<<”.\n";
// cin.get ();
return 0;
}
// Определение шаблона функции
template <typename T> // или class T
void Swap(T &a, T &b)
{
T temp; // temp - переменная типа Т
temp = a;
a = b;
b = temp;
}
// twoswap.cpp -- специализация переопределяет шаблон
#include <iostream>
template <typename T>
void Swap(T &a, T &b);
struct job
{
char name[40];
double salary;
int floor;
};
template <> void Swap<job> (job &jl, job &j2); // Явная специализация
void Show(job &j);
int main()
{
using namespace std;
cout.precision (2);
cout.setf(ios::fixed, ios::floatfield);
int i = 10, j = 20;
cout << "i, j = " << i << ", " << j << ". \n";
cout << "Using compiler-generated int swapper. \n";
Swap(i,j); // генерирует void Swap (int &, int &)
cout << "Now i, j = " << i «", " «j «". \n";
job sue = {"Susan Yaffee", 73000.60, 7};
job Sidney = {"Sidney Taffee", 78060.72, 9};
cout «"Before job swapping. \n";
Show(sue);
Show(sidney);
Swap (sue, Sidney); // использует void Swap (job &, job &)
cout «"After job swapping. \n";
Show(sue);
Show(sidney);
// cin.get ();
|
return 0;
}
template <typename T>
void Swap (T &a, T &b) // обобщенная версия
{
T temp;
temp = a;
a = b;
b = temp;
}
// Обменивается только содержимым полей salary и floor структуры job
template <> void Swap<job>(job &jl, job &j2) // специализация
{
double tl;
int t2;
tl = jl.salary;
jl.salary = j2.salary;
j2.salary = tl;
t2 = jl.floor;
jl.floor = j2.floor;
j2.floor = t2;
}
void Show(job &j)
{
using namespace std;
cout << j.name «": $" «j.salary
«" on floor " «j.floor << endl;
}
1. Напишите функцию, которая принимает ссылку на объект string в качестве параметра и преобразует содержимое string в символы верхнего регистра. Используйте функцию toupper(). Напишите программу, использующую функцию в цикле. Пример вывода может выглядеть следующим образом:
Enter a string (q to quit): go away
GO AWAY
Next string (q to quit): good grief!
GOOD GRIEF!
Next string (q to quit): q
Bye.
2. Напишите шаблонную функцию max5(), которая принимает в качестве аргумента массив из пяти элементов типа Т и возвращает наибольший элемент в массиве. (Поскольку размер массива фиксирован, его можно жестко закодировать в цикле, а не передавать в виде аргумента.) Протестируйте функцию в программе с использованием массива из пяти значений int и массива из пяти значений double.
Задание на дом
1. Структура CandyBar содержит три члена. Первый член хранит название коробки конфет. Второй — ее вес (который может иметь дробную часть), а третий — количество калорий (целое значение). Напишите программу, использующую функцию, которая принимает в качестве аргументов ссылку на CandyBar, указатель на char, значение double и значение int. Функция использует три последних значения для установки соответствующих членов структуры. Три последних аргумента должны иметь значения по умолчанию: "Millennium Munch", 2.85 и 350.
Кроме того, программа должна использовать функцию, которая принимает в качестве аргумента ссылку на CandyBar и отображает содержимое этой структуры. Где необходимо, используйте const.
2. Напишите шаблонную функцию maxn(), которая принимает в качестве аргумента массив элементов типа Т и целое число, представляющее количество элементов в массиве, а возвращает элемент с наибольшим значением. Протестируйте ее работу в программе, которая использует этот шаблон с массивом из шести значений int и массивом из четырех значений double. Программа также должна включать специализацию, которая использует массив указателей на char в качестве первого аргумента и количество указателей — в качестве второго, а затем возвращает адрес самой длинной строки. Если имеется более одной строки наибольшей длины, функция должна вернуть адрес первой из них. Протестируйте специализацию на массиве из пяти указателей на строки.