
- •Int z[n]; //Неверно!
- •Урок 10. Рекурсивные функции
- •Int z[3]; //Массив
- •Урок 26. Конструкторы и деструкторы
- •Урок 27. Классы и указатели
- •Урок 28. Практика: список - добавление элементов
- •Урок 29. Показ элементов списка
- •Урок 30. Ищем элемент в списке
- •Урок 31. Пара вспомогательных методов для списка
- •Урок 32. Удаление элемента из списка
- •Урок 33. Функция с переменным числом параметров
- •Урок 34. Считаем элементы в списке
- •Урок 35. Обмен соседних элементов в списке
- •Урок 36. Получаем элемент списка по его номеру
- •Урок 36. Получаем элемент списка по его номеру
- •Урок 37. Сортируем элементы списка
- •Урок 38. Сортировка с перегрузкой оператора
Урок 31. Пара вспомогательных методов для списка
Сейчас мы с вами напишем пару вспомогательных методов для нашего класса списка.
Внесите в заголовочный файл класса списка объявления наших методов:
//Класс списка.
class CList
{
public:
// Не пустой ли наш список?
bool IsEmpty();
// Предыдущий элемент в списке.
CData * GetPrev(CData * p);
...
Первый метод короткий - с него и начнем. Он просто отвечает на вопрос, не пуст ли наш список. Вот его код:
bool CList::IsEmpty()
{
return m_pFirst==NULL;
}
Второй метод возвращет по указателю на передаваемый в параметре элемент списка предыдущий для него (такой метод может оказаться весьма полезным, так как наш класс CData содержит только указатель на следующий элемент, а на предыдущий - нет). Вот его код:
CData * CList::GetPrev(CData *p)
{
// Если предыдущего элемента списка нет
// (т. е. наш элемент совпадает с первым)
// то возвращем NULL.
if(p==m_pFirst)
return NULL;
// Если предыдущий элемент есть.
CData * pCurr = m_pFirst;
do{
// Если для очередного элемента в списке
// следующий для него элемент есть
// передаваемый нами в параметре,
if(pCurr->m_pNext==p){
// то и возвращаем этот очередной элемент.
return pCurr;
}
// Переводим pCurr на следующий элемент в списке.
}while((pCurr = pCurr->m_pNext)!=NULL);
return NULL;
}
C/C++
Урок 32. Удаление элемента из списка
Рассмотрим стандартную задачу - удаление элемента из списка.
Алгоритмически мы должны рассмотреть два случая - когда удаляем самы первый элемент из списка и когда удаляем элемент из середины или конца списка.
Вот код для нашего метода (не забудьте внести объявление этого метода в сам класс):
bool CList::RemoveData(int a, int b)
{
// Если список пуст
if(IsEmpty())
// то выходим.
return false;
// Получаем элемент для удаления.
CData * pData = FindData(a, b);
// Если такого элемента в списке нет
if(pData == NULL)
// то выходим.
return false;
// Если удаляемый элемент - первый в списке.
if(pData == m_pFirst){
// Делаем первым следующий за ним элемент списка.
m_pFirst = pData->m_pNext;
// Освобождаем память, которую занимал удаляемый элемент.
delete pData;
// И выходим.
return true;
}
// Если удаляемый элемент - не первый в списке.
// То делаем так, чтобы элемент, находящийся в списке
// перед удаляемым, показывал на следующий за удаляемым элемент.
GetPrev(pData)->m_pNext = pData->m_pNext;
// Освобождаем память, которую занимал удалаемый элемент.
delete pData;
// И выходим.
return true;
}
Код должен быть ясен из комментария. Если удаление произошло, то возвращяем true, если нет, то false. В этом методе мы использовали другие методы (GetPrev, FindData), написанные на прошлых уроках.
C/C++
Урок 33. Функция с переменным числом параметров
Вот пример функции, принимающий переменное число параметров.
Пример классический - а именно наша функция возвращает сумму своих параметров. Обратите внимание, что первым параметром мы передаем число чисел для суммирования (т. е. сам первый параметр суммироваться не будет, он говорит только, сколько всего параметров будут суммироваться (это все оставшиеся параметры)).
#include <iostream.h>
// Задаем функцию с переменным числом параметров.
int sum(int n, ...)
{
// Получаем адрес первого параметра.
int *p = &n;
// Переводим указатель на второй параметр.
p++;
// Объявляем переменную для суммы
// и присваиваем ей ноль.
int res = 0;
// Сумирование оставшихся параметров.
for(int i=0; i<n; i++){
// Добавление к сумме очередного параметра.
res+=(*p);
// Первод указателя на следующий параметр.
p++;
}
// Возврат суммы.
return res;
}
void main(){
int r = 0;
// Суммируем 5 чисел.
r = sum(5, 1, 2, 3, 4, 500);
cout<<"Sum = "<<r<<"\n";
}
Переменное число параметров в функции обозначаается посредством многоточия (...). В нашем объявлении функции мы указываем, что обязотельно должен присутствовать первый параметр (типа int), после которого может быть любое число параметров любого типа.
Внутри функция устроена так - мы получаем адрес в адресном пространстве, по которому расположены передаваемые в функцию параметры. Это адрес первого параметра:
...
int *p = &n;
...
Далее мы перебираем все параметры (а всего их n) через указатель - он постоянно переводится на следующий параметр посредством строки:
...
p++;
...
Результатом выполнения указанного фрагмента будет 510.
C/C++