{{indexmenu_n>1}}
====== Lab 01 - Úvodní cvičení ======
* Seznámení s počítačovou učebnou, [[courses:b3b36prg:tutorials:services|ownCloud]] a [[https://cw.felk.cvut.cz/brute/|BRUTE]].
/* * pro vyučující: [[courses:b3b36prg:internal:tutorialinstruction:01|]] */
===== Cíle cvičení =====
- Přihlášení do operačního prostřední a nastavení vývojového prostředí.
- Vytvoření jednoduchého skriptu (posloupnosti příkazů) pro práci se soubory.
- Formátování zdrojového programu.
- Kompilace programu a spouštění programu.
- Základní datové typy, standardní vstup a výstup.
V PRG nepředepisujeme jaké [[https://cw.fel.cvut.cz/wiki/courses/b3b36prg/tutorials/start#pracovni_prostredi|pracovní vývojové prostředí používat]]. Obecně doporučujeme začínajícím programátorům použít prostředí [[courses:b3b36prg:tutorials:devel:vscode|VS Code]], případně nakonfigurovaný editor ''gedit'' nebo ''vim''. Určitě je také možné použít komplexní prostředí jako je např. CLion. Nicméně jeho konfigurace a prozkoumání všech možností, může velmi rychle překročit časovou dotaci předmětu.
===== Práce s příkazovou řádkou =====
* Procvičte si práci v [[courses:bab36prga:labs:lab01:cmd|příkazové řádce]] a vypracujete úkoly.
* Ve svém domovském adresáři si založte složku ''prg'' a složku ''lab01''.
* Ve složce ''lab01'' vytvořte soubor se jménem ''program.c''.
* Celou složku ''lab01'' přesuňte z domovského adresáře do složky ''prga''.
* Přejmenujte ''program.c'' na ''main.c''.
===== Formátování zdrojového programu =====
Klíčové nastavení editoru je pro formátování zdrojového kódu. V předmětu PRG je preferováno formátování nástrojem clang-format a nastavením stylu:
{BasedOnStyle: llvm, IndentWidth: 4, BreakBeforeBraces: Linux}
Formátování zdrojového kódu pak provedete např. následovně:
clang-format -style='{BasedOnStyle: llvm, IndentWidth: 4, BreakBeforeBraces: Linux}' muj_kod.c > formatovany_kod.c
V případě použití vývojového prostředí VS Code lze lokálně nastavit formátování vytvořením souboru ''.clang-format'', viz [[courses:b3b36prg:tutorials:devel:vscode|Programovací prostředí]].
++++ Výstup pak může například vypadat následovně. |
{{:courses:b3b36prg:labs:vscode-clangformat2.png?400|}}
{{:courses:b3b36prg:labs:vscode-clangformat.png?400|}}
{{:courses:b3b36prg:labs:vscode-clang_format10.png?400|}}
++++
++++ Nastavení formátování ''clang-format'' v ''gedit'' |
* Stáhněte si nastavení pro textový editor **gedit**: {{:courses:b3b36prg:labs:setup_gedit.zip|}}.
=== ===
wget https://cw.fel.cvut.cz/wiki/_media/courses/b3b36prg/labs/setup_gedit.zip
==== ====
* Rozbalte jej, prohlédněte obsah a nainstalujte (=spusťte).
=== ===
unzip setup_gedit.zip
cat setup_gedit.sh
gedit setup_gedit.sh
./setup_gedit.sh
==== ====
++++
===== Kompilace programu a spouštění programu =====
==== ====
// example program in C
#include
int main()
{
printf("Hello PRG!\n");
return 0;
}
==== Překlad programu ====
Překlad na spustitelný soubor provádíme z příkazové řádky příkazem
clang -Wall -pedantic -std=c99 main.c -o main
případně
gcc -Wall -pedantic -std=c99 main.c -o main
==== Spuštění programu ====
Program spouštíme z příkazové řádky příkazem
./main
=== VS Code ===
V prostředí VS Code může vypadat interaktivní práce tak, že si stáhneme soubor domácího úkolu v prohlížeči do adresáře ''~/Downloads'' a dále vše řešíme už jen z VS Code s využitím integrovaného terminálu.
{{:courses:bab36prga:labs:vscode-hw00.png?800|}}
kde můžeme též využít příložena ''Makefile'' a vytvořit si ''zip'' soubour voláním ''make zip''.
{{:courses:bab36prga:labs:vscode-hw00zip.png?800|}}
==== Úkoly ====
* Do souboru ''main.c'' napište zdrojový kód programu, který vypíše na standardní výstup **"Hello PRG!"**.
* Program zkompilujte a spusťte
* Jaká je návratová hodnota programu?
* Jak lze programy spouštět za sebou?
* Zdrojový kód zazipujte do archivu **''hw0.zip''**, například příkazem: **"''zip hw0.zip main.c''"**
* V archivu nevytvářejte žádné složky.
* Vytvořený archiv nahrajte do systému [[https://cw.felk.cvut.cz/brute/|BRUTE]], viz nebodovaný úkol HW0.
* Dále je možné využít proměnnou prostředí ''$?'' a vyzkoušet si různé návratové hodnoty programu a řetězení kompilace a spuštění programu, včetně např. podmíněného spuštění programu v závislosti na úspěchu kompilace programu.
{{:courses:bab36prga:labs:vscode-lab01-return_value.png?800|}}
===== Základní datové typy, standardní vstup a výstup =====
* základní datové typy - ''char, int, float, double''
* standardní vstup - [[http://www.tutorialspoint.com/c_standard_library/c_function_scanf.htm|scanf]] [[http://www.tutorialspoint.com/c_standard_library/c_function_getchar.htm|getchar]]
=== ===
int scanf(const char *format [, address, ...]);
int getchar(void);
===== =====
* standardní výstup - [[http://www.tutorialspoint.com/c_standard_library/c_function_printf.htm|printf]], [[http://www.cplusplus.com/reference/cstdio/fprintf/|fprintf]]
=== ===
int printf(const char *format [, arg, ...]);
int fprintf(FILE *stream, const char *format [, arg, ...]);
===== =====
* řídicí struktury - ''if''
=== ===
if( podmínka ){
příkaz1
} else {
příkaz2
}
===== =====
* řídicí struktury - '' for ''
=== ===
for( inicializace ; podmínka ; změna){
příkaz
}
===== Úkoly =====
==== Základní datové typy ====
* Zjistěte jakou velikost mají základní datové typy ''char'', ''int'', ''float'' a ''double''?
printf("Size of int: %lu\n", sizeof(int));
==== Standardní výstup ====
* Vyzkoušejte různé formy výpisu znaků a čísel formátovaným výstupem [[http://www.tutorialspoint.com/c_standard_library/c_function_printf.htm|printf]], [[http://www.cplusplus.com/reference/cstdio/fprintf/|fprintf]].
== ==
char c = 'a';
int i = 1000,j;
float x,y = 3.1415;
printf("%c\n",c);
printf("%i\n",c);
printf("%d\n",i);
printf("%+5d\n",i);
printf("%x\n",i);
printf("%f\n",y);
printf("%10.3f\n",y);
printf("\t%-g\n",y);
==== ====
* co bude výsledkem výpisu následujících příkazů?
== ==
printf("%6d,%4d",86,1040);
printf("\n");
printf("%12.5e",3.14159265);
printf("\r");
printf("%.4f\n",85.167);
==== ====
* Vyzkoušejte výpis na standardní výstup (''stdout'') a standardní chybový výstup (''stderr'') pomocí funkce ''fprintf''
== ==
fprintf(stdout,"Standardní výstup: %d",i);
fprintf(stderr,"Error výstup: %d",i);
==== ====
* Vyzkoušejte přesměrování výstupů programu do souboru
== ==
./main >output.log 2>error.log
==== Standardní vstup ====
* Vyzkoušejte načtení vstupu:
== ==
1-20.3-4.0e3
==== ====
* Příkazem:
== ==
int r = scanf("%d%d%f%f",&i,&j,&x,&y)
==== ====
* Zamyslete se nad chováním příkazu ''scanf'' na základě formátovacího řetězce.
* Vypište návratovou hodnotu ''r''.
* Vyzkoušejte načtení vstupů " 9/ 16" a " 9 / 16" pomocí formátovacího řetězce ''"%d/%d"''
* Vyzkoušejte přesměrování vstupu programu.
== ==
./main
==== Jednoduchý automat na mince ====
* Napište program, který pro zadanou částku (v celých korunách) vypíše nejmenší počet mincí (20, 10, 5, 2, 1), ze kterých se dá daná částka složit.
* Rozšiřte program tak, aby vypisoval pouze použité mince.
* Nechte program vypsat vloženou částku i v jiných měnách.
/*
===== Základní datové tipy =====
^ Typ ^ Význam, přesnost ^
| char | obvykle jeden byte (znak) pro uchování jednoho znaku |
| int | celé číslo, (obvykle 2 nebo 4 byty) |
| float | číslo v pohyblivé řádové čárce (obvykle 4 byty) |
| double | číslo v dvojnásobné přesnosti |
*/
/*
Konkrétní rozsahy pro jednotlivé datové typy jsou uvedeny v hlavičkových souborech limits.h a float.h, které jsou součástí každé implementace.
Velikost lze zjistit programově: printf("Velikost intu je %d \n", sizeof(int));
*/
/*
===== Standardní výstup - printf =====
int printf(const char *format [, arg, ...]);
* %[flags][width][.prec][h|l|L]type
* Znaky h l a L označují typ čísla. Znak h typ short (nemá smysl pro 16bitové překladače), l dlouhé celé číslo, L long double.
=== type ===
* %[flags][width][.prec][h|l|L]**type**
^ type ^ význam ^
| d, i | celé číslo se znaménkem |
| u | celé číslo bez znaménka |
| o | číslo v oktalové soustavě |
| x, X | číslo v hexadecimální soustavě |
| f | racionální číslo (float, double) bez exponentu |
| e, E | racionální číslo s exponentem, implicitně jedna pozice před desetinnou tečkou a šest za ní. Exponent uvozuje malé nebo velké E |
| g, G | racionální číslo s exponentem nebo bez něj (podle absolutní hodnoty čísla). Neobsahuje desetinnou tečku, pokud nemá desetinnou část |
| c | znak |
| s | řetězec |
=== flags ===
* %[**flags**][width][.prec][h|l|L]type
^ flag ^ význam ^
| - | výsledek je zarovnán zleva |
| + | u čísla bude vždy zobrazeno znaménko |
| mezera | u kladných čísel bude místo znaménka "+" mezera |
| # | pro o, x, X výstup jako konstanty jazyka C \\ pro e, E, f, g, G vždy zobrazí desetinnou tečku \\ pro g, G ponechá nevýznamné nuly \\ pro c, d, i, s, u nemá význam |
=== width ===
* %[flags][**width**][.prec][h|l|L]type
^ width ^ význam ^
| n | nejméně n znaků doplněných mezerami |
| 0n | nejméně n znaků doplněných nulami |
| * | nejméně n znaků, kde n je další argument funkce printf() |
=== .prec ===
* %[flags][width][**.prec**][h|l|L]type
^ .prec ^ význam ^
|.0 | pro e, E, f nezobrazí desetinnou tečku \\ pro d, i, o, u, x nastaví standardní hodnoty |
| .n | pro d, i, o, u, x minimální počet číslic \\ pro e, E, f počet desetinných číslic \\ pro g, G počet platných míst \\ pro s maximální počet znaků |
| .* | jako přesnost bude použit následující parametr funkce printf()|
===== Standardní vstup - scanf =====
int scanf(const char *format [, address, ...]);
* čte ze stdin (standard input),
* vrací počet bezchybně načtených a do paměti uložených položek.
Činnost funkce scanf při konverzi %d:
* ignoruje počáteční mezery a oddělovače řádků,
* zápis čísla musí začínat znaménkem nebo dekadickou číslicí,
* čtení skončí na prvním znaku, který není dekadickou číslicí,
* musí být přečtena alespoň jedna dekadická číslice.
=== Typy konverze ===
^ znak ^ význam ^
| d | celé číslo dekadicky se znaménkem |
| u | celé číslo dekadicky bez znaménka |
| o | celé číslo oktalově bez znaménka |
| x | celé číslo hexadecimálně bez znaménka (hex. číslice a, b, c, d, e, f) |
| X | celé číslo hexadecimálně bez znaménka (hex. číslice A, B, C, D, E, F) |
| i | celé číslo, zápis odpovídá zápisu konstanty v jazyce C, např. 0x uvozuje číslo v šestnáctkové soustavě |
| n | počet dosud přečtených znaků aktuálním voláním funkce scanf() |
| e, f, g | racionální čísla typu float, lze je modifikovat pomocí l a L |
| s | řetězec; úvodní oddělovače jsou přeskočeny, na konci je přidán znak '\0' |
| c | vstup znaku; je li určena šířka, je čten řetězec bez přeskočení oddělovačů |
| [search_set] | jako s, ale se specifikací vstupní množiny znaků, \\ je možný i interval, například %[0-9], i negace, například %[//^//a-c]. |
=== Příklad použití ===
int a, b, c, v;
a = 0, b = 0, c = 0;
printf("Zadejte tri cela cisla: \n");
v = scanf("%d%d%d", &a, &b, &c);
if (v==3)
printf("Zadana cisla jsou: \n");
else
printf("Nektere cislo bylo spatne zadane.\n");
printf("a=%d, b=%d, c=%d\n",a, b, c);
===== Řídicí struktury =====
==== Podmínka if ====
Podmínka if umožňuje větvení na základě pravdivosti zadané podmínky. Má dva tvary:
- if ( podmínka ) příkaz1 else příkaz2
- if ( podmínka ) příkaz1
Přestože lze tuto podmínku zapsat na jeden řádek volíme **vždy** zápis se složenými závorkami
if ( podmínka ) {
příkaz1
} else {
příkaz2
}
Podmínky můžeme také řetězit:
if ( podmínka1 ) {
příkaz1
} else if ( podmínka2 ) {
příkaz2
} else {
příkaz3
}
===== Tenární operátor ? =====
Tento operátor nazýváme ternárním, neboť má tři argumenty. Umožňuje zapsat úplnou podmínku stručnějším, avšak v některých případech méně přehledným způsobem, zvláště pokud je těchto operátorů vnořeno více do sebe. Jeho syntax je:
Podmínka ? Výraz1pomocí : Výraz2;
Je-li podmínka vyhodnocena jako pravdivá, bere se hodnota výraz1, v opačném případě výraz2. Podmínku
if ( a < b ) {
c = a++;
} else {
c = b++;
}
lze tedy zapsat jako
c = a < b ? a++ : b++;
*/