singlepost

Помогите, пожалуйста, разобраться в ошибках (С++) << На главную или назад  

программа должна рисовать кривую Коха

#include <windows.h>
#include <math.h>
//#include "resource.h"

HINSTANCE hInst;
char szAppName[] ="ApiWin";
char szTitle[] ="Window Application";
LRESULT CALLBACK WndProc(HWND, UINT, WPARAM, LPARAM);
void Koch(float startx, float endx, float starty, float endy, int level);
int WINAPI WinMain(HINSTANCE hInstance,
HINSTANCE hPrevInstance,
LPSTR lpCmdLine,
int nCmdShow)
{
MSG msg;
WNDCLASSEX wc;
HWND hwnd;
hInst=hInstance;
memset(&wc,0,sizeof(wc));
wc.style=CS_HREDRAW | CS_VREDRAW;
wc.lpfnWndProc= (WNDPROC)WndProc;
wc.cbClsExtra = 0;
wc.cbWndExtra = 0;
wc.hInstance= hInst;
//wc.hIcon=(HICON)LoadImage(hInst,MAKEINTRESOURCE(IDI_ICON1),IMAGE_ICON,32,32,0);
wc.hCursor=LoadCursor(NULL,IDC_ARROW);
wc.hbrBackground = (HBRUSH)(COLOR_WINDOW+1);
wc.lpszMenuName= NULL;
wc.lpszClassName = szAppName;
wc.cbSize=sizeof(WNDCLASSEX);
//wc.hIconSm=LoadImage(hInst,MAKEINTRESOURCE(IDI_APPICON_SM),IMAGE_ICON,16,16,0);

if(!RegisterClassEx(&wc))
return FALSE;

hwnd = CreateWindow(szAppName, szTitle, WS_OVERLAPPEDWINDOW,
CW_USEDEFAULT, 0, CW_USEDEFAULT, 0,
NULL, NULL, hInst, NULL);

if (!hwnd)
return (FALSE);

ShowWindow(hwnd, nCmdShow);

UpdateWindow(hwnd);

while (GetMessage(&msg, NULL, 0, 0))
{
TranslateMessage(&msg);
DispatchMessage(&msg);
}
return (msg.wParam);
}

LRESULT CALLBACK WndProc(
HWND hwnd,
UINT message,
WPARAM wParam,
LPARAM lParam)
{

PAINTSTRUCT ps;
HDC hdc;

switch (message)
{
case WM_PAINT:
{

hdc=BeginPaint(hwnd,&ps);
TextOut(hdc,10,20,"Message WM_PAINT",16);
Koch(100,800,400,400,7);
EndPaint(hwnd,&ps);
break;
}
case WM_LBUTTONDOWN:
MessageBox(NULL,"Hello, 32-bit world!","Window",MB_OK);
break;

case WM_DESTROY:
PostQuitMessage(0);
break;

default:
return (DefWindowProc(hwnd, message, wParam, lParam));
}
return (0);
}
void Koch(float startx, float endx, float starty, float endy, int level){
if(level==1){
line(startx, starty, endx, endy);
}
L = sqrt( (endx-startx) * (endx-startx) + (endy-starty) * (endy-starty) );
h = L /(2 * sqrt(3));
sina = (endy – starty)/L;
cosa = (endx – startx)/L;
x1 = startx + (endx – startx)/3;
x2 = (endx + startx)/2 + h * sina;
x3 = startx + 2 * (endx – startx)/3;
y1 = starty + (endy – starty)/3;
y2 = (endy + starty)/2 – h * cosa;
y3 = starty + 2 * (endy – starty)/3;
Koch(startx, x1, starty, y1, level-1);
Koch(x1, x2, y1, y2, level-1);
Koch(x2, x3, y2, y3, level-1);
Koch(x3, endx, y3, endy, level-1);}

67 ответов в теме “Помогите, пожалуйста, разобраться в ошибках (С++)”

  1. 25
    Юрий Грицуля ответил:

    Тип можно не менять… Но решение с ветвлением тоже верно, просто свое предложил недочитав до него – не заметил, что есть вторая страница :)

  2. 24
    Роман Дрындик ответил:

    ну как вариант можно но только возвращаемый тип void придется поменять, хотя я лично в этом смысла особого не вижу, с ветвлением и так не будет никаких проблем тут, как например переполнение стека ИМХО )
    Хотя с таким решеним проблемы полностью согласен )

  3. 23
    Юрий Грицуля ответил:

    Предлагаю в качестве выхода из рекурсии использовать кусок
    if(level==1)
    {
    DrawLine(hdc, startx, starty, endx, endy);
    }
    Добавив в него банальный return:
    if(level==1)
    {
    DrawLine(hdc, startx, starty, endx, endy);
    return;
    }

  4. 22
    Роман Дрындик ответил:

    ээээ давай-ка по-подробней… выложи код и что за платформа?

  5. 21
    Иван Гончар ответил:

    Не подскажете, почему программа выдает "sigmentation fallout" если в ней присутствует массив char?

  6. 20
    Роман Дрындик ответил:

    условия для корректного выхода из рекурсии:

    void Koch(float startx, float endx, float starty, float endy, int level, HDC hdc)
    {
    float L = 0, sina = 0, cosa = 0, h = 0, x1 = 0, x2 = 0, x3 = 0, y1 = 0, y2 = 0, y3 = 0;

    if(level==1)
    {
    DrawLine(hdc, startx, starty, endx, endy);
    }

    else

    {

    L = (float)sqrt( (endx-startx) * (endx-startx) + (endy-starty) * (endy-starty) );
    h = (float)L /(2 * sqrt(3));
    sina = (endy – starty)/L;
    cosa = (endx – startx)/L;
    x1 = startx + (endx – startx)/3;
    x2 = (endx + startx)/2 + h * sina;
    x3 = startx + 2 * (endx – startx)/3;
    y1 = starty + (endy – starty)/3;
    y2 = (endy + starty)/2 – h * cosa;
    y3 = starty + 2 * (endy – starty)/3;
    Koch(startx, x1, starty, y1, level-1,hdc);
    Koch(x1, x2, y1, y2, level-1,hdc);
    Koch(x2, x3, y2, y3, level-1,hdc);
    Koch(x3, endx, y3, endy, level-1,hdc);

    }

    };

  7. 19
    Роман Дрындик ответил:

    ну чтобы ошибки снять попробуй убрать мои float ы и поставить int посмотрим что из этого получится…
    про переполнение, да будет переполняться везде, т.к. не был продуман выход из рекурсивного вызова функции, а вот как это исправить я еще думаю, никогда рекурсию не любил (

  8. 18
    Оксана Пещур ответил:

    у меня за год учебы ни одной лабы не было на рекурсию)) поэтому я тоже не очень. ну если придумаете, то будет отлично)

  9. 17
    Роман Дрындик ответил:

    ооооо я думал это тока у нас в универе мы лабы лабами называем )))))) сейчас что-нибудь придумаем…

  10. 16
    Оксана Пещур ответил:

    ))))

  11. 15
    Роман Дрындик ответил:

    у меня visual studio 2008, отсюда и проблемы с переносимостью, но это не беда… рисовать оно не рисует, т.к. просто не успевает видимо стек переполняется выводится ошибка и виснет

  12. 14
    Оксана Пещур ответил:

    и что сделать с этим?)) а в моих версиях тож должен переполняться?

  13. 13
    Оксана Пещур ответил:

    да есть. не может перевести float в int

    MoveToEx(hdc, x1, y1, &pt);
    return LineTo(hdc, x2, y2);

    и насчет sqrt пишет ambiguous call to overloaded function в строке
    h = (float)L /(2 * sqrt(3));

  14. 12
    Роман Дрындик ответил:

    хм странно, что у тебя за платформа? у меня собралась нормально…

  15. 11
    Оксана Пещур ответил:

    visual studio 2005.ну у меня еще есть просто с++ 6я версия. а у вас какая? рисует нормально?

  16. 10
    Роман Дрындик ответил:

    ну ошибок нет, программа запускается, но переполнение стека идет ((( чтобы это убрать надо еще глянуть… А что? есть еще ошибки?

  17. 9
    Роман Дрындик ответил:

    Да и еще ты забыла про #include "stdafx.h"

  18. 8
    Роман Дрындик ответил:

    Теекс вобщем чтобы код просто заработал достаточно сделать вот так. В кратце у тебя нету функции line, которая рисует прямую по двум точкам есть аналог – LineTo, она рисует прямую от текущей позиции до заданной. я написал свою функцию DrawLine, которая рисует прямую по 2м точкам:

    #include "stdafx.h"
    #include <windows.h>
    #include <math.h>
    //#include "resource.h"

    HINSTANCE hInst;
    char szAppName[] ="ApiWin";
    char szTitle[] ="Window Application";
    LRESULT CALLBACK WndProc(HWND, UINT, WPARAM, LPARAM);
    void Koch(float startx, float endx, float starty, float endy, int level, HDC hdc);

    int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nCmdShow)
    {
    MSG msg;
    WNDCLASSEX wc;
    HWND hwnd;
    hInst=hInstance;
    memset(&wc,0,sizeof(wc));
    wc.style = CS_HREDRAW | CS_VREDRAW;
    wc.lpfnWndProc = (WNDPROC)WndProc;
    wc.cbClsExtra = 0;
    wc.cbWndExtra = 0;
    wc.hInstance = hInst;
    //wc.hIcon=(HICON)LoadImage(hInst,MAKEINTRESOURCE(IDI_ICON1),IMAGE_ICON,32,32,0);
    wc.hCursor=LoadCursor(NULL,IDC_ARROW);
    wc.hbrBackground = (HBRUSH)(COLOR_WINDOW+1);
    wc.lpszMenuName = NULL;
    wc.lpszClassName = szAppName;
    wc.cbSize=sizeof(WNDCLASSEX);
    //wc.hIconSm=LoadImage(hInst,MAKEINTRESOURCE(IDI_APPICON_SM),IMAGE_ICON,16,16,0);

    if(!RegisterClassEx(&wc))
    {
    return FALSE;
    }

    hwnd = CreateWindow(szAppName, szTitle, WS_OVERLAPPEDWINDOW, CW_USEDEFAULT, 0, CW_USEDEFAULT, 0, NULL, NULL, hInst, NULL);

    if (!hwnd)
    {
    return (FALSE);
    }

    ShowWindow(hwnd, nCmdShow);
    UpdateWindow(hwnd);

    while (GetMessage(&msg, NULL, 0, 0))
    {
    TranslateMessage(&msg);
    DispatchMessage(&msg);
    }
    return (msg.wParam);
    };

    LRESULT CALLBACK WndProc(HWND hwnd,UINT message,WPARAM wParam,LPARAM lParam)
    {

    PAINTSTRUCT ps;
    HDC hdc;

    switch (message)
    {
    case WM_PAINT:
    {

    hdc=BeginPaint(hwnd,&ps);
    TextOut(hdc,10,20,"Message WM_PAINT",16);
    Koch(100,800,400,400,7,hdc);
    EndPaint(hwnd,&ps);
    break;
    }

    case WM_LBUTTONDOWN:
    MessageBox(NULL,"Hello, 32-bit world!","Window",MB_OK);
    break;

    case WM_DESTROY:
    PostQuitMessage(0);
    break;

    default:

    return (DefWindowProc(hwnd, message, wParam, lParam));
    }
    return (0);
    };

    BOOL DrawLine(HDC hdc, float x1, float y1, float x2, float y2)
    {
    POINT pt;
    MoveToEx(hdc, x1, y1, &pt);
    return LineTo(hdc, x2, y2);
    };

    void Koch(float startx, float endx, float starty, float endy, int level, HDC hdc)
    {
    static float L = 0, sina = 0, cosa = 0, h = 0, x1 = 0, x2 = 0, x3 = 0, y1 = 0, y2 = 0, y3 = 0;

    if(level==1)
    {
    DrawLine(hdc, startx, starty, endx, endy);
    }

    L = (float)sqrt( (endx-startx) * (endx-startx) + (endy-starty) * (endy-starty) );
    h = (float)L /(2 * sqrt(3));
    sina = (endy – starty)/L;
    cosa = (endx – startx)/L;
    x1 = startx + (endx – startx)/3;
    x2 = (endx + startx)/2 + h * sina;
    x3 = startx + 2 * (endx – startx)/3;
    y1 = starty + (endy – starty)/3;
    y2 = (endy + starty)/2 – h * cosa;
    y3 = starty + 2 * (endy – starty)/3;
    Koch(startx, x1, starty, y1, level-1,hdc);
    Koch(x1, x2, y1, y2, level-1,hdc);
    Koch(x2, x3, y2, y3, level-1,hdc);
    Koch(x3, endx, y3, endy, level-1,hdc);
    };

  19. 7
    Оксана Пещур ответил:

    ммдээ.. получается если использовать LineTo то надо переделывать всю функцию

  20. 6
    Роман Дрындик ответил:

    Но основная проблема даже не в этом!!! Ты для построения кривой используешь рекурсию, с ней надо быть очень осторожным, если не продумать условия выхода получишь переполнение стека, что собственно у тебя и происходит…

  21. 5
    Оксана Пещур ответил:

    оо спасибо)) сейчас проверю))

  22. 4
    Оксана Пещур ответил:

    а у вас работает, та которую вы мне прислали?

  23. 3
    Оксана Пещур ответил:

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

  24. 2
    Роман Дрындик ответил:

    там проблема в том, что функции line нету, используй что-то другое для рисования линии например LineTo

  25. 1
    Денис Боенсков ответил:

    А вы не пробовали пошагово пройтись дебагером по программе или закомментировать куски кода по частям в поисках неправильно работающего и попытаться найти неправильно работающий участок кода?

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