C++ Wskaźniki ćwiczenie - program przestaje działać.

0

Potrzebuję pomocy. Napisałem program imitujący pracę robota (zadanie z Symfonii C++). Poprzednia wersja programu (wcześniejsze zadanie) było bez argumentu double dla funkcji, odpowiadającego za kąt ruchu poszczególnych części robota. Poprzedni program działał bez zarzutów. Ten działa jedynie, gdy tablica "czynnosci" jest wypełniona. Doszedłem do wniosku, że mam jakiś błąd w tym kawałku kodu, który odpowiada za przerwanie pętli jeżeli w bloku tablicy "czynnosci" jest 0

 
        if(czynnosci[i]==0)
        break;

Proszę o pomoc. Tutaj cały program.

 

#include <iostream>
using namespace std;

bool tulow_lewo(double stopnie)
{
     cout << "Skret tulowia w lewo o " << stopnie << " stopni" << endl;
     return true;
}

bool tulow_prawo(double stopnie)
{
     cout << "Skret tulowia w prawo o " << stopnie << " stopni" << endl;
     return true;
}

bool lstopa_przod(double stopnie)
{
     cout << "Ruch lewej stopy w przod o " << stopnie << " stopni" << endl;
     return true;
}

bool pstopa_przod(double stopnie)
{
     cout << "Ruch prawej stopy w przod o " << stopnie << " stopni" << endl;
     return true;
}

bool lstopa_tyl(double stopnie)
{
     cout << "Ruch lewej stopy w tyl o " << stopnie << " stopni" << endl;
     return true;
}

bool pstopa_tyl(double stopnie)
{
     cout << "Ruch prawej stopy w tyl o " << stopnie << " stopni" << endl;
     return true;
}

     

int main()
{
    bool (*wsk[6])(double) = {&tulow_lewo, &tulow_prawo, &lstopa_przod,
                       &pstopa_przod, &lstopa_tyl, &pstopa_tyl};
    double ruch[20];
                      
    int opcja;
    int koniec=0;
    double stopnie=0;
    
    bool (*czynnosci[20])(double);
    
    cout << "------------------------------------\n"
            "######## STEROWANIE ROBOTEM ########\n" 
            "------------------------------------\n" << endl;
            
    cout << "--------------- MENU ---------------\n"
            "0 - ruch tulowia w lewo\n1 - ruch tulowia w prawo\n"
            "2 - ruch lewej stopy w przod\n3 - ruch prawej stopy w przod\n"
            "4 - ruch lewej stopy w tyl\n5 - ruch prawej stopy w tyl\n"
            "6 - wykonac\n7 - koniec\n\n";
            
    
    for (int i=0; i<20; i++)
    {
                
    cout << "Ktora akcje wykonac? ";
    cin >> opcja;
    
    if((opcja>=0) && (opcja<=5))
    {
     cout << "O ile stopni? ";
     cin >> stopnie;
    }
    
    switch(opcja)
    {
                 case 0:
                 case 1:
                 case 2:
                 case 3:
                 case 4:
                 case 5:
                      czynnosci[i] = wsk[opcja];
                      ruch[i] = stopnie;
                      break;
                 case 6:
                      koniec=1;
                      break;
                 case 7:
                      exit(1);
                 default:
                         break;
    }
    if(koniec==1)
    break;
    
    }
    
    for (int i=0; i<20; i++)
    {
        if(czynnosci[i]==0)
        break;
        czynnosci[i](ruch[i]);
    }
            
    
    
    system("pause");
    return 0;
}
0

Owszem, będzie działać to dobrze jedynie, gdy sam nadasz całej tablicy czynności jakąś wartość.
Zauważ, że tablica czynności w trakcie jej deklaracji nie jest wypełniana zerami. Dlatego też nie jest prawdopodobne, aby warunek

if(czynnosci[i]==0)

został kiedykolwiek spełniony. Musisz sam wyzerować pozostałe elementy tablicy.

0

Ok. Myślałem, że tablica automatycznie wypełnia się zerami po jej deklaracji. Teraz wiem, że jest tak tylko wtedy gdy nadamy jej jakieś wartości (reszta wypełnia się zerami). Lecz nadal nie wiem dlaczego myk z powyższego programu udał się w poprzedniej wersji (funkcje bez argumentów):

#include <iostream>
using namespace std;

bool tulow_lewo()
{
     cout << "Skret tulowia w lewo" << endl;
     return true;
}

bool tulow_prawo()
{
     cout << "Skret tulowia w prawo" << endl;
     return true;
}

bool lstopa_przod()
{
     cout << "Ruch lewej stopy w przod" << endl;
     return true;
}

bool pstopa_przod()
{
     cout << "Ruch prawej stopy w przod" << endl;
     return true;
}

bool lstopa_tyl()
{
     cout << "Ruch lewej stopy w tyl" << endl;
     return true;
}

bool pstopa_tyl()
{
     cout << "Ruch prawej stopy w tyl" << endl;
     return true;
}

     

int main()
{
    bool (*wsk[6])() = {&tulow_lewo, &tulow_prawo, &lstopa_przod,
                       &pstopa_przod, &lstopa_tyl, &pstopa_tyl};                  
    int opcja;
    int koniec=0;
    
    bool (*czynnosci[20])();
    
    cout << "------------------------------------\n"
            "######## STEROWANIE ROBOTEM ########\n" 
            "------------------------------------\n" << endl;
            
    cout << "--------------- MENU ---------------\n"
            "0 - ruch tulowia w lewo\n1 - ruch tulowia w prawo\n"
            "2 - ruch lewej stopy w przod\n3 - ruch prawej stopy w przod\n"
            "4 - ruch lewej stopy w tyl\n5 - ruch prawej stopy w tyl\n"
            "6 - wykonac\n7 - koniec\n\n";
            
    
    for (int i=0; i<20; i++)
    {
                
    cout << "Ktora akcje wykonac? ";
    cin >> opcja;
    
    switch(opcja)
    {
                 case 0:
                 case 1:
                 case 2:
                 case 3:
                 case 4:
                 case 5:
                      czynnosci[i] = wsk[opcja];
                      break;
                 case 6:
                      koniec=1;
                      break;
                 case 7:
                      exit(1);
                 default:
                         break;
    }
    if(koniec==1)
    break;
    
    }
    
    for (int i=0; i<20; i++)
    {
        if(czynnosci[i]==0)
        break;
        czynnosci[i]();
    }
            
    
    
    system("pause");
    return 0;
} 

Jest

 
        if(czynnosci[i]==0)
        break;

, a mimo to działa.

Zbieg okoliczności?

0

Jesteś pewien, że dobrze działa? Bo u mnie chyba nie do końca:


######## STEROWANIE ROBOTEM ########

--------------- MENU ---------------
0 - ruch tulowia w lewo
1 - ruch tulowia w prawo
2 - ruch lewej stopy w przod
3 - ruch prawej stopy w przod
4 - ruch lewej stopy w tyl
5 - ruch prawej stopy w tyl
6 - wykonac
7 - koniec

Ktora akcje wykonac? 0
Ktora akcje wykonac? 0
Ktora akcje wykonac? 6
Skret tulowia w lewo
Skret tulowia w lewo
Naruszenie ochrony pamięci.

A w ogóle, to program Ci się kompiluje bez

#include <cstdlib> 

?
Chodzi mi o komendę

exit(1)

Dodatkowo pamiętaj, że

system("pause")

działa tylko na Windows.

0

bool (*czynnosci[20])(double) = {}; // tak mozesz wyzerowac szybko tablice przy inicjalizacji
dodatkowo gdy zrobisz tak:
bool (*czynnosci[20])(double) = {&x1,&x2,..};
to niepodane elementy automatycznie są zerowane. jeśli nie podasz żadnego elementu, wartości tablicy są losowe (chyba, że zadeklarujesz tablicę jako globalną)

1 użytkowników online, w tym zalogowanych: 0, gości: 1