#include "stdafx.h"
// Глобальные переменные
const int maxSize = 2048;
char buf[maxSize];
char text[] = " I love C++ very much Ok ";
char** words;
int nWords, nChars;
// Глобальные функции (утилиты)
void CountWords()
{
#ifdef _DEBUG
cout << "\n\nCountWords:\tGot a text: '" << text << "'";
#endif
nWords = nChars = 0;
bool was = true;
// Ваш код. Разработайте цикл прохода по строке text и подсчета количества слов
nChars = (int)strlen (text);
#ifdef _DEBUG
cout << "\n\tFound " << nWords << " words"
<< "\n\t" << nChars << " characters";
#endif
}
void CreateList()
{
// Ваш код. Если words не равн нулю, то освободите память
// Ваш код. Захватите память под массив указателей в nWords + 1 элементов
char **d = words; // destination (Рабочая лошадка)
bool was = true;
for (int i = 0, n = 0; i <= nChars; i++)
{
// bool is = // Ваш код. Является ли текущий символ пробелом?
// if (Не пробел и не ноль)
// {
// // Ваш код. Перенесите текущий символ в буфер и увельчьте счетчик n
// Этот фрагмент кода выполняет защитные функции. Его можно и выкинуть, так как вряд-ли у вас будут слова длиннее 2048
// if (n == maxSize - 1)
// {
// cout << "\n\nCreateWords: found word longer than "<<maxSize
// << " bytes. Leaving...";
// // Ваш код. Если words не равн нулю, то освободите память
// return;
// }
// }
// if (сейчас не пробел, а был пробел, или сейчас ноль)
// {
if (n > 0)
{
buf[n++] = 0; // Заканчиваем слово
*d++ = strcpy (new char[n], buf); // Захванываем память, копируем слово и запоминаем в words[i]
n = 0; // Готовимся считать символы следующего слова
}
// }
// was = is;
}
*d = 0;
#ifdef _DEBUG
cout << "\nCreateWords: Ok";
#endif
}
void PrintWords ()
{
cout << "\nWords:\n\n";
// Ваш код. Цикл вывода все слов
}
void TrimWord (char* word)
{
char *s, *d;
for (s = word, d = s; *s == ' '; s++) // Пропускаем начальные пробелы
;
// Ваш код. Копируем не пустые символы по адресу *d. Это цикл
*d = 0; // Заканчиваем слово
}
void ReplaceWord (int id, char *word)
{
if (id < 0 || nWords <= id)
{
cout << "\nReplaceWord: Wrong Index = " << id;
return;
}
delete [] words[id]; // Освобождаем память
// Ваш код. Перекопируйте новое солво в words[id]. Здесь понадобится динамический захват памяти
TrimWord (words[id]);
}
void SwapWords (int i, int j)
{
char* t = words[i];
words[i] = words[j];
words[j] = t;
}
//void SwapWords (Два парамера. Оба адреса на адреса)
//{
// char* t = // Ваш код
// *s1 = // Ваш код
// *s2 = // Ваш код
//}
//void SwapWords (Два парамера. Оба ссылки на адреса)
//{
// char* t = // Ваш код
// // Ваш код
// // Ваш код
//}
void SwapAdjacentWords ()
{
int lim = int(nWords & 0xfffffffe);
for (int i = 0; i < lim; i+=2)
SwapWords(i, i+1);
}
//void SwapAdjacentWordsPtr ()
//{
// for (Используйте указатели p1 и p2)
// SwapWords (p1, p2); // Передача адресом
//}
//void SwapAdjacentWordsRef ()
//{
// for (Используйте указатели p1 и p2)
// SwapWords (*p1, *p2); // Передача ссылкой
//}
void SortWords()
{
if (nWords < 2)
return;
bool sorted = false;
// Ваш код. Внешний цикл сортировки
{
sorted = true;
// Ваш код. Вннутренний цикл сортировки
{
// if (strcmp (*s1, *s2) > 0)
// {
// SwapWords (s1, s2);
// sorted = false;
}
}
}
}
void main()
{
#ifndef _DEBUG
cout << "\n\nSource Text: '"<<text<<"'";
#endif
CountWords();
CreateList(); PrintWords();
SwapAdjacentWordsRef(); PrintWords();
SwapAdjacentWordsRef(); PrintWords();
SwapAdjacentWordsPtr(); PrintWords();
SwapAdjacentWordsPtr(); PrintWords();
SwapAdjacentWords(); PrintWords();
SwapAdjacentWords(); PrintWords();
ReplaceWord (2, " Mary Lou "); PrintWords();
SortWords(); PrintWords();
cout << "\n\n";
}
Все функции приложения должны работать.
В языках С и С++ существуют еще две функции для захвата памяти в области heap. Действия по выделению памяти для массива array из size вещественных выглядят следующим образом:
float *array; // Адрес начала будущего массива
array = (float*) malloc (sizeof(float)*size); // или
array = (float*) calloc (size, sizeof(float));
Здесь malloc и calloc — функции, прототипы которых объявлены в файле alloc.h. Функция malloc(Nbyte) запрашивает память размером Nbyte байт из области heap и возвращает указатель на первый байт этого участка. Возвращаемый указатель имеет описатель void*. Это означает, что тип переменной, на которую он может указывать, не определен. Так как мы собираемся присвоить его переменной array (указателю на тип float), то необходимо осуществить преобразование с помощью cast-преобразования (float*).
Возвращаясь к операции захвата памяти new, отметим, что можно запросить память для произвольного, но известного на этапе выполнения количества (n) элементов какого-то типа. Это и составляет суть динамической работы с массивом переменных.
В языке С++ имеется возможность инициализировать указатель путем запроса памяти прямо в момент объявления переменной. Например,
float *p = new float[n]; // Инициализация указателя p
Здесь действует некая условность. Эту же операцию можно было бы выполнить в два этапа.
Уважаемый посетитель!
Чтобы распечатать файл, скачайте его (в формате Word).
Ссылка на скачивание - внизу страницы.