четверг, 17 мая 2012 г.

Решение задачки на Си


Решил задачку для студента Пермского политеха, вот ниже решение без матчасти и в упрощенной постановке (чтоб не показывать как нашел точку пересечения эллипса с окружностью, в этом соль решения). Определяем принадлежность точки областям А или B.

#include <stdlib.h>
#include <stdio.h>    // чтоб обеспечить ввод/вывод
#include <math.h>     // чтоб использовать стандартные математические функции
#include <windows.h> // Чтоб русифицировать вывод в консоль, в окне консоли шрифт поменять

int blnCircle(double x,double  y,double R,double xo,double yo );
int blnEllips(double x,double  y,double a,double b,double xe,double ye);

int main()
{
    //Чтоб русифицировать вывод в консоль, в окне Свойства консоли шрифт поменять на TT
    // в аргументах кодировка файла для UTF-8 ~ 65001, а для cp1251 ~ 1251
    SetConsoleCP(65001);
    SetConsoleOutputCP(65001);

    double R,x,y,a,b,xo,yo,xe,ye;
    double t1,t2,c;     // Промежут. данные для расчета центра эллипса

    do
    {
        printf("Введите радиус окружности (R>=15):\n");
        scanf("%lf",&R);
    }
    while(R<15);

    do
    {
        printf("Введите значения полуосей эллипса a и b (b>a, 2b>=40 ):\n");
        scanf("%lf%lf",&a ,&b) ;
    }
    while(b<=a || 2.0*b<40);

    printf("Введите координаты точки для проверки, принадлежности её областям A или B\n");
    scanf("%lf%lf",&x ,&y) ;

    /// Определим центр окружности
    xo=(38-sqrtf(-900+60*R));
    yo=(R-30);

    /// Определим центр эллипса
    c=sqrt(pow(b,2)-pow(a,2));
    t1=pow(40.0-b+c,2);
    t2=pow(c-40+b,2);
    xe=9.0 - sqrt((4.0*t1*t2-pow(t1+t2-4*b*b,2))/(-16.0*pow(b,2)));
    ye=40.0-b;




    if( blnEllips(x,y,a,b,xe,ye) && x<=0 && y>=9 && !blnCircle(x,y,R,xo,yo))
        printf ("Точка принадлежит области A\n");
    else if(!blnEllips(x,y,a,b,xe,ye) && blnCircle(x,y,R,xo,yo) && y>=0 && x>=0 && y<=9)
        printf("Точка принадлежит области B\n");
    else
        printf("Точка не принадлежит областям A и B\n");

    system("pause"); // Останов программы под Windows, чтоб успеть результат посмотреть
    return 0;
}


/// Проверка принадлежности точки области ограниченой окружностью и получения её цнтра
int blnCircle(double x,double  y,double R,double xo,double yo)
{
    return (pow((x-xo),2)+pow(y-yo,2)<=pow(R,2));
}

/// Проверка принадлежности точки области внутри эллипса и его центр
int blnEllips(double x,double y,double a,double b,double xe,double ye)
{
    return ( pow(x-xe,2)/pow(a,2)+pow(y-ye,2)/pow(b,2)<=1 );
}


среда, 22 февраля 2012 г.

Эллипсис в C/C++

Эллипсис (многоточие в описании функции, там где аргументы) может приводить к ошибкам сегментации памяти. Если, например,


//Функция, просто выводит один аргумент за другим
void f(char *s1, ...)
{
char **cp = &s1; //--адрес первого указателя
while (*cp)
{ std::cout << (*cp) << std::endl;
cp++; //-- перемещаемся на следующий аргумент
}
}

// ...
f("First ","Two ","Three ", 0); // - это правильный вызов, 0 - признак конца списка аргументов
// ...
f("First ","Two ","Three "); // - это ошибочный вызов, дающий ошибку сегментации
// ...


Вот значит, что VB с людьми делает - появляются вредные привычки в программировании.