Diskuze: Hra Hankgman v céčku
V předchozím kvízu, Online test znalostí C++, jsme si ověřili nabyté zkušenosti z kurzu.

Tvůrce

Zobrazeno 23 zpráv z 23.
//= Settings::TRACKING_CODE_B ?> //= Settings::TRACKING_CODE ?>
V předchozím kvízu, Online test znalostí C++, jsme si ověřili nabyté zkušenosti z kurzu.
Dám sem svoje funkčné riešenie. Ak to bude niekoho zaujímať, kľudne napíšte čo je špatne, budem len rád. Takýmito zadaniami sa učím.
Neviem ako sem dať ten kód, možno takto: http://www.itnetwork.cz/dev-lighter/368
Je tam velká spousta chyb, za všechny se můžeme podívat na funkci getAvailableLetters():
void getAvailableLetters(char lettersGuessed[], char availableLetters[])
{
int i, j = 0;
// to ma byt konstantni staticka promenna mimo funkci
char *najdi, abcd[] = "abcdefghijklmnopqrstuvwxyz";
// proc??
// dynamicka alokace je zbytecna a navic to je memleak
najdi = (char *) malloc(15);
// strlen() se bude vyhodnocovat pro kazde pismeno znovu
for (i = 0; i < strlen(abcd); i++){
najdi = strchr(lettersGuessed, abcd[i]);
// a) kdyz otocis podminku, nemusis mit vubec else vetev
// b) v C staci napsat if (!najdi) nebo if (najdi)
if (najdi != NULL)
continue;
else {
availableLetters[j++] = abcd[i];
}
}
availableLetters[j] = '\0';
// funkce getX() urcite nema nic vypisovat!
printf("%s", availableLetters);
}
V C platí, že co je malé, to je hezké. Pracuj s pointry a snaž se zkrátit kód. Když tvoje řešení přepracuju, měl by v C-čkový zdroják vypadat takhle:
static const char alphabet[] = "abcdefghijklmnopqrstuvwxyz";
void getAvailableLetters(char lettersGuessed[], char availableLetters[])
{
const char *pa = alphabet;
do {
if (!*pa || !strchr(lettersGuessed, *pa))
*availableLetters++ = *pa;
} while (*pa++);
}
A také se snaž držet jednoho jazyka a nemíchej C s angličtinou a slovenštinou.
Viem, že práca s pointermi je základ, ale ešte nie som tak ďaleko, aby
som to zvládal na tvojej úrovni.
Aj napriek tomu mám nejaké otázky.
Toto
static const char alphabet[] = "abcdefghijklmnopqrstuvwxyz";
je globálna premenná? Ak áno, nie je splnená podmienka úlohy (každá
globálna premenná znamená minus v hodnotení).
Navyše vypisovat sa má aj položka: Available letters takto obr.1, ale po
použití tvojho (ináč veľmi pekného) kódu to tam chýba obr.2.
"alphabet" není globální proměnná, je to lokální konstanta a ve smyslu řešení úlohy zcela korektní postup.
AvailableLetters bys měl vypisovat, ale určitě ne v metodě getAvailableLetters(), tam printf() být nemá.
Díky, skúsim sa s tým ešte pohrať. Potom to sem znovu pastnem na kontrolu.
Mimochodem, já bych kód psal spíš takhle
void getAvailableLetters(char lettersGuessed[], char availableLetters[])
{
for (int i = 'a'; i <= 'z'; i++)
if (!strchr(lettersGuessed, i))
*availableLetters++ = i;
*availableLetters = 0;
}
Po ukončení funkcie ostanú dáta v pamäti?
Asi tomu nerozumiem, ale som naučený používať funkcie s návratovou hodnotou void na to, že niečo vypíšu. V tomto prípade nevypíšu nič. Ako môžem tú funkciu použiť, keď nič nevráti? Možno ostanú v pamäti dáta, ktoré môžem použiť.
availableLetters je výstupní parametr, do funkce se předá reference na (char*), takže po opuštění funkce budou data uložena tam.
Ten kód je úplne perfektný, len jedna maličkosť, aby to niekoho
nepomýlilo.
Toto
for (int i = 'a'; i <= 'z'; i++)
v čistom céčku nebude fungovať. Premenná sa musí deklarovať mimo parametrov funkcie for().
int i;
for (i = 'a'; i <= 'z'; i++)
Predsa len mám jednu otázku k tvojmu kódu:
void getAvailableLetters(char lettersGuessed[], char availableLetters[])
{
int i;
for (i = 'a'; i <= 'z'; i++)
if (!strchr(lettersGuessed, i))
*availableLetters++ = i;
*availableLetters = 0;
}
Pracujeme tam s reťazcom a ten by sa mal (vždy) ukončiť znakom '\0', ale ty tam máš
*availableLetters = 0;
Je zaujímavé, že keď dám po vykonaní funkcie vypísať reťazec availableLetters, vypíše sa v poriadku, teda ako by bol správne ukončený.
Môžeš mi to prosím vysvetliť?
Normy z roku 1999+ (c99, c11) povoluju deklaraciu v inicializacnej casti for
cyklu.
for nie je funkcia.
'\0' == 0;
Díky.
\0' == 0; => toto som nevedel
To druhé (povolenie)znamená, že keď budem kód písať napr. vo vim v
linuxe, budem to môcť použit? Pretože v Code:blocks, ktorý používam, mi
to vypisuje chybu.
Ale keď v Code:blocks píšem kód v c++, tam to funguje bez problémov.
norma AnsiC požaduje deklarace proměnných na začátku fce
norma C99 povoluje deklaraci kdekoliv
Záleží na nastavení kompilátoru, dnes většina umí obě normy, mělo by stačit přepnou kompilátor do režimu C99
Pred pár dňami som to upravil, ale podľa tvojej rady som si najprv napísal testy. Len test na funkciu void hangman(char secret[]) som nedokázal napísať ani po jej napísaní.
Kvůli uživatelskému vstupu?
Udělej to následujícím způsobem. Funkce v C, která má 10-15 řádek začíná být podezřelá, funkce, která má 50 řádek je zaručeně napsaná špatně. Rozděl si hangman() na řadu menších statických funkcí a napiš si testy na ně. hangman() pak bude obsahovat jednoduchý cyklus, ze kterého pouze volá ostatní funkce. Tím snížíš pravděpodobnost chyby. Navíc díky tomu, že i hangman() bude dlouhá nejvýš 10 řádků, půjde snadno odhalit chyba už od pohledu.
Díky, máš pravdu. Ja som sa striktne držal zadania a to je tá moja chyba.;)
Suhlasim, ale ak funkcia obsahuje vecsi switch, tak moze byt dost velka a zaroven stale prehladna.
Zobrazeno 23 zpráv z 23.