Ребята, нужна ваша помощь.
К сожалению задача не идет, т.к. программа говорит о том, что идет где-то деление на ноль. Хотя при выводе xmax ymax там ноль не получается. Помогите,пожалуйста, разобраться и найти в чем может состоять ошибка.
#define kr 20
main()
{float ymax,ymin,xmax,xmin,Mx,My,h,r,p,t,Z;
int driver, mode, kod, curmode,rx,ry,xg,yg,otx,oty,i,n,m,x,y,a,k;
printf("Vvedite razmer & kol-vo");
scanf("%d%d",&a,&k);
getch();
driver=DETECT;
initgraph(&driver, &mode, "");
kod=graphresult();
if(kod!=0)
{ puts("Graph Error");
printf("%s\n", grapherrormsg(kod));
getch();
exit(1);
}
t=0;
r=a*sin(k*t);
x=r*cos(t);
y=r*sin(t);
h=2*M_PI/1000;
for(t=0; t<2*M_PI; t+=h)
{r=a*sin(k*t);
x=r*cos(t);
y=r*sin(t);
ymax=y;
ymin=y;
y=y+h;
if(y>ymax)
ymax=y;
if(y<ymin)
ymin=y;
//————————————————–
xmax=x;
xmin=x;
x=x+h;
if(x>xmax)
xmax=x;
if(x<xmin)
xmin=x;
}
rx=getmaxx();
ry=getmaxy();
Mx=(rx-2*kr)/fabs(xmax-xmin);
// if(Z==0)Z=0.0001;
// Mx=Z;
My=(ry-2*kr)/fabs(ymax-ymin);
// if(Z==0)Z=0.0001;
// Mx=Z;
otx=kr-xmin*Mx;
oty=kr+ymax*My;
xg=otx+x*Mx;
yg=oty-y*My;
t=0;
while(t<2*M_PI)
{r=a*sin(k*t);
x=r*cos(t);
y=r*sin(t);
xg=otx+x*Mx;
yg=oty-y*My;
putpixel(xg,yg,14);
t+=h;
}
getch();
closegraph();
return 0;
}
18 ноября 2009 в 20:02
Ну нас самом деле необязательность проверки индекса на выход за границы в operator[] сделано для того, чтобы увеличить скорость работы, и мне кажется странным, что VS все-таки проверяет по умолчанию всегда.
Нагуглил как это отключается:
#define _SECURE_SCL 0
Еще говорят, что в VS2010 в Release конфигурации проверка будет отключена, так что не стоит закладываться на такие вещи, т.к. стандарт их не гарантирует.
18 ноября 2009 в 18:03
Отклонение от стандарта не тут, а в реализации runtime библиотек. Там при использовании vector[] ексепшн тоже вылетает, проверено в release компиляции для VC9
18 ноября 2009 в 16:04
А где тут отклонение от стандарта?
18 ноября 2009 в 16:01
Спасибо за поправку)
Хотя… отклонения от стандарта встречаются повсеместно =)
18 ноября 2009 в 12:05
#13 ну вообще-то вектор в операторе [] не проверяет индекс и никаких эксэпшнов не кидает. Для того, чтобы границы прверялись, следует пользоваться методом at.
18 ноября 2009 в 0:04
Ставить здесь на каждый знаменатель assert? Зачем? Если где-то ноль, то ексепшн вылетит и будет видно где и что не работает.
"assert надо ставить на входные данные, а не в каждой строчке, где мoжет возникнуть ексепшн"
"А почему нельзя ставить там где мы предполагаем критические данные?"
assert предназначет для отладки такого кода, ексепшн из которого не вылетает при неверных данных. Пример:
int array[42];
int get_array_element( size_t index )
{
return array[ index ]; // OMFG
}
Если index больше 41, то ексепшн может вылететь, а может и не вылететь. Это зависит от режима компиляции, от положения массива в памяти и т.д. Поэтому здесь уместно использовать assert:
int array[ SIZE ];
int get_array_element( size_t index )
{
assert( index < SIZE );
return array[ index ];
}
Но если при неверном индексе ексепшн вылетает гарантированно, тогда зачем assert? Пример:
std::vector< int > some_vec;
int get_array_element( size_t index )
{
return some_vec[ index ];
}
Если index кривой, то гарантированно вылетит ексепшн std::out_of_range.
Но это все лирика.
На приктике все assert'ы удаляются из кода программы при release компиляции. Так что забудьте о них и кидайте ексепшн.
17 ноября 2009 в 21:00
Ну мы его тут для отладки ставим.
А почему нельзя ставить там где мы предполагаем критические данные?
17 ноября 2009 в 12:01
assert надо ставить на входные данные, а не в каждой строчке, где может возникнуть ексепшн:
"задолго до того, как они приведут к краху" == true
17 ноября 2009 в 7:04
Жека, не совсем глупость. Обычно бывает полезно проверять инварианты задолго до того, как они приведут к краху =) assert() используется как в отладочной версии, так и используются подобные макросы, например, для логирования нарушения инвариантов и т.п. Отладчиком тут много не накопаешь =))) Хотя, в некоторых ОС на некоторых платформах можно и отладчиком всё это сделать, ИМХО в общем случае логирование гораздо приятнее на вкус =) Почти как REP =)
16 ноября 2009 в 23:00
Ну не знаю, чтобы попялиться на значения других переменных В общем согласен, глупость сказал.
16 ноября 2009 в 22:04
jkff
> А что тебя не устраивает?
"Во все места, где в программе производится деление, поставь проверки, сравнивающие знаменатель с нулем"
Зачем тогда отладчик нужен? =)
16 ноября 2009 в 12:01
вообще если нажать F5 даже в VC++ 6.0 и запустить программу – то программа остановится в том месте, гдк производится деление на ноль
16 ноября 2009 в 8:02
А что тебя не устраивает?
16 ноября 2009 в 1:01
Жека Кирпичев:
"…поставь проверки, сравнивающие знаменатель с нулем…"
Это ты так отладчиком пользоватся умеешь?
15 ноября 2009 в 22:00
Есть еще такое понятие как assert, туда можно засунуть, ту же самую проверку, что знаменатель не нулевой.
15 ноября 2009 в 20:05
спасибо большое.
15 ноября 2009 в 20:04
Научись пользоваться отладчиком (debugger).
Во все места, где в программе производится деление, поставь проверки, сравнивающие знаменатель с нулем. поставь туда брейкпоинты и дойди отладчиком. Так и разберешься, откуда там ноль взялся.