Panel użytkownika
Nazwa użytkownika:
Hasło:
Nie masz jeszcze konta?

Spowolnienie pętli raz działa a raz nie działa, w zależności od kodu 'pobocznego'

Ostatnio zmodyfikowano 2015-06-11 00:51
Autor Wiadomość
Precelek
Temat założony przez niniejszego użytkownika
Spowolnienie pętli raz działa a raz nie działa, w zależności od kodu 'pobocznego'
» 2015-06-11 00:33:48
Czołem, mam mały problem ze spowalnianiem pętli. Problem wydaje się strasznie głupi, bo program ma mniej niż 20 linijek i działa jeżeli zmienia się część odpowiedzialną NIE ZA spowalnianie.

Oto kod: (ten działa)
C/C++
#include <iostream>
#include <unistd.h>
#include <string>

using namespace std;

int main() {
   
    char smiglo[] = { '|', '\\', '-', '/' };
   
    for( int i = 0; i < 200; i++ )
    {
        cout << smiglo[ i % 4 ] << endl;
        usleep( 20000 ); // właściwe spowolnienie
       
       
    }
   
}

Jak widać kod jest bardzo prosty. Wyświetlanie kolejnych znaków tablicy jest spowolnione użyciem funkcji usleep (jestem na Mincie). Wszystko jak należy. Nie rozumiem tylko czemu ten kod już nie działa:

C/C++
#include <iostream>
#include <unistd.h>
#include <string>

using namespace std;

int main() {
   
    char smiglo[] = { '|', '\\', '-', '/' };
   
    for( int i = 0; i < 200; i++ )
    {
        cout << smiglo[ i % 4 ]; //!!!
        usleep( 20000 ); // właściwe spowolnienie
       
       
    }
   
}


Usunąłem jedynie zapis "<< endl", żeby wszystko wypisało się w jednej linii. Jaki efekt? Zamiast spowolnienia pomiędzy napisaniem kolejnych znaków, jest jedna długa przerwa na początku, a potem wszystkie znaki pojawiają się naraz.

Funkcja usleep była u mnie już aktem desperacji, ponieważ ten sam problem występuje, kiedy zamiast niej używam zwykłe pętli for
C/C++
for( int j = 0; j < 1000000; j++ );




Jedyne co mi przychodzi do głowy to jakieś działanie optymalizacyjne kompilatora - ale na to nie umiem wpływać, więc też kaszana.

Przy okazji, jaki efekt chcę osiągnąć?
Chcę, aby powstało śmigło, czyli po narysowaniu znaku i przerwie chcę wywołać "\r". Ale póki to nie działa, to mogę o tym zapomnieć. Dzięki.
P-133441
pekfos
» 2015-06-11 00:39:40
To nie optymalizacje, tylko buforowanie wyjścia. Wypisuj na std::cerr, albo wywołuj metodę flush(), by wymusić wysłanie zawartości bufora na wyjście. Użycie std::endl, od wypisania samego znaku nowej linii, różni się właśnie wywołaniem tej metody. Wybierając rozwiązanie pamiętaj, że strumień błędów jest przeznaczony do wypisywania błędów, a nie regularnych danych. Jeśli zaczniesz bawić się z przekierowaniami, zacznie robić to dużą różnicę.
P-133442
Precelek
Temat założony przez niniejszego użytkownika
» 2015-06-11 00:43:36
Dzięki wielkie, flush wszystko naprawia. Mógłbyś powiedzieć o tym coś więcej albo podrzucić link do poczytania o co tu chodzi?
P-133443
pekfos
» 2015-06-11 00:47:43
Operacje i/o są woolne, więc są buforowane. Nie zobaczysz wyniku, póki bufor się nie wypełni. Strumień błędów np nie jest buforowany, bo lepiej mieć wolne wyjście i je mieć, niż pozwolić na sytuację, że komunikat błędu zaginie w buforze, bo program po drodze umrze. Jak chcesz poczytać, to jest dokumentacja biblioteki standardowej C++.
P-133444
Precelek
Temat założony przez niniejszego użytkownika
» 2015-06-11 00:51:33
Rozumiem, dzięki wielkie.
P-133445
« 1 »
  Strona 1 z 1