singlepost

График в полярной системе координат на С++ << На главную или назад  

Ребята, нужна ваша помощь.
К сожалению задача не идет, т.к. программа говорит о том, что идет где-то деление на ноль. Хотя при выводе 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;
}

52 ответов в теме “График в полярной системе координат на С++”

  1. 17
    Пашка Джиоев ответил:

    Ну нас самом деле необязательность проверки индекса на выход за границы в operator[] сделано для того, чтобы увеличить скорость работы, и мне кажется странным, что VS все-таки проверяет по умолчанию всегда.
    Нагуглил как это отключается:

    #define _SECURE_SCL 0

    Еще говорят, что в VS2010 в Release конфигурации проверка будет отключена, так что не стоит закладываться на такие вещи, т.к. стандарт их не гарантирует.

  2. 16
    Вася Пупкинъ ответил:

    Отклонение от стандарта не тут, а в реализации runtime библиотек. Там при использовании vector[] ексепшн тоже вылетает, проверено в release компиляции для VC9

  3. 15
    Пашка Джиоев ответил:

    А где тут отклонение от стандарта?

  4. 14
    Вася Пупкинъ ответил:

    Спасибо за поправку)

    Хотя… отклонения от стандарта встречаются повсеместно =)

  5. 13
    Пашка Джиоев ответил:

    #13 ну вообще-то вектор в операторе [] не проверяет индекс и никаких эксэпшнов не кидает. Для того, чтобы границы прверялись, следует пользоваться методом at.

  6. 12
    Вася Пупкинъ ответил:

    Ставить здесь на каждый знаменатель 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 компиляции. Так что забудьте о них и кидайте ексепшн.

  7. 11
    Владимир Стебунов ответил:

    Ну мы его тут для отладки ставим.
    А почему нельзя ставить там где мы предполагаем критические данные?

  8. 10
    Вася Пупкинъ ответил:

    assert надо ставить на входные данные, а не в каждой строчке, где может возникнуть ексепшн:

    "задолго до того, как они приведут к краху" == true

  9. 9
    Константин Смотритель ответил:

    Жека, не совсем глупость. Обычно бывает полезно проверять инварианты задолго до того, как они приведут к краху =) assert() используется как в отладочной версии, так и используются подобные макросы, например, для логирования нарушения инвариантов и т.п. Отладчиком тут много не накопаешь =))) Хотя, в некоторых ОС на некоторых платформах можно и отладчиком всё это сделать, ИМХО в общем случае логирование гораздо приятнее на вкус =) Почти как REP =)

  10. 8
    Жека Кирпичев ответил:

    Ну не знаю, чтобы попялиться на значения других переменных :) В общем согласен, глупость сказал.

  11. 7
    Вася Пупкинъ ответил:

    jkff
    > А что тебя не устраивает?

    "Во все места, где в программе производится деление, поставь проверки, сравнивающие знаменатель с нулем"

    Зачем тогда отладчик нужен? =)

  12. 6
    Александр Кручинин ответил:

    вообще если нажать F5 даже в VC++ 6.0 и запустить программу – то программа остановится в том месте, гдк производится деление на ноль

  13. 5
    Жека Кирпичев ответил:

    А что тебя не устраивает?

  14. 4
    Вася Пупкинъ ответил:

    Жека Кирпичев:
    "…поставь проверки, сравнивающие знаменатель с нулем…"

    Это ты так отладчиком пользоватся умеешь?

  15. 3
    Владимир Стебунов ответил:

    Есть еще такое понятие как assert, туда можно засунуть, ту же самую проверку, что знаменатель не нулевой.

  16. 2
    Codigo Pensador ответил:

    спасибо большое.

  17. 1
    Жека Кирпичев ответил:

    Научись пользоваться отладчиком (debugger).
    Во все места, где в программе производится деление, поставь проверки, сравнивающие знаменатель с нулем. поставь туда брейкпоинты и дойди отладчиком. Так и разберешься, откуда там ноль взялся.

Клуб программистов работает уже ой-ой-ой сколько, а если поточнее, то с 2007 года.