Версия для печати темы
Нажмите сюда для просмотра этой темы в оригинальном формате
Форум программистов > C/C++: Общие вопросы > Улучшить код


Автор: Мизеракль 23.12.2012, 22:07
Доброго времени суток.

Я написал рабочий прграмный код, но хотел поинтересоваться можно ли его написать ещё лучше. Так как я новичок в этом, то хотел бы услышать мнение более сведущих в этом деле людей. Заранее спасибо)))

Код

#include <iostream>
#include <string>

#include "engine.h"

Engine *engine;

void EnteringNumber(int& n)
{
    std::string st;
    std::cin>>st;
    bool minus;
    minus = (st[0] == '-');

    int j = 0;
    if(minus)
        j++;

    n = 0;
    int coef = 1;

    for(int i = st.length()-1; i>=j; i--)
    {
        if(st[i]>'9' || st[i]<'0')
        {
            std::cout<<"Please enter a number!"<<std::endl;
            return;
        }
        n += coef * (st[i]-'0');
        coef*=10;
    }

    if(minus)
        n *= (-1);
}

void Console()
{
    std::cout<<"enter h to view help"<<std::endl;
    while(1)
    {
        char c;
        std::cin>>c;
        switch ©
        {
        case 'h':
            std::cout<<"press s to view status"<<std::endl;
            std::cout<<"press n to change number of dimensions(int)"<<std::endl;
            std::cout<<"press l to change length of curve's edge (int)[-100; 100] to fit on screen"<<std::endl;
            std::cout<<"press x to change x start coordinate (int)[-100; 100] to fit on screen"<<std::endl;
            std::cout<<"press y to change y start coordinate (int)[-100; 100] to fit on screen"<<std::endl;
            std::cout<<"press t to change type {right+, left-}"<<std::endl;
            std::cout<<"press a to change curve's angle (int)[-360; 360]"<<std::endl;
            std::cout<<"predd d to redraw"<<std::endl;
            std::cout<<"press q to quit console"<<std::endl;
            break;
        case 's':
            engine->PrintStatus();
            break;
        case 'q':
            return;
        case 'n':
            int n;
            EnteringNumber(n);
            engine->SetDimension(abs(n));
            break;
        case 'l':
            int l;
            EnteringNumber(l);
            engine->SetL(l);
            break;
        case 'x':
            int x;
            EnteringNumber(x);
            engine->SetX(x);
            break;
        case 'y':
            int y;
            EnteringNumber(y);
            engine->SetY(y);
            break;
        case 't':
            char type;
            std::cin>>type;
            if(type == '+')
                engine->SetRightType(true);
            if(type == '-')
                engine->SetRightType(false);
            break;
        case 'a':
            int angle;
            EnteringNumber(angle);
            engine->SetAngle(angle);
            break;
        case 'd':
            engine->Draw();
            glutSwapBuffers();
            break;
            
        }
        
    }
}

GLvoid onKeyDown(unsigned char key, int x, int y)
{
    switch (key)
    {
    case 'c':
        Console();
        break;
    }

    engine->Draw();
    glutSwapBuffers();
}

GLvoid display(GLvoid)
{
      engine->Draw();
      glutSwapBuffers();
}
 
GLvoid reshape(GLsizei width, GLsizei height)
{
      engine->Resize(width, height);
}

int main(int argc, char** argv)
{
      glutInit(&argc, argv);
      glutInitDisplayMode(GLUT_DOUBLE | GLUT_RGB);
      glutInitWindowSize(800, 600);
      glutInitWindowPosition(100, 100);
      glutCreateWindow("Gilbert's curve");
      
      engine = new Engine();
      engine->Init();
      
      glutDisplayFunc(display);
      glutReshapeFunc(reshape);
      glutKeyboardFunc (onKeyDown);
      
      glutMainLoop();
      return 0;
}

__________________________________________________________

#include "engine.h"

#include <iostream>

//////////////////////////////////

namespace
{
    void renderBitmapString(float x, float y, void *font, char *string) 
    {  
      char *c;
      glRasterPos2f(x,y);
      for (c=string; *c != '\0'; c++) 
      {
        glutBitmapCharacter(font, *c);
      }
    }
}

//////////////////////////////////

Engine::Engine():
    m_dimension(1),    m_x(0), m_y(0), m_l(0.1),
    m_right_type(true), m_angle(0.0)
{
}

//////////////////////////////////

GLvoid Engine::SetProjectionMatrix(GLvoid){
    //glMatrixMode(GL_PROJECTION);                        
    //glLoadIdentity();                                                        
}

//////////////////////////////////

GLvoid Engine::SetModelviewMatrix(GLvoid){
    glMatrixMode(GL_MODELVIEW);                            
    glLoadIdentity();                                                        
}

//////////////////////////////////

GLvoid Engine::Resize(GLsizei width, GLsizei height){
    if (height == 0)                                    
    {
        height = 1;                                        
    }

    glViewport(0, 0, width, height);                    

    Height = height;
    Width = width;

    SetProjectionMatrix();
    SetModelviewMatrix();
}

//////////////////////////////////

GLvoid Engine::Init(GLvoid){
    glClearColor(0.2f, 0.5f, 0.75f, 1.0f);                
    glClearDepth(1.0f);                                    
                                                        
    glEnable(GL_DEPTH_TEST);                            
    glDepthFunc(GL_LEQUAL);                                
                                                        
    glShadeModel(GL_SMOOTH);                            
    glEnable(GL_LINE_SMOOTH);                            
    glHint(GL_LINE_SMOOTH_HINT, GL_NICEST);                
                                                        
    glEnable(GL_BLEND);                                    
    glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);    
                                                        
}

//////////////////////////////////

GLvoid Engine::Draw(GLvoid)                                
{
    glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);    
    
    renderBitmapString(-0.9, 0.9, GLUT_BITMAP_TIMES_ROMAN_24, "press c to open console");
    
    glMatrixMode(GL_MODELVIEW);

    glPushMatrix();

    glLoadIdentity();

    glTranslatef(m_x, m_y, 0.0);    
    
    glRotatef(m_angle, 0.0, 0.0, 1.0);

    if(!m_right_type)
        glRotatef(180, 0.0, 1.0, 0.0);        

    glColor3f(1.0f, 1.0f, 1.0f);
    
    glBegin(GL_LINE_STRIP);
    
    float x = 0.0, y = 0.0;
    glVertex2f(x, y);
    
    DrawD(m_dimension,x,y);

    glEnd();

    glPopMatrix();        
}

//////////////////////////////////

void Engine::SetDimension(int i_dim)
{
    m_dimension = i_dim;
}

//////////////////////////////////

void Engine::SetX(int i_x)
{
    m_x = float(i_x)/100;
}

//////////////////////////////////

void Engine::SetY(int i_y)
{
    m_y = float(i_y)/100;
}

//////////////////////////////////

void Engine::SetL(int i_l)
{
    m_l = float(i_l)/100;
}

//////////////////////////////////

void Engine::DrawA(int i, float& x, float& y) const
{
    if (i == 0)
        return;
    DrawD(i-1,x,y);
    x+=m_l;
    glVertex2f(x, y);

    DrawA(i-1, x, y);
    y+=m_l;
    glVertex2f(x, y);
    
    DrawA(i-1, x, y);
    x-=m_l;
    glVertex2f(x, y);
    
    DrawC(i-1, x, y);
}

//////////////////////////////////

void Engine::DrawB(int i, float& x, float& y) const
{
    if (i == 0)
        return;
    DrawC(i-1,x,y);
    x-=m_l;
    glVertex2f(x, y);

    DrawB(i-1, x, y);
    y-=m_l;
    glVertex2f(x, y);
    
    DrawB(i-1, x, y);
    x+=m_l;
    glVertex2f(x, y);
    
    DrawD(i-1, x, y);
}

//////////////////////////////////

void Engine::DrawC(int i, float& x, float& y) const
{
    if (i == 0)
        return;
    DrawB(i-1,x,y);
    y-=m_l;
    glVertex2f(x, y);

    DrawC(i-1, x, y);
    x-=m_l;
    glVertex2f(x, y);
    
    DrawC(i-1, x, y);
    y+=m_l;
    glVertex2f(x, y);
    
    DrawA(i-1, x, y);
}

//////////////////////////////////

void Engine::DrawD(int i, float& x, float& y) const
{
    if (i == 0)
        return;
    DrawA(i-1,x,y);
    y+=m_l;
    glVertex2f(x, y);

    DrawD(i-1, x, y);
    x+=m_l;
    glVertex2f(x, y);
    
    DrawD(i-1, x, y);
    y-=m_l;
    glVertex2f(x, y);
    
    DrawB(i-1, x, y);
}

//////////////////////////////////

void Engine::SetRightType(bool i_right)
{
    m_right_type = i_right;
}

//////////////////////////////////

void Engine::SetAngle(int i_angle)
{
    m_angle = i_angle;
}

//////////////////////////////////

void Engine::PrintStatus() const
{
    std::cout<<"number of dimensions = "<<m_dimension<<std::endl;
    std::cout<<"edge length = "<<int(m_l*100)<<std::endl;
    std::cout<<"x coord = "<<int(m_x*100)<<std::endl;
    std::cout<<"y_coord = "<<int(m_y*100)<<std::endl;
    std::cout<<"angle value = "<<m_angle<<std::endl;
    std::cout<<"curve type = ";
    if(m_right_type)
        std::cout<<"right"<<std::endl;
    else
        std::cout<<"left"<<std::endl;
}


___________________________________________________________


#pragma once

#pragma comment( lib, "opengl32.lib" )                            
#pragma comment( lib, "glu32.lib" )                                                            
#pragma comment( lib, "glut32.lib" )
#pragma comment( lib, "glut.lib" )

#include <windows.h>        
    
#include <gl\glut.h>        


class Engine {
    GLsizei Height, Width;
    GLvoid SetProjectionMatrix(GLvoid);                
    GLvoid SetModelviewMatrix(GLvoid);                
public:
    Engine();
    GLvoid Resize(GLsizei width, GLsizei height);
    GLvoid Init(GLvoid);                            
    GLvoid Draw(GLvoid);

    void SetDimension(int i_dim);
    void SetX(int i_x);
    void SetY(int i_y);
    void SetL(int i_l);
    void SetRightType(bool i_right);
    void SetAngle(int i_angle);

    void DrawA(int i_dim, float& x, float& y) const;
    void DrawB(int i_dim, float& x, float& y) const;
    void DrawC(int i_dim, float& x, float& y) const;
    void DrawD(int i_dim, float& x, float& y) const;

    void PrintStatus() const;

private:
    int m_dimension;
    bool m_right_type;
    float m_x;
    float m_y;
    float m_l;
    int m_angle;

};


Модератор: используйте подсветку кода. 

Автор: borisbn 24.12.2012, 11:50
Цитата(Мизеракль @  23.12.2012,  22:07 Найти цитируемый пост)
можно ли его написать ещё лучше. 

можно. посмотри это - https://dl.dropbox.com/u/46469564/2012-12-08%2020h10_17.mp4

функцию EnteringNumber можно чуть-чуть упростить:

Код
void EnteringNumber( int & n )
{
    std::cin >> n;
}


дальше ломать глаза не хочется. оформи как следует - тогда и можно будет смотреть

Автор: EvilsInterrupt 24.12.2012, 12:21
Мизеракль
1)
Оформи код, хотя бы тегом код. Но лучше вынеси в отдельный файл и при аттач его. Можешь где-нить у себя в блоге и сюда ссылку.

2)
>>void EnteringNumber( int & n )
А зачем в такую короткую функцию передавать параметр по ссылке? На мой взгляд по значению было бы лучше! Вот когда тебе надо будет передать большое значение в функцию, тогда согласен лучше передать по "const Type &"

3)
В switch-case прикинь какое значение чаще всего будет попадаться и поставь его case первым. Затем какое чуть менее чаще и поставь его вторым. Т.е. поставь case-блоки по частоте. Более того при таком большом switch-case имеет смысл задуматься о таблице функций, т.е. массиве указателей на функции.

Автор: borisbn 24.12.2012, 12:52
Цитата(EvilsInterrupt @  24.12.2012,  12:21 Найти цитируемый пост)
А зачем в такую короткую функцию передавать параметр по ссылке? На мой взгляд по значению было бы лучше!

это - выходной параметр. тогда уж лучше
Код
int EnteringNumber()
{
    int n;
    std::cin >> n;
    return n;
}

хотя... ради такого городить функцию...

Автор: baldina 24.12.2012, 13:39
Цитата(borisbn @  24.12.2012,  12:52 Найти цитируемый пост)
int EnteringNumber()

Код

int getNumber();

Автор: Мизеракль 24.12.2012, 14:22
Спасибо за ответы, просто не знаю как на форуме ещё правильно оформлять. Сейчас попробую переделать.

Автор: volatile 24.12.2012, 18:23
Цитата(Мизеракль @  23.12.2012,  22:07 Найти цитируемый пост)
       case 'n':
            int n;
            EnteringNumber(n);
            engine->SetDimension(abs(n));
            break;
        case 'l':
            int l;
            EnteringNumber(l);
            engine->SetL(l);
            break;
        case 'x':
            int x;

а что, разве такое компилятор кушает?

Автор: Dem_max 25.12.2012, 04:00
Цитата

а что, разве такое компилятор кушает?

Кушает в некоторых случаях.

Powered by Invision Power Board (http://www.invisionboard.com)
© Invision Power Services (http://www.invisionpower.com)