To getchar() nečekalo, protože ti v bufferu zbyla část řetězce po zadání čísla uživatelem, ukončená znakem \n, kterou to načetlo. Buď bys musel
vyprázdnit buffer (složitejší, ale správnější možnost), a nebo tam dát
dvě getchar() za sebou (jednodušší, zatím s tím jako začátečník vystačíš).
Příkaz
system("cls") u mě funguje, ale bash provede akorát výpis chybového hlášení, protože nezná cls. Já bych tu musel napsat
system("clear"). Ale s tím plýtváním výkonu a paměti platí totéž co u tebe. Prostě je to mytí okna v přízemí z vysunutého hasičského žebříku!
Programovací jazyk je jako Lego, z malých kostiček si vytváříš větší celky, a z těch buduješ svůj program. Céčko má ty kostičky hodně malé (proti třeba Javě), ale zase jsou mnohem variabilnější - dokázal bys postavit víc kombinací z jednotlivých atomů celé periodické tabulky, nebo několika základních molekul? Ale na druhou stranu je to v Céčku pracnější, a je potřeba toho mnohem víc umět, javovským kódovacím opicím stačí vygooglit si správnou třídu nebo metodu a tu tam plácnout, ale zkus se jich zeptat kolik registrů nebo paměti která část kódu potřebuje, nebo jaké bity ve kterém portu nastavuje, když cpou něco do periférií!

(Co je to
port?)
Ovládání vlastností obrazovky je v knihovně curses (nebo ncurses), ale její použití je dost pracné, navíc může být na různých systémech pod různým názvem. Na tu přijde čas, až si budeš potřebovat nastavovat libovolnou pozici kurzoru na obrazovce, barvy, a jiné vlastnosti textu. Zatím zkusíme použít menší kostičky, a nebudeme tam cpát obrovskou složeninu, ze kterém bysme stejně využili jen jednu malou část.
Takže nejlepší v tuhle chvíli bude udělat si vlastní funkci
cls(), pro jednoduchost jako makro, čímž využiješ schopnosti preprocesoru. V programu ti pak stačí kdekoliv napsat jen cls() a preprocesor ho ve všech případech nahradí tebou zadanou sekvencí (stejně jako u toho MAX).
Už bys měl znát pár řídících znaků, jako je
\n (newline),
\t (tabulator) nebo
\a (alarm), jeden z dalších je
\f (formfeed), který by měl způsobit vymazání obrazovky a přesunutí kurzoru do levého horního rohu. Je to synonymum pro znak s ASCII kódem 12, takže ti bude stačit zadat příkaz
putchar(12) nebo správněji
putchar('\n').
Mě to ale v Linuxu nefunguje, tady musím použít Escape kódy, pomocí kterých se terminál ovládá. Takže trochu delší příkaz
printf("\033[2J\033[H"). Obojí si na začátku programu nadefinuješ v hlavičce jako makro:
Kód: Vybrat vše
#define cls() putchar('\f') /* Windows */
/* #define cls() printf("\033[2J\033[H") Linux */
A potom už kdekoliv v programu stačí použít jen cls(), abys to nemusel vypisovat pokaždé celé ručně. Při překladu na Linuxu stačí přehodit značky komentářů a odkrýt správný řádek. Až časem pronikneš víc do tajů preprocesoru, můžeš použít i podmíněný překlad, který to za tebe udělá automaticky.
CZechBoY: Neděs ho s C++, řekl bych že je dost zmatený ze samotného Céčka, a ještě bych to maličko rozvedl:
Kód: Vybrat vše
int main(void)
{
int a,b,x,y;
a = b = 7;
printf("%d\t%d\tpocatecni stav a b\n",a,b);
x = ++a; /* nejdřív inkrementuje a pak předá hodnotu */
y = b++; /* nejdřív předá hodnotu a pak inkrementuje */
printf("%d\t%d\tziskane hodnoty x y\n",x,y);
printf("%d\t%d\tkonecny stav a b\n",a,b);
return 0;
}
Totéž samozřejmě platí i pro dekrementaci (--), vyzkoušej si to.
Jak jsem minule psal o tom zrychlování programu, všiml sis že by to testování šlo ještě víc zkrátit? Například pro číslo 100 nemá smysl počítat 2 až 99, ale úplně bude stačit 2 až 10, což je druhá odmocnina aktuálně prověřovaného čísla. Nejmenší dělitel každého neprvočísla je totiž vždy
menší nebo roven jeho druhé odmocnině!
Takže teď je čas použít tu knihovnu math.h a funkci
sqrt(). Bude to trochu složitější, protože tahle funkce pracuje s čísly double, zatímco my máme int, takže budeme muset použít
přetypování do správného formátu a zase zpátky:
Kód: Vybrat vše
#include <stdio.h>
#include <math.h>
#define MAX 100
#define cls() putchar('\f') /* Windows */
/* #define cls() printf("\033[2J\033[H") Linux */
int main()
{
int i,j,o;
cls();
printf("Prvocisla do %d\n",MAX);
for (i=2;i<MAX;++i)
{
o=(int)sqrt((double)i);
for (j=2;j<=o;++j)
if (i%j==0)
break;
if (j>o)
printf("%d\n",i);
}
return 0;
}
A další zrychlení by nastalo, kdybys oddělil zjištění sudého čísla dvojkou, a smyčku začal až od 3 a přičítal po dvou. Program se tím sice trochu prodlouží, ale zrychlí téměř na dvojnásobek. Otázka je, jestli to má smysl. U takhle jednoduchého programu, který běží jednou pouhých pár milisekund, asi ne (teď je to dobré jen k tomu aby ses to naučil poznat a napsat), ale pokud by to měla být součást většího programu, která se bude opakovat tisíckrát za sekundu, tak to bude zatraceně znatelný rozdíl
