Forum Coders' city Strona Gwna Coders' city
Nasza pasja to programowanie!
 

 PomocPomoc   SzukajSzukaj   UytkownicyUytkownicy   GrupyGrupy  RejestracjaRejestracja 
Archiwum starego forum + teoria    RSS & Panel/SideBar
 ProfilProfil   Zaloguj si, by sprawdzi wiadomociZaloguj si, by sprawdzi wiadomoci   ZalogujZaloguj 

Potrzebuj szybkiej odpowiedzi na moje pytanie... Zasady

Cz?sto udzielane odpowiedzi

Id do strony 1, 2  Nastpny

 
Odpowiedz do tematu    Forum Coders' city Strona Gwna -> C i C++
Zobacz poprzedni temat :: Zobacz nastpny temat  
Autor Wiadomo
marcin_an



Doczy: 26 Maj 2005
Posty: 18822

PostWysany: Sro Gru 24, 2008 11:51 pm  OP    Temat postu: Cz?sto udzielane odpowiedzi Odpowiedz z cytatem Pisownia

Kiedy? mikmas stworzy? w?tek zatytu?owany "nie!", w ktrym podawa? informacje, co powinno by? opisane w po?cie, ?eby nie trzeba by?o wzywa? wr?ki. Robi? w?a?nie podobn? rzecz, ale w celu u?atwienia sobie odpowiedzi. S? odpowiedzi, ktrych udzielam cz??ciej ni? innych. Nie ma wtedy czasu na opisanie problemu dok?adnie. Czasami te? celowo pomijam pewne kwestie lub przedstawiam je w troch? innym ?wietle. S?dz?, ?e w?tek, w ktrym mo?na rozwin?c te odpowiedzi mo?e si? przyda?. Oto i on.

Zasady:
  1. W?tek b?dzie przyklejony, ?eby nie spada?.
  2. Ka?dy mo?e tuaj dopisywa? swoje odpowiedzi, je?li uzna, ?e udziela ich na tyle cz?sto, ?e opisanie ich w oddzielnym, wi?kszym po?cie mo?e by? potrzebne.
  3. To nie jest FAQ (przynajmniej nie wprost)! Chc?, by trafia?y tutaj tylko odpowiedzi, ktre faktycznie si? powtarzaj? (niezale?nie od ilo?ci pyta?) i ktrych pog??bienie mo?e by? potrzebne, a mo?liwo?? odes?ania do takiego wyja?nienia b?dzie przydatna.
  4. To nie jest oficjalne CC-FAQ. Jest to co? w rodzaju magazynu tekstw do dawania do nich odno?nikw. Tym samym ka?dy mo?e sobie tutaj umie?ci? "paczk?" wg w?asnego uznania i jej zawarto?? nie b?dzie weryfikowana w tym w?tku pod k?tem merytorycznym. Mo?esz napisa?, ?e S?o?ce kr??y wok? Ziemi* i je?li tak napiszesz, to tak b?dzie w twoim po?cie. Oczywi?cie poza tym posty s? moderowane, wi?c nie oznacza to, ?e mo?na wstawi? go?? panienk? i post b?dzie wisia? na forum.
  5. ?adnych pyta? i dyskusji w tym w?tku. Ka?de pytanie lub prb? prowadzenia rozmowy usun? bez ostrze?enia. Mo?na w tym celu za?o?y? oddzielny w?tek i tam dyskutowa?. Tutaj umieszczamy tylko rzeczy do robienia do nich linkw.
  6. Poniewa? osoby spoza zespo?u moderatorw i administracji nie maj? mo?liwo?ci usuni?cia swoich postw, mo?na da? zna? komu? z tych zespo?w, by to zrobi?. Jest to do zrobienia poprzez prywatn? wiadomo?? lub dopisanie posta z tak? pro?b?. Prosz? jednak o to, by pro?by by?y wyra?ne i dobrze opisywa?y, co ma by? usuni?te. Moderator mo?e odmwi? usuni?cia wpisu, je?li uzna, ?e naruszy?oby to tre?? postw do niego si? odnosz?cych.
  7. Jeden post - jednen temat. Nie publikujemy tutaj artyku?w o wszystkim i niczym. Poruszany temat -> odpowied?/wyja?nienie.
  8. Tym samym dozwolone jest umieszczanie kilku postw jeden pod drugim i je?eli s? to oddzielne tematy (tj. nie s? to dopiski "bo zapomnia?em napisa?"), to moderatorzy nie b?d? zwracali na to uwagi.
  9. Nie jest to miejsce na publikacj? swoich artyku?w, rozpraw etc. To mo?na zrobi? w serwisach do tego przeznaczonych.
  10. Je?eli moderator stwierdzi, ?e wpis nie jest wykorzystywany lub te? u?ytkownik wcale nie umie?ci? w nim niczego, na co musia? cz?sto odpowiada?, post mo?e zosta? usuni?ty.
  11. Go?cie nie mog? si? tutaj wypowiada?. Przepraszam, kwestie organizacyjne ;).
____
* Co akurat jest prawd?...

_________________
Nieaktywny od 2017-04-01


Ostatnio zmieniony przez marcin_an dnia Czw Gru 25, 2008 12:02 am, w caoci zmieniany 1 raz
Powrt do gry
Zobacz profil autora Wylij prywatn wiadomo
marcin_an



Doczy: 26 Maj 2005
Posty: 18822

PostWysany: Sro Gru 24, 2008 11:51 pm  OP    Temat postu: [] Zwracanie warto?ci z main Odpowiedz z cytatem Pisownia

Zwracanie warto?ci z main
Tagi: C++
Q
Czy main musi zwraca? warto??? Czy prawid?owy jest kod:
Kod:
int main() {}


A
Z punktu widzenia j?zyka: tak, prawid?owy. Tak w sensie sk?adni, jak i zwracanych warto?ci. C++ wymaga, by w przypadku braku istnienia jawnego zwracania warto?ci z main zosta?a zwrcona warto?? 0. Powy?szy kod jest zatem rwnowa?ny:
Kod:
int main()
{
    return 0;
}

W czym wi?c problem?
  • main nie zawsze b?dzie g?wn? funkcj? programu lub te? to, co zdefiniujemy jako main, niekoniecznie musi by? widziane przez kompiltor jako main. Przyk?ady: WinMain w Windowsie lub SDL_main podstawiany zamiast main w SDL.
  • Zasada o automatycznym zwrceniu 0 dzia?a tylko, je?li w main nie ma ?adnego jawnego zwrcenia.
    Kod:
    int main()
    {
        if (warunek)
        {
            return 1;
        }
    }

    Powy?szy kod nie zwrci automatycznie 0 w przypadku, gdy warunek da false, poniewa? gdzie? w kodzie main ju? co? jest zwracane (nie ma znaczenia, czy jest to osi?galne, czy nie). Problem? Wbrew pozorom przy wielu edycjach funkcji okazuje si?, ?e nietrudno zgubi? to return na ko?cu, je?li od pocz?tku go tam nie by?o (nawet je?li teraz wydaje si? to niedorzeczne).
  • Pocz?tkuj?cy: jeden z cz?stych b??dw osb zaczynaj?cych przygod? z programowaniem jest nie?wiadome pomijanie warto?ci zwracanych przez funkcj? np. przy wyst?pieniu sytuacji alternatywnych. Uczenie, ?e mo?na od tak sobie co? pomin??, chyba nie wp?ywa pozytywnie na zmian? tego - lepiej niech ucz?cy si? my?li, co ma zwrci? i niech to zwraca.


--- edit 27.12.2009 22:20 ---
Pojawi?y si? pewne niejasno?ci, zatem wyja?niam. Interpretacja z punktu 2 jest jedn? z dwch interpretacji. Druga mwi, ?e automatyczne zwrcenie zadzia?a zawsze. Problem z ni? polega na tym, ?e przy takim uj?ciu warunek "without encountering a return statement" jest co najmniej g?upi. Mo?liwe, ?e jest to defekt standardu, ale narazie nie by? jako taki zg?aszany, w najnowszym szkicu nadal wyst?puje, a sama interpretacja jest bezpieczniejsza - w t? stron? nie zepsuje si? ?adnego programu, a w przeciwn? ju? mo?na. Z tych powodw oraz dlatego, ?e cz??ciej si? z ni? spotyka?em, podaj? t?.

Bo profesor tak wymaga: je?li profesor b?dzie wymaga?, ?eby podczas pisania kodu chodzi? po ?cianach, to student ma obowi?zek chodzi? po ?cianach, bo inaczej nie zaliczy. Podane informacje dotycz? normalnych sytuacji. Profesorowi pisz jak profesor chce.

_________________
Nieaktywny od 2017-04-01


Ostatnio zmieniony przez marcin_an dnia Nie Gru 27, 2009 10:26 pm, w caoci zmieniany 3 razy
Powrt do gry
Zobacz profil autora Wylij prywatn wiadomo
marcin_an



Doczy: 26 Maj 2005
Posty: 18822

PostWysany: Sro Gru 24, 2008 11:53 pm  OP    Temat postu: Wypychanie danych ze strumieni Odpowiedz z cytatem Pisownia

Wypychanie danych ze strumieni
Tagi: C++
Q
Co robi std::endl i dlaczego jego stosowanie jest z?e?
A
std::endl nie jest z?y i jego stosowanie rwnie? z?e nie jest. Jest wr?cz bardzo przydatne. Jest jednak jeden istotny warunek: jest stosowane do tego, do czego s?u?y. Dosta?e? informacj?, ?e niepotrzebnie wypychasz dane ze strumienia lub w twoim programie pojawiaj? si? konstrukcje podobne do tych?
Kod:
cout << "ala ma kota" << endl;
Kod:
cout << "x = " << x << endl;
cout << endl << endl << endl;
Je?eli tak, to prawdopodobnie pad?e? ofiar? nauczania, ?e endl s?u?y do robienia znakw nowej linii w "stylu C++" (czymkolwiek to jest...). Nie b?d? si? tutaj rozpisywa? o ?rd?ach takiego przekonania, ale jedno mog? powiedzie? natychmiast: jest to bzdura. Nie wierzysz? Zajrzyj do dobrej dokumentacji i sprawd?, jakie jest znaczenie tego manipulatora. Jest nim wypychanie danych ze strumienia, podobnie jak manipulatora std::flush. R?nica pomi?dzy nimi polega na tym, ?e std::endl dodatkowo wyprowadza przed wypchni?ciem danych znak nowej linii. Co powoduje wypchni?cie danych ze strumienia? 1001 rzeczy w zale?no?ci od rodzaju strumienia - generalnie zapewnia, ?e dane b?d?ce w wewn?trznych buforach implementacji zostan? w tym w?a?nie momencie wypchni?te z nich do miejsca, do ktrego prowadzi strumie?. Np. do pliku na dysku, na terminal lub do sieci. Co robi w przypadku cout? Teoretycznie zapewnia, ?e... <blablabla>. Szczerze? W praktyce absolutnie nic. Na systemach uniksowych znak nowej linii i tak powoduje opr?nienie tych buforw, na Windowsie wyj?cie jest niebuforowane. Mo?e istniej? inne implementacje, dla ktrych to dzia?a - nie mog? zaprzeczy?. Ch?tnie si? dowiem jakie.
Zatem stosujesz konstrukcj?, ktra:
  1. Jest u?yta niezgodnie ze swoim przeznaczeniem i wykonuje inn? czynno??, ni? ta, ktr? chcesz uzyska?.
  2. Wyd?u?a i komplikuje niepotrzebnie kod.
  3. Prawdopodobnie nic nie robi.
Rwnowa?ne kody b?d?ce nie mniej w "stylu C++":
Kod:
cout << "Hello world\n";
Kod:
cout << "x = " << x << "\n\n\n\n";
Je?li chcesz co?, co bardziej pasuje do czego? daj?cego si? nazwa? stylem C++, to taki kod b?dzie tego lepszym przyk?adem:
Kod:
cout << format("X = %1%\n") % x;
Tak, co? jak printf, ale daj?ce si? u?ywa?. Dost?pne w pakiecie Boost.
Kiedy u?ywa? endl? Wtedy, kiedy jest potrzebne ;). Mo?esz u?y? prostej zasady: je?eli napisa?by? jeden z poni?szych, wykonuj?cych w zasadzie to samo, kodw...
Kod:
output.put('\n').flush();
output << '\n' << flush;
..., to nale?y u?y? endl. W innych przypadkach nie nale?y.
Dlaczego widzia?e? te endl w 9 na 10 ksi??ek, dlaczego u?ywa? ich sam Stroustrup i wiele innych znanych w ?rodowisku C++ osb etc.? Moja teoria jest taka: kto? kiedy? co? takiego naklepa? w ksi??ce (mo?e nawet faktycznie mia? ku temu powd). Osoby ucz?ce si? nie maj? zwyczaju stara? si? dog??bnie zrozumie? tematu, wi?c tego typu konstrukcje (np. static_const w srand+time) maj? w swej naturze rozprzestrzenianie si? gorzej ni? wirusy komputerowe przez powtarzanie zaobserwowanego wzorca. U?ycie takiej konstrukcji nie oznacza, ?e kto? nie ma bladego poj?cia o C++. Najprawdopodobniej po prostu nigdy nie zastanawia? si? nad tym, co pisze.
Bo profesor tak wymaga: je?li profesor b?dzie wymaga?, ?eby podczas pisania kodu chodzi? po ?cianach, to student ma obowi?zek chodzi? po ?cianach, bo inaczej nie zaliczy. Podane informacje dotycz? normalnych sytuacji. Profesorowi pisz jak profesor chce.

_________________
Nieaktywny od 2017-04-01


Ostatnio zmieniony przez marcin_an dnia Czw Cze 25, 2009 6:37 am, w caoci zmieniany 3 razy
Powrt do gry
Zobacz profil autora Wylij prywatn wiadomo
marcin_an



Doczy: 26 Maj 2005
Posty: 18822

PostWysany: Sro Gru 24, 2008 11:59 pm  OP    Temat postu: Odpowiedz z cytatem Pisownia

Interfejsy konsolowe w C++
Tagi: C++, C

Uwaga: po zamianie IOStreams na stdio, a cin/cout na odpowiednie funkcje stdio, poni?sze jest prawdziwe tak?e dla C.

Q
U?ywam IOStreams. Jak wyczy?ci? konsol?? Jak przenie?? kursor na wybran? pozycj?? Jak pokolorowa? litery? Jak pobiera? klawisze bez naciskania entera? Jak sprawdzi? dane i poprosi? o ponowne ich wprowadzenie? Program mi pomija polecenia.
A
Nijak. Pradopodobnie kto? powiedzia? ci, ?e cin i cout s?u?? do pisania po ekranie i czytania z klawiatury. Nie jest to jednak prawda. IOStreams s?u?y do operowania na strumieniach i jest to ca?kiem dobra biblioteka do budowania aplikacji strumieniowych. Aplikacja strumieniowa to pude?ko z dwoma (lub wi?cej) rurami. Przez jedn? wpada ci?g danych, przed drug? wypada ci?g danych (wi?cej). Koniec. Nie ma miejsca na jak?kolwiek interakcj? z u?ytkownikiem, kolorowe interfejsy i klawiatury/ekrany. C++ nawet nie wie, co to klawiatura: sterownik konsoli, pod ktry prawdopodobnie zosta? podpi?ty strumie? danych, interpretuje dane z klawiatury i wysy?a je w postaci tekstu do strumienia. Aplikacja strumieniowa tekst ten odbiera. Sam strumie? nie ma zatem ?adnego zwi?zku z klawiatur? b?d? ekranem. Mo?e nawet nie mie? ze sterownikiem konsoli, bo strumienie mo?na zwykle przekierowa? z poziomu systemu (typowe przyk?ady: przekierowanie do pliku lub sieci). Owszem, mo?na zrobi? bardzo prosty interfejs na zasadzie "pytanie-odpowied?". Taki, ?eby wystarczy? do pokazw dzia?ania kodu albo jego debugowania w czasie laboratoriw na studiach. Nie licz jednak na to, ?e zbudujesz cokolwiek wi?cej. Nie dlatego, ?e IoStreams jest z?e, tylko dlatego, ?e to nie jest narz?dzie do robienia tego typu rzeczy. Mo?esz oczywi?cie prbowa? i przy odpowiednim nak?adzie pracy, wsp?pracy sterownika konsoli (sterowanego odpowiednimi kodami) i ew. pomocy funkcji systemowych mo?e nawet cz??? z wymienionych wcze?niej rzeczy uda ci si? uzyska?. B?dzie to jednak prba wkr?cania ?ruby m?otkiem i podobnie si? natrudzisz. Zamiast tego we? po prostu bibliotek? do obs?ugi konsoli, ktra wi?kszo?? tego za?atwi ci w jednej linijce kodu. Przyk?adem takiej biblioteki s? r?ne implementacje curses: np. pdcurses pod Windowsa lub ncurses. Je?eli korzystasz curses, to przeczytaj dobrze najpierw manual, ?eby? za chwil? nie pyta?, dlaczego je?li wyprowadzasz co? przez cout, to to potem nagle znika albo jest wyprowadzane nie tam, gdzie ustawi?e? kursor. Wskazwka: dlatego, ?e u?ywasz cout zamiast funkcji z biblioteki. W manualu s? one opisane.
Dlaczego zosta?e? ok?amany? Po raz kolejny nie chc? si? zag??bia? w histori?. W skrcie: dawno, dawno temu ?wiat wygl?da? zupe?nie inaczej, systemy by?y ubo?sze, ich API robione zupe?nie inaczej itd. Sterowanie konsol? by?o realizowane w?a?nie przez wysy?anie danych na strumie?* pomieszane z wywo?aniami funkcji systemowych. Dzisiaj mamy do tego proste biblioteki i nie ma powodu, by robi? dziwaczne konstrukcje, ktrych efekty cz?sto s? zupe?nie inne, ni? ich autor sobie wyobra?a (cz?sto wystarczy troch? inna konfiguracja nawet tego samego systemu). Nie wszyscy nauczaj?cy maj? jednak w zwyczaju aktualizowa? swoj? wiedzi? i nie dociera do nich, ?e informacje sprzed 20 lat mog? by? z lekka nie?wie?e.
Bo profesor tak wymaga: je?li profesor b?dzie wymaga?, ?eby podczas pisania kodu chodzi? po ?cianach, to student ma obowi?zek chodzi? po ?cianach, bo inaczej nie zaliczy. Podane informacje dotycz? normalnych sytuacji. Profesorowi pisz jak profesor chce.

--- edit: uzupe?nienie o uwagi dla C
--- edit: link do posta o aplikacjach strumieniowych
____
* Z technicznego punktu widzenia gdzie? na samym dole nadal cz??? funkcjonalno?ci jest tak realizowana. Jest to jednak poziom daleko poza tym, co le?y w polu zainteresowa? osoby, ktra chcia?aby po prostu napisa? u?yteczn? aplikacj?.

_________________
Nieaktywny od 2017-04-01


Ostatnio zmieniony przez marcin_an dnia Nie Lut 20, 2011 9:16 am, w caoci zmieniany 2 razy
Powrt do gry
Zobacz profil autora Wylij prywatn wiadomo
hobson



Doczy: 13 Sie 2007
Posty: 439
Skd: Trjmiasto

PostWysany: Pi Mar 06, 2009 9:24 pm      Temat postu: Znikaj?ca konsola Odpowiedz z cytatem Pisownia

Q: Napisa?em swj pierwszy program typu "Hello World", ale on nie dzia?a! Jedyne, co widz?, to migaj?ce przez chwil? czarne okienko konsoli. Co jest ?le?

Najprawdopodobniej, nic nie jest ?le. Po prostu twj program wykonuje si? tak szybko, ?e zanim zd??ysz cokolwiek zobaczy? na konsoli, funkcja main ko?czy swe dzia?anie, a konsola znika. Problem ten mo?na rozwi?za? na kilka sposobw:

  • Je?li uruchamiasz program pod kontrol? debuggera (a tak powinno by? w przypadku 99% uruchomie? podczas pisania programu), mo?esz ustawi? breakpoint na ostatniej linijce funkcji main, lub na nawiasie klamrowym zamykaj?cym t? funkcj?. Gdy program dojdzie do tego miejsca zatrzyma si?, a ty mo?esz zobaczy? wynik jego dzia?ania na konsoli.
  • Niektre ?rodowiska maj? opcj? uruchamiania programu i pozostawiania otwartej konsoli po zako?czeniu. Inne pozwalaj? na podgl?d wyj?cia programu, gdy zako?czy on swe dzia?anie. W ?rodowisku MS Visual Studio mo?na skorzysta? z opcji Run without debugging (skrt klawiszowy Ctrl + F5).
  • Gdy chcesz uruchomi? swj program poza kontrol? ?rodowiska, otwrz konsol? (np. nast?puj?cym poleceniem systemu Windows: Start/Uruchom.../cmd), przejd? do katalogu, w ktrym znajduje si? twj skompilowany program, i wpisz jego nazw? (oraz, w razie potrzeby, parametry). Gdy program zako?czy si?, konsola pozostanie otwarta, a ty b?dziesz mg? przeczyta? wszystko, co program wypisa?.
  • Je?li chcesz uruchamia? program przy pomocy dwukrotnego klikni?cia na ikonk?, mo?esz stworzy? plik wsadowy uruchamiaj?cy twj program, i zatrzymuj?cy si? przy pomocy polecenia specyficznego dla Twojej pow?oki. Albo mo?esz utworzy? skrt z ustawion? opcj? pozostawiania otwartego okna konsoli po zako?czeniu programu.


Q: Ale kto? powiedzia? mi, ?e mog? zatrzyma? program przy pomocy jakiej? linijki kodu. Czy jest to mo?liwe? Jak to zrobi??

Tak, jest to mo?liwe. Takich sposobw na zatrzymanie programu w celu powstrzymania konsoli przed znikaniem przy pomocy kodu jest kilka. Niestety, ?aden z nich nie jest idealny. Przede wszystkim, powstrzymywanie konsoli przed znikni?ciem jest w zdecydowanej wi?kszo?ci przypadkw zupe?nie bez sensu, poniewa? nie jest to sposb, w jaki powinny dzia?a? aplikacje strumieniowe (a tego typu aplikacji zazwyczaj dotyczy ten problem). Popatrz sam: czy program ipconfig zatrzymuje si? po wy?wietleniu wszystkich informacji? A polecenie dir? Je?li jednak powy?sze argumenty nie przekona?y ci?, i nadal upierasz si? przy tym, ?e powstrzymywanie konsoli przed znikaniem jest dobrym pomys?em, masz ca?kiem sporo sposobw do wyboru:


  • getch() z biblioteki conio.h - najgorszy chyba mo?liwy sposb. Wymaga do??czenia niestandardowej, przestarza?ej biblioteki. Pochodzi z czasw DOSa, dost?pna jest na przestarza?ych kompilatorach Borlanda, jej obecno?? nie jest gwarantowana w ?adnej wsp?cze?nie dostarczanej platformie.

  • system("PAUSE") - sposb jeszcze gorszy od poprzedniego. Jest ma?o efektywny, wymaga uruchomienia przez ?rodowisko dodatkowych programw, dzia?a tylko na systemach Windows (i to nie jest gwarantowane, ?e na ka?dym).

  • cin.get() z iostream oraz getchar() z stdio.h - troch? lepsze ni? poprzednie, ale nie dzia?aj? do ko?ca tak, jak by?my sobie tego ?yczyli. Przede wszystkim, s? to funkcje do obs?ugi strumieni, nie maj? zielonego poj?cia o istnieniu klawiatury i o wciskaniu klawiszy. Program, je?li jest uruchomiony w konsoli, co prawda si? zatrzyma, ale wcale nie ruszy dalej po wci?ni?ciu dowolnego przycisku. Najcz??ciej (ale nie zawsze, kolejny niepewny punkt!) dane z konsoli przesy?ane s? do strumienia dopiero po wci?ni?ciu klawisza ENTER, wi?c u?ytkownik mo?e wpisa? ca?kiem d?ugi elaborat, zanim jego program ruszy dalej. Co gorsza, wszystko, co wpisa? (nie tylko pierwszy znak), zostanie przes?ane do strumienia wej?ciowego programu, wi?c przy kolejnych prbach komunikacji z u?ytkownikiem mo?e on nie mie? mo?liwo?ci wpisania czegokolwiek, bo w strumieniu ju? b?d? dane.

  • funkcje do obs?ugi konsoli, np. z biblioteki curses - chyba najlepszy sposb na wybrni?cie z problemu, bo operuje na konsoli, czyli robi dok?adnie to, o co nam chodzi. Ale i tu tkwi haczyk: je?li zainicjalizujemy bibliotek? curses, nie mamy pewno?ci, co stanie si? ze standardowymi strumieniami podpi?tymi do konsoli. Mo?e nie stanie si? nic, a mo?e przestan? dzia?a?. Mo?e na twoim komputerze nie stanie si? nic, a na komputerze profesora przestan? dzia?a?. Najlepiej, je?li zdecydujesz si? na u?ycie funkcji do obs?ugi konsoli, zrezygnowa? ze strumieni standardowych (iostream w C++ lub stdio.h w C).

  • Sposb jedyny s?uszny: zrezygnowa? z aplikacji strumieniowej, i zast?pi? j? aplikacj? konsolow?, korzystaj?c? z odpowiednich funkcji w ka?dym miejscu programu.


Najwa?niejsz? rzecz? jest jednak przyj?cie do wiadomo?ci, ?e zatrzymanie aplikacji strumieniowej po jej wykonaniu to NIE JEST sposb, w jaki powinna ona dzia?a?.
Powrt do gry
Zobacz profil autora Wylij prywatn wiadomo Numer GG
marcin_an



Doczy: 26 Maj 2005
Posty: 18822

PostWysany: Wto Kwi 14, 2009 6:44 pm  OP    Temat postu: Odpowiedz z cytatem Pisownia

Aplikacje strumieniowe
Tagi: C++
Q
Co to jest aplikacja strumieniowa?
A
Najkrcej, ?opatologicznie i obrazowo: m?ynek z dwoma rurami. Jedn? rur? znaki wpadaj? do m?ynka, drug? wypadaj?:
  .
.
.

A

C
,--------.
| |
X -----------| M?YNEK |-----------
Q R T D > > R T A G
-----------| |----------- B
| |
`--------' U

S

.
.
.
Mwi?c bardziej formalnie: aplikacja ma na wej?ciu (rura po lewej na obrazku) ci?g znakw i wyprowadza na wyj?cie (rura po prawej na obrazku) rwnie? ci?g znakw. Aplikacja mo?e pobiera? kolejno znaki z wej?cia i kolejno wyprowadza? je na wyj?cie. W mi?dzyczasie mo?e je sobie mieli?. Na tym, dok?adnie na tym, ko?czy si? dzia?anie tej aplikacji. Nie ma praktycznie ?adnego wp?ywu ani na ?rd?o danych, ani na odbiorc? danych. Do rur mog? by? pod??czane najr?niejsze rzeczy i aplikacji nie interesuje, co tam b?dzie. Przyk?adowo mo?e to by? plik, inny program, po??czenie TCP/IP, port komputera z pod??czonym pod niego czujnikiem, mikrofon/g?o?nik, sterownik jakiego? urz?dzenia, drukarka lub nawet "nic". To tylko proste przyk?ady, nie pe?na lista! Co by jednak nie by?o, jest to zwykle poza zainteresowaniami aplikacji. Aplikacja normalnie nie ma te? wi?kszego wp?ywu na to, sk?d si? dane bior? i jak s? wysy?ane. Akceptuje po prostu to, co dostaje. Gdy uruchamiasz w shellu polecenia takie jak ls, netstat czy cat, programw tych nie interesuje, co si? dzieje z danymi, ktre wyprowadza na wyj?cie. Mo?e trafiaj? do pliku? Mo?e zosta?y wywo?ane ze skryptu, ktry przechwytuje ich wynik? Mo?e wynik trafia do grepa lub seda, ktre przetwarzaj? i filtruj? dane? Mo?e, co jest dosy? prawdopodobne do sterownika konsoli, dzi?ki czemu u?ytkownik mo?e je zobaczy?. Nie wiadomo. I to s? w?a?nie aplikacje strumieniowe: dwie rury do m?ynka. Proste, ale w odpowiednich r?kach pot??ne narz?dzie.

Praktycznie wszyscy programi?ci C++ zaczynali przygod? z tym j?zykiem w?a?nie od aplikacji strumieniowych. Niestety nikt im wcze?niej o tym nie powiedzia?, a domy?lne dzia?anie wielu systemw polegaj?ce na pod??czeniu strumieni pod sterownik konsoli nie u?atwia wcale zauwa?enia tego prostego faktu. Na dodatek niejeden ich nauczyciel nagada? bzdur, ktre tylko zaciemni?y obraz wszystkiego. Potem pojawiaj? si? pytania takie, jak trzy posty wy?ej - o konsol?. Pomimo, ?e aplikacja nie jest aplikacj? konsolow?, lecz strumieniow?.
Je?eli padnie pytanie, jak to si? zatem dzieje, ?e wpisywany w konsoli tekst trafia do programu i tekst wyprowadzany jest na ekranie, to wcale si? nie zdziwi?. Sprzeczno?ci jednak nie ma. Po prostu rury zosta?y pod??czone pod sterownik konsoli. Kolejny wielki m?ynek. Odbiera od systemu wiadomo?ci o wci?ni?ciu klawiszy, przetwarza je na znaki, ktre to znaki sobie zbiera i co jaki? czas wysy?a do rury wej?ciowej pod??czonej pod niego aplikacji. Co ile? R?nie, ale najbardziej typowe rozwi?zanie to po ka?dym napotkaniu znaku nowej linii, co jest cz?sto rwnoznaczne naci?ni?ciu entera. Czyli je?li naci?niesz kolejno klawisze: A, L, A, <spacja>, M, A, <spacja>, K, O, T, A, <enter>, 1, 2, 4, 8, 1, 2, <enter>, Q, W, E... taki sterownik konsoli wykona nast?puj?ce rzeczy:
Klawisz     Bufor sterownika        Rura wej?ciowa
---------------------------------------------------------------
"" ""
A "A" ""
L "AL" ""
A "ALA" ""
<spacja> "ALA " ""
M "ALA M" ""
A "ALA MA" ""
<spacja> "ALA MA " ""
K "ALA MA K" ""
O "ALA MA KO" ""
T "ALA MA KOT" ""
A "ALA MA KOTA" ""
<enter> -- wys?anie ------> "ALA MA KOTA\n"
1 "1" "ALA MA KOTA\n"
2 "12" "ALA MA KOTA\n"
4 "124" "ALA MA KOTA\n"
8 "1248" "ALA MA KOTA\n"
1 "12481" "ALA MA KOTA\n"
2 "124812" "ALA MA KOTA\n"
<enter> -- wys?anie -------> "ALA MA KOTA\n124812\n"
Q "Q" "ALA MA KOTA\n124812\n"
W "QW" "ALA MA KOTA\n124812\n"
E "QWE" "ALA MA KOTA\n124812\n"
Je?eli przed pierwszym naci?ni?ciem entera program b?dzie prbowa? czyta? z wej?cia, to implementacja zobaczy, ?e rura jest pusta i b?dzie czeka?a, a? co? si? w rurze pojawi. Gdy wreszcie po naci?ni?ciu entera co? si? pojawi, b?dzie to czyta?a. Potem znowu si? zablokuje, gdy rura si? opr?ni i znowu b?dzie czeka?a, a? b?dzie co? nadaj?cego si? do "zjedzenia". Z tego wynika "czekanie" aplikacji na wpisanie czego? od u?ytkownika. To nie operator >> powoduje, ?e aplikacja zatrzymuje si?, a ty mo?esz co? wpisa? i potwierdzi? to enterem. Aplikcja blokuje si?, bo czeka na dane. Dane te otrzymuje od sterownika konsoli, ktry sam je sobie zbiera. Aplikacja nie ma wi?kszego wp?ywu ani na to, sk?d te dane tak naprawd? b?d?, ani na to, jak b?d? wpisywane. Teraz rozumiesz, czemu pytanie o to, jak uniemo?liwi? wpisanie jakiego? znaku jest bez sensu? Dlatego, ?e to nie twoja aplikacja robi to czarne okienko, nie ona odczytuje wci?ni?te klawisze, nie ona wy?wietla odpowiadaj?ce im znaki przy kursorze i nie on przesuwa kursor - to wszystko robi zupe?nie inny program, ktry dopiero w pewnym momencie ju? skompletowane dane wysy?a do twojej aplikacji. Przenosz?c si? do strony, ?e si? tak wyra??, tylnej - dlaczego dane wy?wietlaj? si? na ekranie? Bo sterownik konsoli odczytuje dane z rury wylotowej. Sprawdza co to za dane, interpretuje je w razie konieczno?ci i wy?wietla. Po raz kolejny: to nie twoja aplikacja cokolwiek wy?wietla. Ona nawet nie wydaje polecenia wy?wietlenia. Jedyne co robi, to w rur? wyj?ciow? pakuje dane, ktre trafiaj? dopiero do urz?dzenia, ktre po ich analizie przeprowadza operacj? ich wy?wietlenia. Poniewa? nie twoja aplikacja cokolwiek rysuje i nie ona wy?wietla to okienko, to rwnie? pytanie o to, jak zmieni? twoj? aplikacj?, by sterowa?a tym okienkiem, s? nieporozumieniem. Twoja aplikacja nie mo?e tego zrobi? bezpo?rednio, bo to nie ona tym wszystkim zarz?dza.
W najlepszym przypadku mo?e wykorzysta? fakt, ?e sterowniki konsoli mog? u?ywa? protoko?u zawieraj?cego jakie? polecenia. Np. terminale ANSI mia?y zbir polece? pozwalaj?cy powiedzie? im (bo to nadal one wszystko kontrolowa?y), ?e maj? zmieni? kolor czcionki, przenie?? kursor czy wyczy?ci? ekran. Stosowanie takich technik ma jednak dwie istotne wady. Po pierwsze s? nieprzeno?ne. Po drugie w dzisiejszych czasach istniej? gotowe biblioteki do sterowania konsol?, w ktrych mo?na wszystko zrobi? kilkoma prostymi funkcjami zamiast zapychania kodu programu mas? brzydkich krzaczkw.

Pos?uguj?c si? jeszcze jedn? analogi?: twj program jest krow? na pastwisku. Pytanie o zmian? sposobu wprowadzania danych do programu jest rwnie sensowne, co pytanie, jak przerobi? krow?, ?eby trawa szybciej ros?a. Pytanie o zmian? sposobu wy?wietlania danych z programu jest rwnie sensowne, co pytanie, jak przerobi? krow?, ?eby pan Jzio przyje?d?a? po jej odchody w poniedzia?ki, a nie ?rody. Oczywi?cie mu?ki nie zmienisz. Krowa zawsze b?dzie jedn? stron? pobiera?a zielone dane wej?ciowe, a drug? stron? wyrzuca?a plackowate dane wyj?ciowe, bo taki jest jej ?ywot (jak zreszt? ka?dego wi?kszego ?ywego stworzenia).

_________________
Nieaktywny od 2017-04-01
Powrt do gry
Zobacz profil autora Wylij prywatn wiadomo
hobson



Doczy: 13 Sie 2007
Posty: 439
Skd: Trjmiasto

PostWysany: Sro Kwi 15, 2009 11:55 am      Temat postu: Tablice dwuwymiarowe Odpowiedz z cytatem Pisownia

Q: Jak zrobi? dynamiczn? tablic? dwuwymiarow? (macierz)?

W C++ nie istniej? gotowe klasy reprezentuj?ce dwuwymiarowe dynamiczne tablice, lub macierze w sensie matematycznym. Biblioteka standardowa zawiera jednak kilka elementw, ktre wspomagaj? utworzenie tego typu rzeczy. Je?li musisz zrobi? tak? tablic?, mo?esz pos?u?y? si? kilkoma sposobami

Za?o?enia:
  • Przyk?ady poni?ej u?ywaj? kodu C++, aby ich u?y? w C niezb?dne s? pewne przerbki.
  • Obs?uga b??dw w poni?szych prbkach kodu to jedynie przyk?ady, mo?na je dostosowa? do w?asnych okoliczno?ci.
  • Terminy 'macierz' i 'tablica dwuwymiarowa' u?ywane s? przemiennie, nie oznaczaj? one 'macierzy liczb' czy te? 'tablic obiektw'.


1. U?ycie kontenerw dostarczanych przez bibliotek? standardow?.

Jest to w wi?kszo?ci przy padkw najlepszy sposb na realizacj? tego zadania. Do jego g?wnych zalet nale?y fakt, ?e kontenery automatycznie zarz?dzaj? pami?ci?, i nie trzeba po nich sprz?ta?. Ilo?? potrzebnego do napisania kodu spada, trudniej pope?ni? b??d, i nie trzeba si? przejmowa? zwalnianiem pami?ci. W bibliotece standardowej istnieje spora gama kontenerw do wyboru, w razie potrzeby prac? ka?dego z nich mo?na sterowa? przy pomocy w?asnego alokatora. W wi?kszo?ci zastosowa? dobrym wyborem b?dzie szablon std::vector. Ale je?li np. spodziewasz si?, ?e twoje macierze b?d? wykorzystywane w operacjach arytmetycznych, jako kontenera mo?esz u?y? klasy std::valarray, ktra implementuje kilka podstawowych operacji na tablicach liczb:

Kod:

    //z uzyciem std::valarray
    {
        typedef std::valarray<int> Wiersz;
        typedef std::valarray<Wiersz> Macierz;

        Macierz macierz(Wiersz(kolumny), wiersze);
        
        for(size_t i=0; i < wiersze; ++i) {
            for(size_t j=0; j < kolumny; ++j) {
                macierz[i][j] = i;
            }
        }
    }

    //z uzyciem std::vector

    {
        typedef std::vector<int> Wiersz;
        typedef std::vector<Wiersz> Macierz;

        Macierz macierz(wiersze, Wiersz(kolumny));
        
        for(size_t i=0; i < wiersze; ++i) {
            for(size_t j=0; j < kolumny; ++j) {
                macierz[i][j] = i;
            }
        }
    }



W razie potrzeby, po niewielkich modyfikacjach, mo?liwe jest przekszta?cenie powy?szego kodu w taki sposb, aby u?ywa? wierszy o niejednakowej d?ugo?ci (tzw. jagged arrays). Jako dwuwymiarowej tablicy znakw do przechowywania linijek tekstu mo?esz u?y? std::vector<std::string> >.


Nie zawsze u?ycie kontenerw jest jednak mo?liwe. W j?zyku C trzeba alokowa? pami?? r?cznie. Czasami, w ramach zaj?? na uczelni, nie mo?emy korzysta? z kontenerw, poniewa? profesorowi wydaje si?, ?e C++ to takie troch? bogatsze C. W ka?dym razie, jakie by nie by?y powody, trzeba u?y? innych ?rodkw.


2. R?czna alokacja jednego du?ego fragmentu pami?ci.

W tej metodzie alokowana jest od razu pami?? na ca?? macierz, a potem wska?niki na fragmenty tego obszaru zapisywane s? do tablicy wierszy:

Kod:

    {
        int* dane = NULL;
        int** macierz = NULL;

        try {
            //alokacja
            dane = new int[wiersze * kolumny];        
            macierz = new int* [wiersze];

            for(size_t i =0; i < wiersze; ++i) {
                macierz[i] = dane + i * kolumny;
            }

            //operacje na macierzy...
            for(size_t i=0; i < wiersze; ++i) {
                for(size_t j=0; j < kolumny; ++j) {
                    macierz[i][j] = i;
                }
            }

            //zwolnienie pamieci
            delete[] macierz;
            delete[] dane;

        } catch(const bad_alloc& ) {

            //gdyby nastapil blad alokacji
            delete[] macierz;
            macierz = NULL;

            delete[] dane;
            dane = NULL;
        }
    }



U?ycie tej metody poci?ga za sob? wszystkie uci??liwe aspekty r?cznego zarz?dzania pami?ci?. Trzeba pami?ta? o zwolnieniu zaalokowanych tablic, zarwno w sytuacji, gdy wszystko idzie dobrze, jak i w chwili wyst?pienia b??dw.

Metoda ta u?ywa tylko dwch dynamicznych alokacji pami?ci, co sprawia, ?e powinna by? nieco wydajniejsza od trywialnego alokowania ka?dego wiersza z osobna, a sprz?tanie jest wiele ?atwiejsze, poniewa? nie trzeba ?ledzi?, ktre tablice ju? zosta?y zaalokowane, a ktre jeszcze nie. Jednak w przypadku bardzo du?ych tablic mo?e si? ona okaza? zawodna, poniewa? w systemie mo?e nie by? mo?liwe odnalezienie dostatecznie du?ego obszaru pami?ci (jest podatna na fragmentacj? pami?ci). W wi?kszo?ci zastosowa? jest to jednak ma?o prawdopodobne. U?ywaj?c tego sposobu nieco trudniejsze jest utworzenie tablicy o niejednakowej d?ugo?ci wierszy.


3. Alokacja wiersz po wierszu

W tej metodzie najpierw alokowana jest tablica wska?nikw na ka?dy z wierszy macierzy, a potem ka?dy wiersz jest alokowany z osobna:

Kod:

    {
        int** macierz = NULL;
        try {
            //alokacja
            macierz = new int* [wiersze];
            for(size_t i=0; i<wiersze; ++i) {
                macierz[i] = NULL;
            }        

            for(size_t i=0; i < wiersze; ++i) {
                macierz[i] = new int[kolumny];
            }

            //operacje na macierzy...
            for(size_t i=0; i < wiersze; ++i) {
                for(size_t j=0; j < kolumny; ++j) {
                    macierz[i][j] = i;
                }
            }

            //zwolnienie pamieci
            for(size_t i=0; i < wiersze; ++i) {
                delete[] macierz[i];
            }
            delete[] macierz;
            
        } catch(const bad_alloc& ) {

            //gdyby nastapil blad alokacji, trzeba
            //zwolnic zaalokowane do tej pory wiersze
            if(macierz) {
                for(size_t i=0; i < wiersze; ++i) {
                    delete[] macierz[i];
                    macierz[i] = NULL;
                }
                delete[] macierz;
                macierz = NULL;
            }
        }
    }



Generalnie nie jest to zbyt dobry sposb: wprowadza nadmiarow? fragmentacj? pami?ci, bardzo uci??liwe w nim jest obs?ugiwanie b??dw, a du?a ilo?? alokacji dynamicznych spowalnia prac? programu. Jego chyba jedyn? zalet? jest fakt, ?e w miar? ?atwo pozwala na tworzenie tablic o niejednorodnej d?ugo?ci wierszy.


Je?li to mo?liwe, bardzo dobrym pomys?em by by?o opakowanie ktrego? z powy?szych sposobw w klas?, i udost?pnienie przez ni? interfejsu pozwalaj?cego na dost?p do danych i wykonywanie wymaganych przez nas operacji. W przypadku r?cznej alokacji pami?ci trzeba pami?ta? oczywi?cie o konstruktorze kopiuj?cym, operatorze przypisania, i destruktorze. Jeszcze lepiej, mo?na t? klas? uczyni? szablonem, i sprawi?, aby ten sam kod nadawa? si? do tworzenia tablic dwuwymiarowych przechowuj?cych obiekty niemal dowolnego typu.

Komentarz
Powrt do gry
Zobacz profil autora Wylij prywatn wiadomo Numer GG
Quentin



Doczy: 10 Lip 2009
Posty: 193
Skd: Warszawa

PostWysany: Sro Sie 12, 2009 8:37 pm      Temat postu: Odpowiedz z cytatem Pisownia

Deklarowanie przyja?ni z szablonami

Q1: Dlaczego przy pisaniu deklaracji przyja?ni z funkcj? szablonow? musz? pisa? ostre nawiasy <> po jej nazwie ? Co by si? sta?o jakbym ich tam nie wymieni? ?

Q2: Jak mog? zaprzyja?ni? moj? klas? z ca?ym szablonem klas/funkcji ?


---------------------------------------------------------------------------------------------------------------------------------------------------------

Ad. 1

Na pocz?tek trzeba u?wiadomi? sobie, ?e nazwa funkcji wygenerowanej przez szablon to tak na prawd? nazwa + parametry w <>. Przyk?adowo takie oto wywo?anie:

Kod:
template <class typ1, class typ2>
void funkcja(typ1 arg1, typ2 arg2)
{    /* ... */    }

int main()
{
    funkcja(34, 3.0);
}


Powoduje powstanie funkcji funkcja<int, double>. Czyli jak wida? nawiasy <> przy deklaracji przyja?ni s? potrzebne - inaczej zadeklarujemy przyja?? ze zwyk?a funkcj? o takich argumentach (ktra niekoniecznie istnieje).

Jednak mo?na si? spotka? z dwoma ich wersjami:

~ friend void funkcja<>(int, double);
~ friend void funkcja<int, double>(int, double);

Formu?k? - aby to lepiej zapami?ta? - mo?na sformu?owa? sobie nast?puj?co:

Cytat:
Nazwy typw, ktre wyst?puj? w okr?g?ych nawiasach, kompilator automatycznie umie?ci w nawiasach ostrych (chyba, ?e sami je tam wymienimy)


Mo?na wi?c zapyta? - po co wi?c wymy?lono tak? d?u?sz? wersj? deklaracji przyja?ni jak przy "w??yku" drugim ?

Od czasu mo?liwo?ci pisania przy wywo?aniu funkcji szablonowej ostrych nawiasw (wcze?niej nie by?o to mo?liwe) - parametr szablonu funkcji mo?e zawiera? rwnie? takie sta?e wyra?enia, ktre wcze?niej mog?y pojawi? si? jedynie przy szablonach klas. S? to:

- warto?? ca?kowita
- adres obiektu globalnego
- adres funkcji globalnej
- adres sk?adnika statycznego klasy

Mo?na wi?c napisa? taki szablon:

Kod:
template <int nr, class typ1, class typ2>
void funkcja(typ1 arg1, typ2 arg2)
{    /* ... */    }


I zadeklarowa? z nim przyja?? w taki oto sposb:

Kod:
friend void funkcja<32>(int, double);
//LUB te?:
friend void funkcja<32, int, double>(int, double);    //(ALE - patrz regu?ka wy?ej)


Bo jak wida? parametr 1-szy nie wyst?puje na li?cie argumentw.

Mam nadziej?, ?e teraz jasne jest, jak wa?ne jest u?ycie ostrych nawiasw w deklaracji przyja?ni.

----------------------------------------------------------------------------------------------------------------------------------------

Ad. 2

1. Przyja?? z ca?ym szablonem funkcji:

~ W zwyk?ej klasie:

Kod:
class klasa
{
    //...
    template <class typ>
    friend void fun(typ cos);
};


~ W klasie szablonowej:

Kod:
template <class X, class Y>
class klasa
{
    //...
    template <class XX, class YY>
    //Wa?ne, ?eby nie by?y to takie same
    //parametry jak tej klasy 'klasa' !!!
    friend void fun(XX cos1, YY cos2);
};


O r?nicy parametrw trzeba zapami?ta? - w tym miejscu najwi?cej pocz?tkuj?cych robi zazwyczaj b??dy.

2. Przyja?? z ca?ym szablonem klas:

~ W zwyk?ej klasie:

Kod:
class klasa
{
    //...
    template <class typ>
    friend class klasa_zaprzyjaz;
};


~ W klasie szablonowej:

Kod:
template <class X, class Y>
class klasa
{
    //...
    template <class XX, class YY>
    //Wa?ne, ?eby nie by?y to takie same
    //parametry jak tej klasy 'klasa' !!!
    friend class klasa_zaprzyjaz;
};



---------------------------------------------------------------------------------------------------------------------------------------------------------

W za??czniku znajduje si? plik PDF, ktry podsumowuje ca?y mj post - mo?e si? przyda :-)

Je?eli masz jakie? pytania, sugestie - napisz PW.



Deklaracje przyja?ni z szablonami.pdf
 Opis:
Plik PDF, ktry zawiera wskazwki co do deklaracji przyja?ni z szablonami.

Pobierz
 Nazwa pliku:  Deklaracje przyja?ni z szablonami.pdf
 Wielko pliku:  686.92 KB
 Pobierano:  698 raz(y)

Powrt do gry
Zobacz profil autora Wylij prywatn wiadomo Wylij email
marcin_an



Doczy: 26 Maj 2005
Posty: 18822

PostWysany: Sro Wrz 16, 2009 2:41 am  OP    Temat postu: Odpowiedz z cytatem Pisownia

U?ywanie using w nag?wkach
Tagi: C++
Q
Czy prawid?owy jest kod z nag?wka:
Kod:
#ifndef FUN_INCLUDED__
#define FUN_INCLUDED__

#include <iostream>

namespace x
{
    using namespace std;
    
    inline void fun()
    {
        cout << "Ala ma kota\n";
    }
}

#endif


A
Sam plik - w oddzieleniu od innych plikw, jego u?ycia oraz utrzymania - tak, nie zawiera b??dw sk?adniowych. W praktyce jednak linia 8 jest proszeniem si? o k?opoty i nigdy nie powinna by?a si? pojawi?.

Proste pytanie: co definiuje/deklaruje ten nag?wek w przestrzeni nazw x? Wbrew pozorom nie tylko x::fun. Wprowadza on tak?e co najmniej osiem deklaracji obiektw: x::cin, x::cout, x::cerr, x::clog itd., a znaj?c faktyczny sposb implementacji nag?wkw: tak?e dziesi?tki innych deklaracji, cz?sto nawet nieudokumentowanych "wewn?trznych ?mieci" implementacji biblioteki. Czy faktycznie chcia?e?, aby to wszystko znalaz?o si? w x? Nie s?dz?. using u?yty w ten sposb w celu skrcenia sobie pisania jest z?y g?wnie dlatego, ?e powoduje za?miecenie przestrzeni nazw rzeczami, ktre nigdy nie mia?y si? tam znale??.

Nale?y te? pami?ta? o tym, ?e dyrektywa include powoduje do??czenie zawarto?ci (tekstu) wskazanego pliku. Je?eli do??czymy nag?wek z nieodpowiednio u?ytym using, to w efekcie nasze using mo?e trafi? przed inne nag?wki do??czane po tym. To jest samo w sobie b??dem, a w szczeglnych sytuacjach mo?e spowodowa? b??dn? interpretacj? kolejnych nag?wkw.

Skutkiem mog? by? te? trudne do zlokalizowania b??dy. Przeanalizuj sobie taki kod:
Kod:
namespace ns
{
    class X;
}

using namespace ns;

class X;

void test()
{
    X* x; // B??d, kompilator nie wie, o ktr? klas? `X` chodzi!
}

X* x; // To samo...

O sytuacj? tak? wbrew pozorom nietrudno, a ?eby by?o zabawniej, np. g++ w drugim przypadku daje komunikat, z ktrego trudno wywnioskowa?, co si? sta?o.

Gdzie zatem mo?na stosowa? using w nag?wkach? We wszystkich zakresach, ktrych zawarto?? nigdy nie b?dzie osi?galna przez u?ytkownika. S? nimi oczywi?cie implementacje funkcji:
Kod:
inline void fun()
{
    using namespace std;
    cout << "Ala ma kota\n";
}
Tak, ten kod jest prawie (patrz ni?ej) poprawny. Ponadto mo?na sobie stworzy? "prywatn?" przestrze? nazw, ktra zgodnie z dokumentacj? b?dzie zastrze?ona dla implementacji biblioteki. W niej mo?na robi? w zasadzie co si? chce. Je?eli kto? si? do niej odwo?a, to sam sobie robi problemy - nie s? one wynikiem zaniedbania autora nag?wka.

Wcze?niej napisa?em, ?e ostatni kod jest "prawie poprawny". Nadal jest jednak podatny na ostatni z wymienionych problemw. Cz?sto niezalecane jest w ogle u?ywanie konstrukcji using namespace, je?li nie jest to dok?adnie to, co chcemy zrobi?. Lepszym rozwi?zaniem jest zwykle importowanie poszczeglnych nazw, czyli w tym przypadku lepszym by?oby: using std::cout;. W ten sposb wiemy, co dok?adnie ?ci?gamy do swojego kodu.

Kiedy using poza wymienionymi wy?ej przypadkami mo?e wyst?pi? w nag?wku? Wtedy, gdy faktycznie chcemy, by dane deklaracje znalaz?y si? we wskazanym miejscu. Nie jest to cz?ste, czasami jest problemotwrcze, ale samo w sobie nie jest jeszcze b??dem.

Bo profesor tak wymaga: je?li profesor b?dzie wymaga?, ?eby podczas pisania kodu chodzi? po ?cianach, to student ma obowi?zek chodzi? po ?cianach, bo inaczej nie zaliczy. Podane informacje dotycz? normalnych sytuacji. Profesorowi pisz jak profesor chce.

_________________
Nieaktywny od 2017-04-01
Powrt do gry
Zobacz profil autora Wylij prywatn wiadomo
hobson



Doczy: 13 Sie 2007
Posty: 439
Skd: Trjmiasto

PostWysany: Pon Gru 07, 2009 3:12 pm      Temat postu: Odpowiedz z cytatem Pisownia

Q: Gdy u?ytkownik poda nieprawid?owe dane wej?ciowe, na przyk?ad litery zamiast liczby, program wpada w niesko?czon? p?tl?. Jak temu zapobiec?
http://www.parashift.com/c++-faq-lite/input-output.html#faq-15.2
http://www.parashift.com/c++-faq-lite/input-output.html#faq-15.3

Q: Czemu mj program ignoruje wywo?ania getline lub inne ??dania pobrania danych z wej?cia?
http://www.parashift.com/c++-faq-lite/input-output.html#faq-15.6

Q: Czemu mj program dwa razy przetwarza ostatni? porcj? danych wej?ciowych?
http://www.parashift.com/c++-faq-lite/input-output.html#faq-15.5
Powrt do gry
Zobacz profil autora Wylij prywatn wiadomo Numer GG
Wywietl posty z ostatnich:   
Odpowiedz do tematu    Forum Coders' city Strona Gwna -> C i C++ Wszystkie czasy w strefie CET (Europa)
Id do strony 1, 2  Nastpny
Strona 1 z 2

 
Skocz do:  
Moesz pisa nowe tematy
Moesz odpowiada w tematach
Nie moesz zmienia swoich postw
Nie moesz usuwa swoich postw
Nie moesz gosowa w ankietach
Moesz dodawa zaczniki na tym forum
Moesz pobiera pliki z tego forum




Debug: strone wygenerowano w 0.22832 sekund, zapytan = 14
contact

| Darmowe programy i porady Jelcyna | Tansze zakupy w Helionie | MS Office Blog |