Cvičení k 10. a 11. lekci Céčka

C a C++ Céčko Základní konstrukce C Cvičení k 10. a 11. lekci Céčka

ONEbit hosting Unicorn College Tento obsah je dostupný zdarma v rámci projektu IT lidem. Vydávání, hosting a aktualizace umožňují jeho sponzoři.

Následující 3 cvičení vám pomohou procvičit znalosti programování v C z minulých lekcí. Ve vlastním zájmu se je pokuste vyřešit sami. Pod článkem máte pro kontrolu řešení ke stažení. Ale pozor, jakmile se na něj podíváte bez vyřešení příkladů, ztrácí pro vás cvičení smysl a nic se nenaučíte :)

Pokud si opravdu nebudete vědět rady, podívejte se raději znovu do minulého tutoriálu a pokuste se na to přijít.

Jednoduchý příklad

Vytvořte program, který do konzole vykreslí šachovnici. Pro tmavá pole můžete využít mřížku "#" nebo kterýkoli jiný znak, pro světlá pole využijte mezeru.

Konzolová aplikace
# # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #

Tip: Pro vykreslení samozřejmě využijte znalosti cyklů. Pro zjištění zda je pole světlé nebo tmavé vám pomůže modulo.

Středně pokročilý příklad

Naprogramujte aplikaci, která simuluje hru piškvorky pro 2 hráče. Aplikace vykresluje hrací plochu do konzole a nechává si střídavě od hráčů zadávat souřadnice, na které pokládají své kameny. Kontrolu výhry můžete zanedbat, uživatelské vstupy ošetřete.

K reprezentaci hrací plochy využijte vícerozměrného pole.

Ukázka programu:

Konzolová aplikace
ABCDEFGH 1 2 3 4 X 5 6 7 8 Zadejte horizontalni souradnici (A-H): D Zadejte vertikalni souradnici (1-8): 5 ABCDEFGH 1 2 3 4 X 5 O 6 7 8 Zadejte horizontalni souradnici (A-H): K Zadejte vertikalni souradnici (1-8): 3 Hodnoty nejsou validni, prosim opakujte akci

Pokročilý příklad

Pomocí goniometrické funkce sinus vykreslete do konzole jednu periodu sinusoidy (grafu této funkce).

Nápověda: Protože je vypisování pouze jednosměrné (co napíšeme již nelze vzít zpět) a lineární (musíme zapisovat znaky, jak jdou po sobě), používá se u úloh podobného typu tzv. buffer. Buffer je pole znaků v paměti, kde si připravíme jak chceme obrazovku vykreslit a teprve až je vše jak potřebujeme, vykreslíme vše naráz. V tomto případě si vytvoříme buffer podle rozměrů, které si nastavíme (bude se jednat o 2D pole). Do tohoto bufferu zaneseme jednotlivé body sinu. Až budeme mít celý výpočet hotový, teprve poté celý buffer vykreslíme do konzole.

Ukázka programu:

Konzolová aplikace
######### #### #### ### ### ## ## ## ### ## ## ## ## ## ## ## ## # ## ## ### ## ## ### ## ## ### ## ## ### #### #### #########

Tip: Perioda funkce sinus je 2 PI. Začněte vykreslením této křivky v poměru 1:1, sice bude malá, ale bude v konzoli vidět. Abyste dosáhli výsledku jako na obrázku, musíte ji pronásobit poměrem rozměrů konzole a hodnotou funkce sinus. Sinusoida se poté roztáhne. Jednotlivé souřadnice bodů vypočítávejte v desetinných číslech, výsledné souřadnice teprve zaokrouhlíte na celé znaky.


 

Stáhnout

Staženo 65x (98.81 kB)
Aplikace je včetně zdrojových kódů v jazyce c

 

 

Článek pro vás napsal patrik.valkovic
Avatar
Jak se ti líbí článek?
Ještě nikdo nehodnotil, buď první!
Věnuji se programování v C++ a C#. Kromě toho také programuji v PHP (Nette) a JavaScriptu.
Miniatura
Předchozí článek
Matematické funkce v jazyce C
Miniatura
Všechny články v sekci
Základní konstrukce jazyka C
Miniatura
Následující článek
Funkce v jazyce C
Aktivity (5)

 

 

Komentáře

Avatar
Mate
Člen
Avatar
Mate:25.7.2016 16:11

Dobrý den,

řešení středně těžkého příkladu, které tu máte ke stažení není správně. Nefunguje zadávání do sloupce H.

Tak není ošetřeno zadávání malých písmen (to ale není součástí zadání).

 
Odpovědět 25.7.2016 16:11
Avatar
patrik.valkovic
Šéfredaktor
Avatar
Odpovídá na Mate
patrik.valkovic:25.7.2016 19:03

Chybělo rovnítko, mělo by to být opraveno.

Odpovědět 25.7.2016 19:03
Nikdy neumíme dost na to, abychom se nemohli něco nového naučit.
Avatar
Johny
Člen
Avatar
Johny:12. ledna 13:38

Dobrý den,

prosím o kritiku k mému kodu.

krok = (2*M_PI)/(double)SIRKA;     // vypocet kroku pro inkrementaci pred vypoctem funkce SIN

      for(i=0; i<SIRKA; i++){
               hodnota = sin(i*krok);
               j = (int)trunc((hodnota*10));
               if(j>0)
               {
                       j = 10 - j;
                      buffer[i][j] = '#';
               }
               else if(j<=0){
                       j = (((-1)*j) + 9);
                       buffer[i][j] = '#';
                       }

               printf("%d = %2.2f\t", j, (hodnota*10));
               if(i%5 == 0)printf("\n");

      }

Děkuji :-)

 
Odpovědět 12. ledna 13:38
Avatar
DarkCoder
Člen
Avatar
Odpovídá na Johny
DarkCoder:12. ledna 21:52
  1. opakující se výpočet výrazu v závorce, lepší zařadit koeficient násobení 10 do výpočtu proměnné hodnota
  2. trunc není nejšťastnější, lepší je použit round
  3. if za else je zbytečné, stačí else
  4. tentýž příkaz v obou podmínkách je lepší zařadit za tyto podmínky
  5. pro testy na nulu je lepší užívat operátor negace !
 
Odpovědět 12. ledna 21:52
Avatar
Johny
Člen
Avatar
Johny:19. ledna 20:17

Super, jen by jsem poprosil o vysvětlení těchto věcí,
přesně nerozumím důvodu proč by to tak mělo být.

  1. z jakého důvodu je to lepší. Kvůli té závorky navíc?
  2. tady by jsem poprosil jestli by jsi to mohl trošku rozebrat?

A to jak jsem řešil zapisování do bufferu je ok?
Nějaký návrh jak přeindexovat pole aby jsem měl nulu uprostřed ?

Ještě jednou moc díky.

Editováno 19. ledna 20:17
 
Odpovědět 19. ledna 20:17
Avatar
DarkCoder
Člen
Avatar
Odpovídá na Johny
DarkCoder:20. ledna 0:17
  1. Úspora procesorového času a efektivnost. V tomto příkladu to zase až tak důležité není, počet opakování a složitost výpočtu zde není až tak veliká, ale můžeš se setkat s řešením něčeho kde to důležité bude. Dost často se z důvodu efektivnosti jako řídící proměnná cyklu namísto klasické používá proměnná s přídavkem registr. To že tam je závorka navíc, nevadí. Lepší navíc než když někde chybí. Jedno pravidlo praví - když si nejsi jistý - závorkuj!
  2. Důvodem je rozptyl a tedy nepřesnost při zaokrouhlování.

Máš-li hodnoty 5.2, 5.5, 5.8, -5.2, -5.5. -5.8 pak výsledkem funkce round jsou hodnoty 5, 6, 6, -5, -6, -6.
Máš-li hodnoty 5.2, 5.5, 5.8, -5.2, -5.5, -5.8 pak výsledkem funkce trunc jsou hodnoty 5, 5, 5, -5, -5, -5.
Zejména u hodnot 5.8 a -5.8 vykazuje výsledek vyšší nepřesnost u funkce trunc než za použití funkce round.

Pokud je buffer deklarován jako dvourozměrné pole znaků s dostatečně velkými indexy, pak příkaz přiřazení znaku do tohoto pole je zcela korektní.

Když se podíváš, jakých mezních hodnot sinusoida dosahuje (-1, 1) pak můžeš stanovit pozici vykreslování podle vztahu: pozice = round (K * (1 - sinus(alfa))) kde K je hodnota pozice odpovídající polovině výšky obrazovky.

 
Odpovědět  +1 20. ledna 0:17
Avatar
Johny
Člen
Avatar
Odpovídá na DarkCoder
Johny:20. ledna 7:57

Mockrát děkuji za vyčerpávající odpovědi :-)

 
Odpovědět 20. ledna 7:57
Děláme co je v našich silách, aby byly zdejší diskuze co nejkvalitnější. Proto do nich také mohou přispívat pouze registrovaní členové. Pro zapojení do diskuze se přihlas. Pokud ještě nemáš účet, zaregistruj se, je to zdarma.

Zobrazeno 7 zpráv z 7.