// Компилировать с опцией /EHa
// Можно включить в Project\Properties->Configuration Properties\C/C++\Code Generation\Enable C++ Exceptions
// выбрать /EHa
#include <locale>
#include <iostream>
#include <exception>
#include <Windows.h>
using namespace std;
// Этот класс будем использовать для возврата результата
class xy
{
public:
xy(double x,double y);
double x() const;
double y() const;
private:
double _x,_y;
};
// Будем использовать для проверки переполнени стека
class stackoverflowexception:public exception
{};
// Рекурсивная функция для вычисления
xy calc(unsigned int N);
// Обработчик исключений
void __cdecl sehTranslator(unsigned int code,_EXCEPTION_POINTERS*);
// Здесь будем хранить указатель на предыдущий обработчик исключений
_se_translator_function prevTranslator=0;
int main()
{
setlocale(LC_ALL,"russian");
// Вводим N
cout<<"Введите N:";
int N=0;
cin>>N;
if(cin.fail())
{
cout<<"Ошибочный ввод"<<endl;
}
else
{
if(N>0)
{
// Не рекурсивное вычисление
double X=1,Y=1;
for(unsigned int i=2;i<=static_cast<unsigned int>(N);++i)
{
double newX=X+Y/i/i;
double newY=Y+X/i;
X=newX;
Y=newY;
}
cout<<"X("<<N<<")="<<X<<endl;
cout<<"Y("<<N<<")="<<Y<<endl;
// Рекурсивное вычисление
cout<<"Вычисление при помощи рекурсии:"<<endl;
// Установим собственный обработчик исключений, чтоб перехватить переполнение стека.
// Т.к. стандартный обработчик просто аварийно завершит программу
// Так же сохраним предыдуший обработчик в prevTranslator
prevTranslator=_set_se_translator(sehTranslator);
// Флаг сигнализирующий, что возникло переполнение стека и требуется его восстановление.
bool resetRequired=false;
// Блок обработки исключений
try
{
// Наш рекурсивный вызов
xy res=calc(N);
// Выводим результат
cout<<"X("<<N<<")="<<res.x()<<endl;
cout<<"Y("<<N<<")="<<res.y()<<endl;
}
catch(stackoverflowexception)
{
// Стек переполнился - установим флаг
resetRequired=true;
}
catch(exception e)
{
cout<<"Исключение:"<<e.what()<<endl;
}
catch(...)
{
cout<<"Неизвестное исключение"<<endl;
}
if(resetRequired)
{
cout<<"Возникло переполнение стека"<<endl;
if(!_resetstkoflw())exit(1);
}
// Вернем старый обработчик исключений. Можно и без этого.
_set_se_translator(prevTranslator);
}
else cout<<"Ожидается положительное число"<<endl;
}
system("PAUSE");
return 0;
}
// Рекурсивная функция
xy calc(unsigned int N)
{
if(N>1)
{
xy t=calc(N-1);
return xy(t.x()+t.y()/N/N,t.y()+t.x()/N);
}
else return xy(1,1);
}
xy::xy( double x,double y )
:_x(x)
,_y(y)
{}
inline double xy::x() const
{
return _x;
}
inline double xy::y() const
{
return _y;
}
// Наш обработчик исключений
void __cdecl sehTranslator(unsigned int code,_EXCEPTION_POINTERS* ep)
{
// Если переполнился стек то сгенерируем исключение stackoverflowexception
if(code==EXCEPTION_STACK_OVERFLOW)throw stackoverflowexception();
else
{
// Иначе передадим исключение старому обработчику. Пусть сам разбирается с ним:)
if(prevTranslator)prevTranslator(code,ep);
else throw exception("Unknown exception");
}
}
Введите N:1000
X(1000)=2.41177
Y(1000)=14.0074
Вычисление при помощи рекурсии:
X(1000)=2.41177
Y(1000)=14.0074
Если Вы уже зарегистрированы на Портале - войдите в систему, если Вы еще не регистрировались - пройдите простую процедуру регистрации.