C++- Typy wyliczeniowe (enum)


(Kn0pix5) #1

Właśnie uczę się C++ i mam za zadanie napisać grę "Kółko i krzyżyk". Wykorzystuję typy wyliczeniowe:

enum FIELD [FEMPTY='|', 

                    FCIRCLE='O', 

                    FCROSS='X' ];

Gdy wyświetlam tablicę aPlan za pomocą strumenia std::

FIELD aPlan[3][3]= {{FEMPTY,FEMPTY,FEMPTY},

                             {FEMPTY,FEMPTY,FEMPTY},

                             {FEMPTY,FEMPTY,FEMPTY}};

using namespace std;

cout << aPlan[0][0] << ... << endl;

To zamiast znaków | pojawiają się zera... Czy jest gdzieś strona, na której mogę to sprawdzić?


(Sawyer47) #2

Wewnętrznie wartości typu enum to liczby całkowite. Zazwyczaj pisze się enum { field1 = 0, field2 = 1 }. Dużego problemu nie ma bo typ char jest typem arytmetycznym i można go skonwertować na liczbę. Jedyne co to trzeba użyć rzutowania na typ char z typu enum, wtedy to powinno działać.

Ten kod u mnie działa:

enum Field { empty = '|',

			 circle = 'O',

			 cross = 'X' };


int main() {

	Field znak = empty ;

	std::cout << static_cast(znak) << std::endl;

}

(Kn0pix5) #3

Dzięki wielkie :slight_smile: Przykład działa, lez jako wyrażenie korzystam z elementu tablicy:

static_cast(aPlan[0][0]);

PS: Czy istnieje funkcja, dzięki której wyczyszcze ekran konsoli nie zamykając programu ?


(Fiołek) #4

system("cls")

Można też cofnąć się na początek konsoli, wypisać tablice spacji[rozmiar konsoli], cofnąć się do początku i będzie to samo.


(Sawyer47) #5

W C++ nie ma takiej funkcji. Można wypisać albo

"\033[2J\033[0;0f"

albo

"\033[H\033[2J"

Zobacz tu: http://4programmers.net/C/FAQ/Uniwersal ... azdy_Jezyk

Jest to w miarę uniwersalna metoda, choć nie działa wszędzie i jest raczej średnio elegancka.

Można też wywoływać komendę w systemie za pomocą funkcji system(), ale to z wiadomych względów tez zbyt przenośne nie jest.


(Kn0pix5) #6

nr47 , spróbowałem obu metod. Nie działają na kompilatorze Dev-cpp.


(Sawyer47) #7

Więc masz najlepszy dowód, że to nie jest uniwersalne i eleganckie rozwiązanie, choć u mnie działają obydwa.

PS. Dev-cpp to nie kompilator.


(system) #8

poco static_cast skoro można bezpośrednio:

cout << (char)aPlan[0][0] << ... << endl;

(Fiołek) #9

Po co rzutowanie C-like, jak można C++-like? Czepiasz się szczegółów...


(system) #10

Poco do wróbla strzelać z dubeltówki jeżeli można z armaty?

static_cast przeznaczony jest dla bardziej skomplikowanej konwersji, owszem potrafi tez enum na char skonwertować, tylko że proszę pamiętać że static_cast jest wzorcem funkcji, czyli działa wolno, tymczasem to co uważasz za C-like (błędne przekonanie) nie wykonuje nawet jednej operacji assemblera (przynajmniej w tym przypadku).


(Sawyer47) #11

13tySmok , mylisz się. static_cast, jak sama nazwa wskazuje wykonywane jest w czasie kompilacji i działa praktycznie tak samo jak rzutowanie w starym stylu, a efekt jest ten sam, binarki są identyczne. (przynajmniej na g++) Owszem, static_cast składnią przypomina funkcję sparametryzowaną, ale jest to operator, element języka.

Poza tym ciekawi mnie do jakich bardziej skompilikowanej konwersji przeznaczone jest static_cast? Bo z tego co wiem, to do nich są const_cast, dynamic_cast i reinterpret_cast.

I wreszcie odpowiedź na pytanie "po co static_cast". Otóż rzutowanie jest złe i brzydkie i równie brzydko powinno wyglądać w kodzie. static_cast jest bardzo łatwo wyszukać w kodzie, tak jak i inne C++-owe operatory rzutowania.


(Kn0pix5) #12

Dodaję, że rzutowanie w stylu C dodaje nawiasy, przez co ciężko połapać się w kodzie.


(system) #13

np

class ca {};

class cb {};

class cab:public ca,public cb {};

cab C;

cb *pb=static_cast(&C); // pb != &C

cab *pc=static_cast(pb); // pc != pb && pc == &C

[-X

char napis[]="ala ma kota";