3.5. Скопируйте значения из массива, являющегося аргументом функции, в массив, расположенный в свободной памяти.
3.6. Выведите на печать элементы массива, расположенного в свободной памяти.
3.7. Удалите массив из свободной памяти.
4. В функции
main()
сделайте следующее.
4.1. Вызовите функцию
f()
с аргументом
ga
.
4.2. Определите массив
aa
, содержащий десять элементов, и инициализируйте его первыми десятью значениями факториала (т.е. 1, 2*1, 3*2*1, 4*3*2*1 и т.д.).
4.3. Вызовите функцию
f()
с аргументом
aa
.
Задание со стандартным вектором
1. Определите глобальный вектор
vector<int> gv
; инициализируйте его десятью целыми числами 1, 2, 4, 8, 16 и т.д.
2. Определите функцию
f()
, принимающую аргумент типа
vector<int>
.
3. В функции
f()
сделайте следующее.
3.1. Определите локальный вектор
vector<int> lv
с тем же количеством элементов, что и вектор, являющийся аргументом функции.
3.2. Скопируйте значения из вектора
gv
в вектор
lv
.
3.3. Выведите на печать элементы вектора
lv
.
3.4. Определите локальный вектор
vector<int> lv2
; инициализируйте его копией вектора, являющегося аргументом функции.
3.5. Выведите на печать элементы вектора
lv2
.
4. В функции
main()
сделайте следующее.
4.1. Вызовите функцию
f()
с аргументом
gv
.
4.2. Определите вектор
vector<int> vv
и инициализируйте его первыми десятью значениями факториала (1, 2*1, 3*2*1, 4*3*2*1 и т.д.).
4.3. Вызовите функцию
f()
с аргументом
vv
.
Контрольные вопросы
1. Что означает выражение “Покупатель, будь бдителен!”?
2. Какое копирование объектов класса используется по умолчанию?
3. Когда копирование объектов класса, используемое по умолчанию, является приемлемым, а когда нет?
4. Что такое конструктор копирования?
5. Что такое копирующее присваивание?
6. В чем разница между копирующим присваиванием и копирующей инициализацией?
7. Что такое поверхностное копирование? Что такое глубокое копирование?
8. Как копия объекта класса vector сравнивается со своим прототипом?
9. Перечислите пять основных операций над классом.
10. Что собой представляет конструктор с ключевым словом
explicit
? Когда его следует предпочесть конструктору по умолчанию?
11. Какие операции могут применяться к объекту класса неявно?
12. Что такое массив?
13. Как скопировать массив?
14. Как инициализировать массив?
15. Когда передача указателя на аргумент предпочтительнее передачи его по ссылке и почему?
16. Что такое строка в стиле С, или С-строка?
17. Что такое палиндром?
Термины
Упражнения
1. Напишите функцию
char* strdup(const char*)
, копирующую строку в стиле языка C в свободную память, одновременно выделяя для нее место. Не используйте никаких стандартных функций. Не используйте индексирование, вместо него применяйте оператор разыменования
*
.
2. Напишите функцию
char* findx(const char* s, const char* x)
, находящую первое вхождение строки
x
в стиле языка С в строку
s
. Не используйте никаких стандартных функций. Не используйте индексирование, вместо него применяйте оператор разыменования *.
3. Напишите функцию
int strcmp(const char* s1, const char* s2)
, сравнивающую две строки в стиле языка С. Если строка
s1
меньше строки
s2
в лексикографическом смысле, функция должна возвращать отрицательное число, если строки совпадают — нуль, а если строка
s1
больше строки
s2
в лексикографическом стиле — положительное число. Не используйте никаких стандартных функций. Не используйте индексирование, вместо него применяйте оператор разыменования
*
.
4. Что случится, если передать функциям
strdup()
,
findx()
и
strcmp()
в качестве аргумента не строку в стиле С? Попробуйте! Сначала необходимо выяснить, как получить указатель
char*
, который не ссылается на массив символов, завершающийся нулем, а затем применить его (никогда не делайте этого в реальном — не экспериментальном — коде; это может вызвать катастрофу). Поэкспериментируйте с неправильными строками в стиле С, расположенными в свободной памяти или стеке. Если результаты покажутся разумными, отключите режим отладки. Переделайте и заново выполните все три функции так, чтобы они получали еще один аргумент — максимально допустимое количество символов в строке. Затем протестируйте функции с правильными и неправильными строками в стиле языка С.
5. Напишите функцию
string cat_dot(const string& s1, const string& s2)
, выполняющую конкатенацию двух строк с точкой между ними. Например,
cat_dot("Нильс", "Бор")
вернет строку
Нильс.Бор
.
6. Модифицируйте функцию
cat_dot()
из предыдущего упражнения так, чтобы в качестве третьего аргумента она получала строку, используемую как разделитель (а не точку).
7. Напишите варианты функции
cat_dot()
из предыдущих упражнений, получающие в качестве аргументов строки в стиле языка C и возвращающие строку в стиле языка С, размещенную в свободной памяти. Не используйте никаких стандартных функций или типов. Протестируйте эти функции на нескольких строках. Убедитесь, что вся память, занятая вами с помощью оператора new, освобождается с помощью оператора
delete
. Сравните усилия, затраченные вами на выполнение упр. 5 и 6.
8. Перепишите все функции, приведенные в разделе 18.6, используя для сравнения обратную копию строки; например, введите строку "
home
", сгенерируйте строку "
emoh
" и сравните эти две строки, чтобы убедиться, что слово
home — не палиндром.
9. Проанализируйте схему распределения памяти, описанную в разделе 17.4. Напишите программу, сообщающую, в каком порядке выделяется статическая память, стек и свободная память. В каком направлении растет стек: в сторону старших или младших адресов? Допустим, массив расположен в свободной памяти. Какой элемент будет иметь больший адрес — с большим индексом или с меньшим?