Programovací jazyk C3: podmínky, rozvětvení a programové smyčky

30. 9. 2025
Doba čtení: 33 minut

Sdílet

Programovací jazyk C3
Autor: Root.cz s využitím Zoner AI
Seznámíme se s konstrukcemi pro řízení běhu programu. Jedná se o podmínky a různé formy rozvětvení (včetně rozšířené sémantiky switch-case) a dále o různé typy smyček. Jazyk C3 v tomto ohledu značně vylepšuje možnosti céčka.

Obsah

1. Programovací jazyk C3: podmínky, rozvětvení a programové smyčky

2. Rozvětvení běhu programu založené na konstrukcích if a if-else

3. Porovnání s jazykem C: nekorektní způsoby zápisu konstrukce if-else

4. Složitější rozvětvení založené na konstrukci if-else if-else

5. Základní forma rozvětvení založeného na konstrukci switch-case

6. Větší množství podmínek a konstrukce switch-case

7. Podmínky v konstrukci switch-case vyhodnocované v čase běhu procesu

8. Konstrukce switch-case a příkaz break

9. Klíčové slovo nextcase v programové konstrukci switch-case

10. Základní forma počítané programové smyčky for

11. Průchod polem či jinou sekvencí smyčkou typu foreach

12. Průchod polem smyčkou foreach se získáním indexu i prvku v každé iteraci

13. Modifikace prvků pole při jeho průchodu smyčkou foreach

14. Modifikace prvků pole přes ukazatel získaný v každé iteraci smyčky foreach

15. Průchod prvky sekvence v opačném pořadí s využitím smyčky foreach_r

16. Programová smyčka typu while

17. Vnořené programové smyčky

18. Vnořené programové smyčky a příkaz break

19. Repositář s demonstračními příklady

20. Odkazy na Internetu

1. Programovací jazyk C3: podmínky, rozvětvení a programové smyčky

V předchozích třech článcích o programovacím jazyce C3 jsme si mj. řekli, že tento jazyk má poměrně velké množství rezervovaných klíčových slov. Všechna tato slova jsou vypsána pod tímto odstavcem:

void        bool        char        double
float       float16     int128      ichar
int         iptr        isz         long
short       uint128     uint        ulong
uptr        ushort      usz         float128
any         fault       typeid      assert
asm         bitstruct   break       case
catch       const       continue    alias
default     defer       typedef     do
else        enum        extern      false
for         foreach     foreach_r   fn
tlocal      if          inline      import
macro       module      nextcase    null
return      static      struct      switch
true        try         union       var
while       attrdef

Některá slova již známe. Jedná se o názvy datových typů, o některé konstanty a taktéž o slova používaná v definicích funkcí. Pokud tato slova ze seznam odstraníme, zbude nám dosti zmenšený seznam:

any                     typeid      assert
asm         bitstruct   break       case
catch       const       continue    alias
default     defer       typedef     do
else        enum        extern
for         foreach     foreach_r   fn
tlocal      if          inline
macro                   nextcase
            static      struct      switch
            try         union
while       attrdef

V dnešním článku se seznámíme s konstrukcemi pro řízení běhu programu, které jsou realizovány zvýrazněnými klíčovými slovy:

any                     typeid      assert
asm         bitstruct   break       case
catch       const       continue    alias
default     defer       typedef     do
else        enum        extern
for         foreach     foreach_r   fn
tlocal      if          inline
macro                   nextcase
            static      struct      switch
            try         union
while       attrdef

Pro připomenutí – všechny demonstrační příkladu ukázané v navazujících kapitolách, jsou založeny na následující šabloně:

module program_stub;
 
fn void main()
{
}

Jedná se o zápis plnohodnotného programu, který je možné přeložit a spustit:

Program linked to executable './program_stub'.
Launching ./program_stub
Program completed with exit code 0.

2. Rozvětvení běhu programu založené na konstrukcích if a if-else

V prakticky všech moderních programovacích jazycích se pro základní rozvětvení běhu programu používá konstrukce založená na klíčovém slovu if; v případě úplného rozvětvení (do dvou větví) pak konstrukce založená na dvojici klíčových slov if a else. Nejinak je tomu i v programovacím jazyku C3, ve kterém se konstrukce if zapisuje následujícím způsobem (včetně kulatých závorek okolo podmínky, tedy výrazu vyhodnocovaného na hodnotu typu bool, a včetně zápisu příslušné větve do bloku ohraničeného složenými závorkami):

module if_branch;
import std::io;
 
fn void which_number(int x) {
    if (x % 2 == 0) {
        io::printfn("%d is even number", x);
    }
}
 
fn void main()
{
    for (int i=0; i<10; i++) {
        which_number(i);
    }
}

Tento program po svém překladu a spuštění vypíše pouze informace o tom, že funkci which_number byl předán parametr obsahující sudé číslo:

0 is even number
2 is even number
4 is even number
6 is even number
8 is even number

Úplné rozvětvení je realizováno s využitím klíčových slov if a else, přičemž obě větve jsou zapsány vlastním blokem (i když tento blok bude obsahovat jen jediný příkaz):

module if_else_branch;
import std::io;
 
fn void which_number(int x) {
    if (x % 2 == 0) {
        io::printfn("%d is even number", x);
    }
    else {
        io::printfn("%d is odd number", x);
    }
}
 
fn void main()
{
    for (int i=0; i<10; i++) {
        which_number(i);
    }
}

Takto upravený program dokáže rozpoznat a vypsat jak sudá, tak i lichá čísla, což je ostatně patrné i z vypsaných výsledků:

0 is even number
1 is odd number
2 is even number
3 is odd number
4 is even number
5 is odd number
6 is even number
7 is odd number
8 is even number
9 is odd number

3. Porovnání s jazykem C: nekorektní způsoby zápisu konstrukce if-else

V programovacím jazyku C, a tím pádem i například v C++ nebo v Javě (ale i v dalších programovacích jazycích) je možné ve větvi if popř. ve větvi else zapsat jen jediný příkaz, který nemusí být umístěn do samostatného bloku. Ovšem i kvůli zamezení chybám typu Apple Goto fail takovou konstrukci jazyk C3 (ale například i Go) odmítne a bude vyžadovat, aby se tento (jediný) příkaz zapsal přímo na řádek s podmínkou if.

To si ostatně můžeme snadno otestovat na následující ukázce kódu:

module improper_if_else;
import std::io;
 
fn void which_number(int x) {
    if (x % 2 == 0)
        io::printfn("%d is even number", x);
    else
        io::printfn("%d is odd number", x);
}
 
fn void main()
{
    for (int i=0; i<10; i++) {
        which_number(i);
    }
}

Překladač tuto konstrukci odmítne:

 3:
 4: fn void which_number(int x) {
 5:     if (x % 2 == 0)
 6:         io::printfn("%d is even number", x);
            ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
(/tmp/ramdisk/c3-control-flow/04_improper_if.c3:6:9) Error: The 'then' part of a single line if-statement must start on the same line as the 'if' or use '{ }'

Pokud se jedná o neúplné rozvětvení (s if, ale bez else), je podporován tento zápis:

module improper_if_else;
import std::io;
 
fn void which_number(int x) {
    if (x % 2 == 0) io::printfn("%d is even number", x);
}
 
fn void main()
{
    for (int i=0; i<10; i++) {
        which_number(i);
    }
}

Ovšem v případě, že se jedná o rozvětvení úplné, vyžaduje překladač jazyka C3 explicitní zápis programových bloků, tedy takový zápis, který byl použit v předchozí kapitole:

module improper_if_else;
import std::io;
 
fn void which_number(int x) {
    if (x % 2 == 0) io::printfn("%d is even number", x);
    else io::printfn("%d is odd number", x);
}
 
fn void main()
{
    for (int i=0; i<10; i++) {
        which_number(i);
    }
}

Chybové hlášení překladače:

 2: import std::io;
 3:
 4: fn void which_number(int x) {
 5:     if (x % 2 == 0) io::printfn("%d is even number", x);
                        ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
(/tmp/ramdisk/c3-control-flow/05_improper_if.c3:5:21) Error: if-statements with an 'else' must use '{ }' even around a single statement.

4. Složitější rozvětvení založené na konstrukci if-else if-else

V případě, že má být provedeno rozvětvení do většího množství větví (typicky na základě složitější podmínky), můžeme využít konstrukci if-else if else. Ve skutečnosti se jedná o běžné rozvětvení if-else, ovšem ve větvi else je zapsáno další rozvětvení. Výsledek není příliš čitelný a i z tohoto důvodu lze využít rozšířenou konstrukci switch-case popsanou v navazujících kapitolách. Nicméně se vraťme k rozvětvení realizovanému pomocí if-else if-else. Vypadá následovně:

module if_else_if;
import std::io;
 
fn void which_number(int x) {
    if (x == 0) {
        io::printfn("%d is zero", x);
    }
    else if (x % 2 == 0) {
        io::printfn("%d is even number", x);
    }
    else {
        io::printfn("%d is odd number", x);
    }
}
 
fn void main()
{
    for (int i=0; i<10; i++) {
        which_number(i);
    }
}

Takto upravený program rozliší, zda se do funkce which_number předává nulová hodnota, hodnota kladná či naopak hodnota záporná:

0 is zero
1 is odd number
2 is even number
3 is odd number
4 is even number
5 is odd number
6 is even number
7 is odd number
8 is even number
9 is odd number
Poznámka: z tohoto popisu nepřímo vyplývá, že v jazyku C3 neexistuje klíčové slovo elseif či elif.

5. Základní forma rozvětvení založeného na konstrukci switch-case

V předchozí kapitole bylo napsáno, že rozhodovací konstrukce if-else if-else není příliš čitelná a většinou se ani často v jazyku C3 nepoužívá. Je tomu tak z toho důvodu, že programovací jazyk C3 nabízí vývojářům lepší, použitelnější i čitelnější rozhodovací konstrukci switch-case. Ta se v některých ohledech odlišuje od jazyka C a spíše se podobá programovacímu jazyku Go.

Podívejme se nejdříve na základní způsob zápisu této rozhodovací konstrukce. Za klíčovým slovem switch je v kulatých závorkách zapsán výraz, který se vyhodnotí a jeho výsledek je postupně porovnáván s konstantami zapsanými za klíčová slova case. V případě, že dojde ke shodě, tj. například pokud platí, že x==1, jsou vykonány příkazy uvedené v bloku za case. Oproti programovacímu jazyku C je zde jeden významný rozdíl – není zapotřebí jednotlivé bloky explicitně ukončovat klíčovým slovem break:

module switch_statement;
import std::io;
 
fn void which_number(int x) {
    switch (x) {
        case 0:
            io::printfn("%d is zero", x);
        case 1:
            io::printfn("%d is odd number", x);
        case 2:
            io::printfn("%d is even number", x);
        default:
            io::printfn("I don't know what to say about %d", x);
    }
}
 
fn void main()
{
    for (int i=0; i<10; i++) {
        which_number(i);
    }
}

Výsledek by měl vypadat následovně:

0 is zero
1 is odd number
2 is even number
I don't know what to say about 3
I don't know what to say about 4
I don't know what to say about 5
I don't know what to say about 6
I don't know what to say about 7
I don't know what to say about 8
I don't know what to say about 9

Z důvodu (například) přepisu starších programů z C do C3 je ovšem použití klíčového slova break povoleno:

module switch_statement;
import std::io;
 
fn void which_number(int x) {
    switch (x) {
        case 0:
            io::printfn("%d is zero", x);
            break;
        case 1:
            io::printfn("%d is odd number", x);
            break;
        case 2:
            io::printfn("%d is even number", x);
            break;
        default:
            io::printfn("I don't know what to say about %d", x);
            break;
    }
}
 
fn void main()
{
    for (int i=0; i<10; i++) {
        which_number(i);
    }
}
Poznámka: zde to sice není díky větvi default patrné, ale jazyk C3 nevyžaduje, aby podmínky ve větvích case pokrývaly všechny možné stavy (na rozdíl od programovacího jazyka Rust).

6. Větší množství podmínek a konstrukce switch-case

V případě, že budeme mít za úkol rozlišit, jaká čísla (sudá, lichá či nula) v rozsahu od 0 do 9 jsou předána do funkce which_number, můžeme realizaci tohoto algoritmu, i když bude řešení dosti naivní a nerozšiřitelné, založit na konstrukci switch-case, ovšem s tím, že budeme nějaký příkaz (například výpis informace o tom, že se jedná a sudou hodnotu) provádět pro více hodnot x. Realizace se do značné míry podobá zápisu, který by byl použit v klasickém céčku, akorát není zapotřebí zapisovat klíčové slovo break v každém bloku s výpisem typu hodnoty:

module switch_statement;
import std::io;
 
fn void which_number(int x) {
    switch (x) {
        case 0:
            io::printfn("%d is zero", x);
        case 1:
        case 3:
        case 5:
        case 7:
        case 9:
            io::printfn("%d is odd number", x);
        case 2:
        case 4:
        case 6:
        case 8:
        case 10:
            io::printfn("%d is even number", x);
        default:
            io::printfn("I don't know what to say about %d", x);
    }
}
 
fn void main()
{
    for (int i=0; i<10; i++) {
        which_number(i);
    }
}

Nyní bude výsledek vypadat podobně, jako tomu bylo při použití rozhodovací konstrukce if-else if-else:

0 is zero
1 is odd number
2 is even number
3 is odd number
4 is even number
5 is odd number
6 is even number
7 is odd number
8 is even number
9 is odd number
Poznámka: pochopitelně je tento způsob (prozatím) nepříliš obecný, to ovšem změníme v navazující kapitole.

7. Podmínky v konstrukci switch-case vyhodnocované v čase běhu procesu

Ve skutečnosti ovšem programová konstrukce switch-case implementovaná v programovacím jazyku C3 nabízí větší možnosti, než podobně vypadající konstrukce v původním céčku. Například je možné za klíčová slova case zapisovat výrazy vyhodnocované až v čase běhu programu. To tedy znamená, že můžeme realizovat rozhodnutí, zda je předaná celočíselná hodnota nulová, sudá či naopak lichá, například následujícím způsobem:

module switch_statement;
import std::io;
 
fn void which_number(int x) {
    switch (true) {
        case x == 0:
            io::printfn("%d is zero", x);
        case x % 2 == 0:
            io::printfn("%d is even number", x);
        default:
            io::printfn("%d is odd number", x);
    }
}
 
fn void main()
{
    for (int i=0; i<10; i++) {
        which_number(i);
    }
}

Výsledky získané po překladu a spuštění tohoto příkladu:

0 is zero
1 is odd number
2 is even number
3 is odd number
4 is even number
5 is odd number
6 is even number
7 is odd number
8 is even number
9 is odd number

Ve skutečnosti můžeme výraz za klíčovým slovem switch zcela odstranit a provést rozvětvení následujícím způsobem:

module switch_statement;
import std::io;
 
fn void which_number(int x) {
    switch {
        case x == 0:
            io::printfn("%d is zero", x);
        case x % 2 == 0:
            io::printfn("%d is even number", x);
        default:
            io::printfn("%d is odd number", x);
    }
}
 
fn void main()
{
    for (int i=0; i<10; i++) {
        which_number(i);
    }
}

Výsledky budou totožné s předchozím řešením:

0 is zero
1 is odd number
2 is even number
3 is odd number
4 is even number
5 is odd number
6 is even number
7 is odd number
8 is even number
9 is odd number

8. Konstrukce switch-case a příkaz break

V předchozím textu jsme si řekli, že v rozhodovací konstrukci switch-case není nutné jednotlivé větve „uzavírat“ slovem break. Ovšem můžeme se setkat se situací, kdy by větev byla prázdná. V takovém případě se break hodí. Typickým příkladem použití je explicitní zápis větve default, která je prázdná (jazyk C3 její explicitní zápis ovšem nevyžaduje):

module switch_statement;
import std::io;
 
fn void which_number(int x) {
    switch (true) {
        case x == 0:
            io::printfn("%d is zero", x);
        case x % 2 == 0:
            io::printfn("%d is even number", x);
        case x % 2 != 0:
            io::printfn("%d is odd number", x);
        default:
            break;
    }
}
 
fn void main()
{
    for (int i=0; i<10; i++) {
        which_number(i);
    }
}

Opět se podívejme na to, jaké zprávy budou tímto demonstračním příkladem vypsány:

0 is zero
1 is odd number
2 is even number
3 is odd number
4 is even number
5 is odd number
6 is even number
7 is odd number
8 is even number
9 is odd number

9. Klíčové slovo nextcase v programové konstrukci switch-case

V jazyku C3 je možné ve větvi case zapsat klíčové slovo nextcase, které přenese řízení do další větve. V mnoha ohledech se tedy nextcase podobá klíčovému slovu fallthrough z programovacího jazyka Go. Podívejme se na příklad použití. Ve větvi zavolané pro x==0 se po výpisu zprávy „0 is zero“ konstrukce switch-case neukončí, ale přejde se na další větev, ve které se vypíše „0 is even number“ (což je vlastně taktéž korektní). Takto upravený demonstrační příklad vypadá následovně:

module switch_statement;
import std::io;
 
fn void which_number(int x) {
    switch (true) {
        case x == 0:
            io::printfn("%d is zero", x);
            nextcase;
        case x % 2 == 0:
            io::printfn("%d is even number", x);
        case x % 2 != 0:
            io::printfn("%d is odd number", x);
        default:
            break;
    }
}
 
fn void main()
{
    for (int i=0; i<10; i++) {
        which_number(i);
    }
}

Povšimněte si, že se skutečně pro x==0 vypíše dvojice zpráv a nikoli pouze informace o nulovém prvku:

0 is zero
0 is even number
1 is odd number
2 is even number
3 is odd number
4 is even number
5 is odd number
6 is even number
7 is odd number
8 is even number
9 is odd number

10. Základní forma počítané programové smyčky for

Vzhledem k tomu, že je programovací jazyk C3 odvozen od klasického céčka, nebude velkým překvapením, že i v C3 nalezneme programovou smyčku realizovanou klíčovým slovem for. I v C3 je možné specifikovat lokální proměnnou použitou jako počitadlo smyčky. Příkladem může být program, který jsme si (i když v nepatrně odlišné variantě) ukázali minule. V tomto programu je definováno desetiprvkové pole, přičemž hodnoty prvků tohoto pole jsou naplněny právě v počítané smyčce for:

module loops;
import std::io;
 
fn void main()
{
    int[10] a;
 
    for (int i=0; i<a.len; i++) {
        a[i] = (i + 1)*10;
    }
    io::printf("a=%s\n", a);
}

Ze zobrazených výsledků je patrné, že je pole skutečně naplněno hodnotami vypočtenými uvnitř programové smyčky:

a=[10, 20, 30, 40, 50, 60, 70, 80, 90, 100]

Ve smyčce for lze ovšem hodnotu počitadla měnit libovolným způsobem, například:

module loops;
import std::io;
 
fn void main()
{
    for (int i=1; i<1000; i*=2) {
        io::printf("i=%s\n", i);
    }
}

Výsledky:

i=1
i=2
i=4
i=8
i=16
i=32
i=64
i=128
i=256
i=512

11. Průchod polem či jinou sekvencí smyčkou typu foreach

V předchozím článku jsme se seznámili s takzvanými kontejnery, tj. s datovými typy, které jako své hodnoty obsahují nějakou sekvenci prvků (obecně odlišného typu). Pro realizaci průchodu těmito prvky je v programovacím jazyku C3 určena programová smyčka typu forach, kterou je možné zapsat různými způsoby.

Nejjednodušší forma zápisu smyčky typu foreach je ukázána na dalším demonstračním příkladu. Procházíme v něm polem a, přičemž v každé iteraci bude hodnota n-tého prvku uložena do lokální proměnné item. Povšimněte si, že není nutné specifikovat typ této proměnné. A navíc bude tato proměnná viditelná pouze ve vnitřním bloku smyčky foreach:

module loops;
import std::io;
 
fn void main()
{
    int[10] a = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10};
 
    foreach (item : a)
    {
        io::printfn("item: %s", item);
    }
}

Výsledky, které by se měly zobrazit po překladu a spuštění tohoto příkladu:

item: 1
item: 2
item: 3
item: 4
item: 5
item: 6
item: 7
item: 8
item: 9
item: 10
Poznámka: tuto smyčku je možné použít i pro uživatelem definované datové typy, ovšem aby byla aplikovatelná, je nutné provést přetížení některých operátorů atd. v takových typech. Podrobnosti si řekneme v navazujícím článku.

12. Průchod polem smyčkou foreach se získáním indexu i prvku v každé iteraci

Programová smyčka typu forarch dokáže v každé iteraci získat jak hodnotu prvku pole (což jsme ostatně viděli i v předchozí kapitole), tak i index tohoto prvku, což může být poměrně užitečné (modifikace pole, tisk různých tabulek atd.). Zápis takové varianty programové smyčky je ve skutečnosti velmi jednoduchý, jak je to ostatně patrné i z následujícího demonstračního příkladu. Povšimněte si, že není nutné definovat ani typ proměnné index ani item (a pochopitelně jsou tato jména plně volitelná vývojářem):

module loops;
import std::io;
 
fn void main()
{
    int[10] a = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10};
 
    foreach (index, item : a)
    {
        io::printfn("item #%d: %s", index, item);
    }
}

Po překladu a spuštění tohoto příkladu by se mělo vypsat deset řádků s indexy i hodnotami prvků pole a:

item #0: 1
item #1: 2
item #2: 3
item #3: 4
item #4: 5
item #5: 6
item #6: 7
item #7: 8
item #8: 9
item #9: 10

13. Modifikace prvků pole při jeho průchodu smyčkou foreach

Při průchodu polem s využitím programové smyčky foreach je možné obsah tohoto pole přímo modifikovat (což ale obecně nemusí platit pro všechny typy sekvencí). Využijeme přitom znalosti indexu každého prvku pole. Pokud například budeme chtít do desetiprvkového pole celých čísel postupně uložit hodnoty 10, 20, 30 … 100, je možné postupovat následujícím způsobem:

module loops;
import std::io;
 
fn void main()
{
    int[10] a = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10};
 
    foreach (i, item : a)
    {
        a[i] = ((int)i + 1)*10;
    }
    io::printf("a=%s\n", a);
}

Po překladu a spuštění tohoto příkladu si lze snadno ověřit, že je výsledek korektní:

a=[10, 20, 30, 40, 50, 60, 70, 80, 90, 100]
Poznámka: v programovacích jazycích, jakými je Go, je nutné deklarovanou proměnnou skutečně použít. V těchto jazycích by se mohl namísto jména item použít náhradní znak (placeholder) _. V C3 to však není možné a proto nepůjde následující program přeložit:
module loops;
import std::io;
 
fn void main()
{
    int[10] a = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10};
 
    foreach (i, _ : a)
    {
        a[i] = ((int)i + 1)*10;
    }
    io::printf("a=%s\n", a);
}

14. Modifikace prvků pole přes ukazatel získaný v každé iteraci smyčky foreach

Při použití programové smyčky foreach ve formě:

foreach (i, item : a)
{
    ...
    ...
    ...
}

je v každé iteraci do proměnné item zkopírována hodnota prvku. To ovšem znamená, že sice můžeme změnit hodnotu této proměnné, ale na původní pole nebude mít tato modifikace žádný vliv.

To si ostatně můžeme velmi snadno ověřit:

module loops;
import std::io;
 
fn void main()
{
    int[10] a = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10};
 
    foreach (i, item : a)
    {
        item = ((int)i + 1)*10;
    }
    io::printf("a=%s\n", a);
}

Po spuštění tohoto příkladu se vypíšou původní hodnoty prvků pole:

a=[1, 2, 3, 4, 5, 6, 7, 8, 9, 10]

Jazyk C3 ovšem umožňuje, aby se ve smyčce foreach v každé iteraci získal ukazatel na prvek pole, což již umožňuje zápis nové hodnoty do dané prvku (právě přes tento ukazatel). Syntaxe vypadá takto:

foreach (i, &item : a)
{
    ...
    ...
    ...
}

Ověřme si, jak lze takovou variantu programové smyčky využít:

module loops;
import std::io;
 
fn void main()
{
    int[10] a = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10};
 
    foreach (i, &item : a)
    {
        *item = ((int)i + 1)*10;
    }
    io::printf("a=%s\n", a);
}

Po spuštění tohoto demonstračního příkladu skutečně dojde k zápisu nových hodnot do všech prvků pole:

a=[10, 20, 30, 40, 50, 60, 70, 80, 90, 100]

15. Průchod prvky sekvence v opačném pořadí s využitím smyčky foreach_r

Programovací jazyk C3 umožňuje u některých typů sekvencí, mezi které patří mj. i klasická pole, nejenom průchod od prvního prvku směrem k prvku poslednímu, ale i opačný průchod, tj. od posledního prvku směrem k prvku prvnímu. Pokud je zapotřebí v programu tento průchod realizovat, používá se namísto programové smyčky foreach smyčka zapisovaná klíčovým slovem foreach_r. Ta má – pochopitelně kromě opačného směru iterací – naprosto stejné vlastnosti, jako již popsaná smyčka foreach.

module loops;
import std::io;
 
fn void main()
{
    int[10] a = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10};
 
    foreach_r (item : a)
    {
        io::printfn("item: %s", item);
    }
}

Výsledkem běhu tohoto programu bude následující sekvence hodnot přečtených z pole:

item: 10
item: 9
item: 8
item: 7
item: 6
item: 5
item: 4
item: 3
item: 2
item: 1

16. Programová smyčka typu while

Druhým typem programové smyčky, se kterou se dnes seznámíme, je smyčka typu while. Jedná se o smyčku, ve které se podmínka, zda se má provádět další iterace, provádí vždy na začátku každé iterace, tj. ještě před vstupem do těla smyčky (smyčka se tedy nemusí provést ani jedenkrát). Základní tvar této smyčky se v jazyku C3 vlastně nijak neodlišuje od jazyka C, ovšem s tím upřesněním, že podmínka pro další iteraci musí být zapsána výrazem typu bool.

Podívejme se na realizaci průchodu polem, tentokrát ovšem namísto smyčky foreach použijeme smyčku while (která je mimochodem v tomto kontextu nevhodná):

module loops;
import std::io;
 
fn void main()
{
    int[10] a = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10};
 
    int i = 0;
    while (i<a.len) {
        io::printfn("item: %s", a[i]);
        i++;
    }
}

Výsledky vypsané tímto demonstračním příkladem by měly být snadno pochopitelné:

item: 1
item: 2
item: 3
item: 4
item: 5
item: 6
item: 7
item: 8
item: 9
item: 10

V této smyčce lze, pochopitelně podobně jako u dalších typů programových smyček, použít příkaz break určený pro ukončení těla smyčky (typicky při splnění nějaké další podmínky):

module loops;
import std::io;
 
fn void main()
{
    int[10] a = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10};
 
    int i = 0;
    while (i<a.len) {
        if (a[i] >= 6) {
            break;
        }
        io::printfn("item: %s", a[i]);
        i++;
    }
}

Nyní se tělo smyčky ukončí při splnění zapsané podmínky (hodnota prvku pole je větší nebo rovna šesti):

item: 1
item: 2
item: 3
item: 4
item: 5

17. Vnořené programové smyčky

V jazyku C3, ostatně podobně jako ve všech mainstreamových programovacích jazycích, je možné programové smyčky vnořovat, s čímž souvisí i syntaxe a zejména sémantika příkazů break a continue. Podívejme se nejdříve na realizaci výpočtu malé násobilky s využitím dvou vnořených smyček typu for:

module loops;
import std::io;
 
fn void main()
{
    for (int y=1; y<=10; y++) {
        for (int x=1; x<=10; x++) {
            int z = x * y;
            io::printf("%3d ", z);
        }
        io::printn();
    }
}

Výsledkem bude následující tabulka vypsaná na standardní výstup:

  1   2   3   4   5   6   7   8   9  10
  2   4   6   8  10  12  14  16  18  20
  3   6   9  12  15  18  21  24  27  30
  4   8  12  16  20  24  28  32  36  40
  5  10  15  20  25  30  35  40  45  50
  6  12  18  24  30  36  42  48  54  60
  7  14  21  28  35  42  49  56  63  70
  8  16  24  32  40  48  56  64  72  80
  9  18  27  36  45  54  63  72  81  90
 10  20  30  40  50  60  70  80  90 100
Poznámka: realizace založená na programových smyčkách typu while není tak elegantní, vyžaduje proměnné s větší oblastí viditelnosti a navíc zde hrozí zapomenutí příkazu pro zvýšení hodnoty proměnné:
module loops;
import std::io;
 
fn void main()
{
    int y=1;
    while (y<=10) {
        int x=1;
        while (x<=10) {
            int z = x * y;
            io::printf("%3d ", z);
            x++;
        }
        io::printn();
        y++;
    }
}

18. Vnořené programové smyčky a příkaz break

Jak jsme se již řekli v předchozí kapitole, přináší možnost tvorby vnořených programových smyček jeden syntaktický a současně i sémantický problém – jak řešit výskoky (ukončení) z vnitřních smyček? V programovacím jazyku C k tomuto účelu sloužila konstrukce goto, ovšem jazyk C3 se snaží být více strukturovaný. Proto bylo nutné zavést způsob zápisu, který umožní výskok z vnitřních smyček.

Nejprve si připomeňme, že ukončení vnitřní smyčky zajistí příkaz break, a to bez dalších úprav:

module loops;
import std::io;
 
fn void main()
{
    for (int y=1; y<=10; y++) {
        for (int x=1; x<=10; x++) {
            int z = x * y;
            io::printf("%3d ", z);
            if (z == 42) {
                break;
            }
        }
        io::printn();
    }
}

Po spuštění tohoto programu se vnitřní smyčka ukončí po dosažení hodnoty 42, ovšem vnější smyčka stále pokračuje ve své činnosti. Výsledkem bude tabulka se zkráceným šestým a sedmým řádkem:

  1   2   3   4   5   6   7   8   9  10
  2   4   6   8  10  12  14  16  18  20
  3   6   9  12  15  18  21  24  27  30
  4   8  12  16  20  24  28  32  36  40
  5  10  15  20  25  30  35  40  45  50
  6  12  18  24  30  36  42
  7  14  21  28  35  42
  8  16  24  32  40  48  56  64  72  80
  9  18  27  36  45  54  63  72  81  90
 10  20  30  40  50  60  70  80  90 100

Programovací jazyk C3 zavádí novou syntaxi zápisu návěští (label), které umožňuje ukončení nejenom vnitřní smyčky, ale i libovolně zvolené smyčky vnější. Návěští se zapisuje přímo za klíčové slovo, kterým smyčka začíná:

module loops;
import std::io;
 
fn void main()
{
    for END: (int y=1; y<=10; y++) {
        for (int x=1; x<=10; x++) {
            int z = x * y;
            io::printf("%3d ", z);
            if (z == 42) {
                break END;
            }
        }
        io::printn();
    }
}

V tomto demonstračním příkladu bude tisk tabulky zcela ukončen po dosažení hodnoty 42:

  1   2   3   4   5   6   7   8   9  10
  2   4   6   8  10  12  14  16  18  20
  3   6   9  12  15  18  21  24  27  30
  4   8  12  16  20  24  28  32  36  40
  5  10  15  20  25  30  35  40  45  50
  6  12  18  24  30  36  42

Naprosto stejným způsobem lze téhož dosáhnout i u programové smyčky typu while:

module loops;
import std::io;
 
fn void main()
{
    int y = 1;
    while END: (y<=10) {
        int x = 1;
        while (x<=10) {
            int z = x * y;
            io::printf("%3d ", z);
            if (z == 42) {
                break END;
            }
            x++;
        }
        io::printn();
        y++;
    }
}

Výsledek:

  1   2   3   4   5   6   7   8   9  10
  2   4   6   8  10  12  14  16  18  20
  3   6   9  12  15  18  21  24  27  30
  4   8  12  16  20  24  28  32  36  40
  5  10  15  20  25  30  35  40  45  50
  6  12  18  24  30  36  42

Ještě si ukažme nepatrně komplikovanější příklad, ve kterém se příkazem break vyskakuje ze dvou smyček, i když jsou v programu realizovány celkem tři vnořené programové smyčky:

module loops;
import std::io;
 
fn void main()
{
    for (int zaklad=1; zaklad<=100; zaklad*=10) {
        for END: (int y=1; y<=10; y++) {
            for (int x=1; x<=10; x++) {
                int z = x * y;
                io::printf("%5d ", z*zaklad);
                if (z == 42) {
                    break END;
                }
            }
            io::printn();
        }
        io::printn();
        io::printn("-----------------------------------------------------------");
    }
}

Výsledky ukazují ukončení „prostřední“ smyčky, nikoli smyčky vnější:

    1     2     3     4     5     6     7     8     9    10
    2     4     6     8    10    12    14    16    18    20
    3     6     9    12    15    18    21    24    27    30
    4     8    12    16    20    24    28    32    36    40
    5    10    15    20    25    30    35    40    45    50
    6    12    18    24    30    36    42
-----------------------------------------------------------
   10    20    30    40    50    60    70    80    90   100
   20    40    60    80   100   120   140   160   180   200
   30    60    90   120   150   180   210   240   270   300
   40    80   120   160   200   240   280   320   360   400
   50   100   150   200   250   300   350   400   450   500
   60   120   180   240   300   360   420
-----------------------------------------------------------
  100   200   300   400   500   600   700   800   900  1000
  200   400   600   800  1000  1200  1400  1600  1800  2000
  300   600   900  1200  1500  1800  2100  2400  2700  3000
  400   800  1200  1600  2000  2400  2800  3200  3600  4000
  500  1000  1500  2000  2500  3000  3500  4000  4500  5000
  600  1200  1800  2400  3000  3600  4200
-----------------------------------------------------------

19. Repositář s demonstračními příklady

Demonstrační příklady vytvořené pro nejnovější verzi programovacího jazyka C3 byly uloženy do repositáře dostupného na adrese https://github.com/tisnik/c3-examples. Následují odkazy na jednotlivé příklady (či jejich nedokončené části).

Demonstrační příklady z prvního článku o jazyku C3:

# Příklad Stručný popis Adresa
1 factorial.c3 realizace výpočtu faktoriálu https://github.com/tisnik/c3-examples/blob/master/intro­duction/factorial.c3
2 factorial_macro.c3 výpočet faktoriálu konkrétní hodnoty implementovaný formou makra https://github.com/tisnik/c3-examples/blob/master/intro­duction/factorial_macro.c3
       
3 swap_macro.c3 makro realizující prohození dvou hodnot https://github.com/tisnik/c3-examples/blob/master/intro­duction/swap_macro.c3
       
4 renderer.c výpočet a vykreslení Juliovy množiny implementovaný v jazyku C https://github.com/tisnik/c3-examples/blob/master/intro­duction/renderer.c
5 renderer_v1.c3 definice datové struktury s rozměry rastrového obrázku a skeleton všech funkcí https://github.com/tisnik/c3-examples/blob/master/intro­duction/renderer_v1.c3
6 renderer_v2.c3 anotace parametrů funkcí typu ukazatel (pointer) https://github.com/tisnik/c3-examples/blob/master/intro­duction/renderer_v2.c3
7 renderer_v3.c3 statická kontrola, zda se nepředávají neinicializované ukazatele https://github.com/tisnik/c3-examples/blob/master/intro­duction/renderer_v3.c3
8 renderer_v4.c3 runtime kontrola, zda se nepředávají neinicializované ukazatele https://github.com/tisnik/c3-examples/blob/master/intro­duction/renderer_v4.c3
9 renderer_v5.c3 první (nekorektní) varianta funkce pro inicializaci barvové palety https://github.com/tisnik/c3-examples/blob/master/intro­duction/renderer_v5.c3
10 renderer_v6.c3 druhá (korektní) varianta funkce pro inicializaci barvové palety https://github.com/tisnik/c3-examples/blob/master/intro­duction/renderer_v6.c3
11 renderer_v7.c3 volání knihovní I/O funkce a volání nativní céčkovské funkce https://github.com/tisnik/c3-examples/blob/master/intro­duction/renderer_v7.c3
12 renderer_v8.c3 plně funkční program pro výpočet a vykreslení Juliovy množiny https://github.com/tisnik/c3-examples/blob/master/intro­duction/renderer_v8.c3

Demonstrační příklady ze druhého článku o jazyku C3:

# Příklad Stručný popis Adresa
13 01_just_main.c3 struktura nejjednoduššího programu obsahujícího pouze prázdnou funkci main https://github.com/tisnik/c3-examples/blob/master/c3-basics/01_just_main.c3
14 02_module_name.c3 struktura programu s uvedeným plným jménem modulu https://github.com/tisnik/c3-examples/blob/master/c3-basics/02_module_name.c3
15 03_hello_world.c3 klasický program typu „Hello, world!“ napsaný v jazyku C3 https://github.com/tisnik/c3-examples/blob/master/c3-basics/03_hello_world.c3
16 04_exit_value.c3 ukončení procesu s předáním návratového kódu zpět volajícímu programu https://github.com/tisnik/c3-examples/blob/master/c3-basics/04_exit_value.c3
17 05_c_function.c3 zavolání funkce definované v knihovně programovacího jazyka C https://github.com/tisnik/c3-examples/blob/master/c3-basics/05_c_function.c3
       
18 06_bool_type.c3 definice proměnných typu pravdivostní hodnota (bool) https://github.com/tisnik/c3-examples/blob/master/c3-basics/06_bool_type.c3
19 07_int_to_bool.c3 implicitní převod hodnoty typu int na pravdivostní hodnotu (nekorektní řešení) https://github.com/tisnik/c3-examples/blob/master/c3-basics/07_int_to_bool.c3
20 08_int_to_bool.c3 explicitní převod hodnoty typu int na pravdivostní hodnotu (korektní řešení) https://github.com/tisnik/c3-examples/blob/master/c3-basics/08_int_to_bool.c3
21 09_int_to_bool.c3 explicitní převod hodnoty typu int na pravdivostní hodnotu (nekorektní řešení) https://github.com/tisnik/c3-examples/blob/master/c3-basics/09_int_to_bool.c3
22 10_bool_sizeof.c3 zjištění velikosti paměti obsazené hodnotou typu bool https://github.com/tisnik/c3-examples/blob/master/c3-basics/10_bool_sizeof.c3
       
23 11_int_types.c3 definice proměnných typu celé číslo se znaménkem s různou bitovou šířkou https://github.com/tisnik/c3-examples/blob/master/c3-basics/11_int_types.c3
24 12_uint_types.c3 definice proměnných typu celé číslo bez znaménka s různou bitovou šířkou https://github.com/tisnik/c3-examples/blob/master/c3-basics/12_uint_types.c3
25 13_no_suffixes.c3 celočíselné konstanty bez uvedení suffixu (bitové šířky) https://github.com/tisnik/c3-examples/blob/master/c3-basics/13_no_suffixes.c3
26 14_suffixes.c3 celočíselné konstanty s uvedením sufficu (bitové šířky) https://github.com/tisnik/c3-examples/blob/master/c3-basics/14_suffixes.c3
27 15_int_sizeof.c3 zjištění velikosti paměti obsazené celočíselnými hodnotami se znaménkem https://github.com/tisnik/c3-examples/blob/master/c3-basics/15_int_sizeof.c3
28 16_uint_sizeof.c3 zjištění velikosti paměti obsazené celočíselnými hodnotami bez znaménka https://github.com/tisnik/c3-examples/blob/master/c3-basics/16_uint_sizeof.c3
29 17_int_conversions.c3 korektní převody mezi celočíselnými hodnotami s různou bitovou šířkou https://github.com/tisnik/c3-examples/blob/master/c3-basics/17_int_conversions.c3
30 18_int_conversions.c3 nekorektní převody mezi celočíselnými hodnotami s různou bitovou šířkou https://github.com/tisnik/c3-examples/blob/master/c3-basics/18_int_conversions.c3
31 19_int_conversions.c3 explicitní převody a přetečení hodnot https://github.com/tisnik/c3-examples/blob/master/c3-basics/19_int_conversions.c3
       
32 20_float_types.c3 definice proměnných typu numerická hodnota s plovoucí řádovou čárkou (tečkou) https://github.com/tisnik/c3-examples/blob/master/c3-basics/20_float_types.c3
       
33 21_vector_type.c3 definice vektoru obsahujícího celočíselné hodnoty https://github.com/tisnik/c3-examples/blob/master/c3-basics/21_vector_type.c3
34 22_vector_operations.c3 základní operace s celými vektory https://github.com/tisnik/c3-examples/blob/master/c3-basics/22_vector_operations.c3
35 23_vector_sizes.c3 zjištění a tisk velikosti vektorů (různé datové typy prvků vektorů, shodná délka) https://github.com/tisnik/c3-examples/blob/master/c3-basics/23_vector_sizes.c3
36 24_vector_sizes.c3 zjištění a tisk velikosti vektorů (stejné datové typy prvků vektorů, odlišná délka) https://github.com/tisnik/c3-examples/blob/master/c3-basics/24_vector_sizes.c3

Demonstrační příklady z předchozího článku o jazyku C3:

# Příklad Stručný popis Adresa
37 01_vector_type.c3 definice vektoru, modifikace prvků vektoru, tisk obsahu celého vektoru https://github.com/tisnik/c3-examples/blob/master/c3-containers/01_vector_type.c3
38 02_vector_parameter.c3 předání vektoru do funkce hodnotou https://github.com/tisnik/c3-examples/blob/master/c3-containers/02_vector_parameter.c3
39 03_vector_pointer.c3 předání vektoru do funkce odkazem (přes ukazatel) https://github.com/tisnik/c3-examples/blob/master/c3-containers/03_vector_pointer.c3
       
40 04_array_type.c3 definice pole, modifikace prvků pole, tisk obsahu celého pole https://github.com/tisnik/c3-examples/blob/master/c3-containers/04_array_type.c3
41 05_array_parameter.c3 předání pole do funkce hodnotou https://github.com/tisnik/c3-examples/blob/master/c3-containers/05_array_parameter.c3
42 06_array_pointer.c3 předání pole do funkce odkazem (přes ukazatel) https://github.com/tisnik/c3-examples/blob/master/c3-containers/06_array_pointer.c3
       
43 07_slice_type.c3 vytvoření (konstrukce) řezu (slice) https://github.com/tisnik/c3-examples/blob/master/c3-containers/07_slice_type.c3
44 08_slice_parameter.c3 předání řezu do funkce https://github.com/tisnik/c3-examples/blob/master/c3-containers/08_slice_parameter.c3
45 09_slice_slicing.c3 konstrukce řezu z pole stejně pojmenovanou operací (řez od..do) https://github.com/tisnik/c3-examples/blob/master/c3-containers/09_slice_slicing.c3
46 10_slice_slicing.c3 konstrukce řezu z pole stejně pojmenovanou operací (záporné indexy) https://github.com/tisnik/c3-examples/blob/master/c3-containers/10_slice_slicing.c3
47 11_slice_slicing.c3 konstrukce řezu z pole stejně pojmenovanou operací (určení délky řezu) https://github.com/tisnik/c3-examples/blob/master/c3-containers/11_slice_slicing.c3
48 12_slice_of_slice.c3 konstrukce řezu z jiného řezu https://github.com/tisnik/c3-examples/blob/master/c3-containers/12_slice_of_slice.c3
       
49 13_list_type.c3 vytvoření (konstrukce) seznamu https://github.com/tisnik/c3-examples/blob/master/c3-containers/13_list_type.c3
50 14_list_parameter.c3 předání seznamu do funkce https://github.com/tisnik/c3-examples/blob/master/c3-containers/14_list_parameter.c3
       
51 15_dynamic_array.c3 vytvoření (konstrukce) dynamicky alokovaného pole https://github.com/tisnik/c3-examples/blob/master/c3-containers/15_dynamic_array.c3
       
52 16_string_type.c3 základní typ řetězce string https://github.com/tisnik/c3-examples/blob/master/c3-containers/16_string_type.c3
53 17_string_unicode.c3 Unicode znaky v řetězci typu string https://github.com/tisnik/c3-examples/blob/master/c3-containers/17_string_unicode.c3
54 18_zstring_type.c3 řetězce ukončené nulou (C-string, ASCIIZ) https://github.com/tisnik/c3-examples/blob/master/c3-containers/18_zstring_type.c3
55 19_zstring_unicode.c3 Unicode znaky v řetězci typu zstring https://github.com/tisnik/c3-examples/blob/master/c3-containers/19_zstring_unicode.c3
56 20_string_comparison.c3 porovnávání obsahu řetězců https://github.com/tisnik/c3-examples/blob/master/c3-containers/20_string_comparison.c3

Demonstrační příklady z dnešního článku o jazyku C3:

# Příklad Stručný popis Adresa
57 01_program_stub.c3 struktura programu s uvedeným plným jménem modulu https://github.com/tisnik/c3-examples/blob/master/c3-control-flow/01_program_stub.c3
       
58 02_if.c3 nejjednodušší forma rozvětvení založené na konstrukci if https://github.com/tisnik/c3-examples/blob/master/c3-control-flow/02_if.c3
59 03_if_else.c3 plné rozvětvení realizované konstrukcí if-else https://github.com/tisnik/c3-examples/blob/master/c3-control-flow/03_if_else.c3
60 04_improper_if.c3 nekorektní způsob zápisu programové konstrukce if-else (porovnání s jazykem C) https://github.com/tisnik/c3-examples/blob/master/c3-control-flow/04_improper_if.c3
61 05_improper_if.c3 nekorektní způsob zápisu programové konstrukce if-else (porovnání s jazykem C) https://github.com/tisnik/c3-examples/blob/master/c3-control-flow/05_improper_if.c3
62 06_if_else_if.c3 složitější rozvětvení založené na programové konstrukci if-else if-else https://github.com/tisnik/c3-examples/blob/master/c3-control-flow/06_if_else_if.c3
       
63 07_switch_basic.c3 základní forma vícenásobného rozvětvení založeného na konstrukci switch-case https://github.com/tisnik/c3-examples/blob/master/c3-control-flow/07_switch_basic.c3
64 08_switch_basic.c3 větší množství podmínek a programová konstrukce switch-case https://github.com/tisnik/c3-examples/blob/master/c3-control-flow/08_switch_basic.c3
65 09_switch_condition.c3 podmínky zapsané ve větvích programové konstrukci switch-case vyhodnocované v čase běhu procesu https://github.com/tisnik/c3-examples/blob/master/c3-control-flow/09_switch_condition.c3
66 10_switch_true.c3 konstrukce switch-case bez uvedeného výrazu za klíčovým slovem switch https://github.com/tisnik/c3-examples/blob/master/c3-control-flow/10_switch_true.c3
67 11_switch_break.c3 zápis prázdné větve default v programové konstrukci switch-case https://github.com/tisnik/c3-examples/blob/master/c3-control-flow/11_switch_break.c3
68 12_switch_nextcase.c3 pokračování ve vykonávání konstrukce switch-case vynucené klíčovým slovem nextcase https://github.com/tisnik/c3-examples/blob/master/c3-control-flow/12_switch_nextcase.c3
       
69 13_for_loop.c3 základní forma programové smyčky realizované klíčovým slovem for https://github.com/tisnik/c3-examples/blob/master/c3-control-flow/13_for_loop.c3
70 14_foreach_loop.c3 základní forma programové smyčky typu for-each https://github.com/tisnik/c3-examples/blob/master/c3-control-flow/14_foreach_loop.c3
71 15_foreach_loop.c3 programová smyčka for-each vracející index prvku i hodnotu prvku https://github.com/tisnik/c3-examples/blob/master/c3-control-flow/15_foreach_loop.c3
72 16_foreach_loop.c3 modifikace obsahu pole v programové smyčce for-each https://github.com/tisnik/c3-examples/blob/master/c3-control-flow/16_foreach_loop.c3
73 17_foreach_loop.c3 pokus o modifikaci obsahu procházeného pole https://github.com/tisnik/c3-examples/blob/master/c3-control-flow/17_foreach_loop.c3
74 18_foreach_loop.c3 modifikace procházeného pole přes ukazatel na prvek https://github.com/tisnik/c3-examples/blob/master/c3-control-flow/18_foreach_loop.c3
75 19_foreach_r_loop.c3 programová smyčka for-each, ve které se sekvencí prochází v opačném pořadí https://github.com/tisnik/c3-examples/blob/master/c3-control-flow/19_foreach_r_loop.c3
       
76 20_while_loop.c3 základní forma programové smyčky typu while https://github.com/tisnik/c3-examples/blob/master/c3-control-flow/20_while_loop.c3
77 21_while_loop2.c3 programová smyčka typu while s konstrukcí break https://github.com/tisnik/c3-examples/blob/master/c3-control-flow/21_while_loop2.c3
78 22_nested_loops.c3 realizace vnořených programových smyček https://github.com/tisnik/c3-examples/blob/master/c3-control-flow/22_nested_loops.c3
79 23_break.c3 vnořené programové smyčky a příkaz break: ukončení vnitřní smyčky https://github.com/tisnik/c3-examples/blob/master/c3-control-flow/23_break.c3
80 24_break.c3 vnořené programové smyčky a příkaz break: ukončení vnější smyčky https://github.com/tisnik/c3-examples/blob/master/c3-control-flow/24_break.c3
81 25_break.c3 vnořené programové smyčky a příkaz break, varianta se smyčkami typu while https://github.com/tisnik/c3-examples/blob/master/c3-control-flow/25_break.c3

20. Odkazy na Internetu

  1. Programovací jazyk C3: evoluce, nikoli revoluce
    https://www.root.cz/clanky/pro­gramovaci-jazyk-c3-evoluce-nikoli-revoluce/
  2. Programovací jazyk C3: datové typy pro moderní architektury
    https://www.root.cz/clanky/pro­gramovaci-jazyk-c3-datove-typy-pro-moderni-architektury/
  3. Programovací jazyk C3: složené datové typy a kontejnery
    https://www.root.cz/clanky/pro­gramovaci-jazyk-c3-slozene-datove-typy-a-kontejnery/
  4. The C3 Programming Language
    https://c3-lang.org/
  5. C3 For C Programmers
    https://c3-lang.org/language-overview/primer/
  6. C3 is a C-like language trying to be an incremental improvement over C rather than a whole new language
    https://www.reddit.com/r/Pro­grammingLanguages/comments/o­ohij6/c3_is_a_clike_langu­age_trying_to_be_an/
  7. Tiobe index
    https://www.tiobe.com/tiobe-index/
  8. PYPL PopularitY of Programming Language
    https://pypl.github.io/PYPL.html
  9. C3 Tutorial
    https://learn-c3.org/
  10. History of programming languages
    https://devskiller.com/history-of-programming-languages/
  11. History of programming languages (Wikipedia)
    https://en.wikipedia.org/wi­ki/History_of_programming_lan­guages
  12. D language
    https://dlang.org/
  13. Zig programming language
    https://ziglang.org/
  14. V language
    https://vlang.io/
  15. D programming language
    https://en.wikipedia.org/wi­ki/D_(programming_language)
  16. Zig programming language (Wikipedia)
    https://en.wikipedia.org/wi­ki/Zig_(programming_langu­age)
  17. V programming language (Wikipedia)
    https://en.wikipedia.org/wi­ki/V_(programming_language)
  18. Syntax highlighting for C3's programming language
    https://github.com/Airbus5717/c3.vim
  19. Go factorial
    https://gist.github.com/e­simov/9622710
  20. Generational list of programming languages
    https://en.wikipedia.org/wi­ki/Generational_list_of_pro­gramming_languages
  21. The Language Tree: Almost Every Programming Language Ever Made
    https://github.com/Phileo­sopher/langmap
  22. List of C-family programming languages
    https://en.wikipedia.org/wi­ki/List_of_C-family_programming_languages
  23. Compatibility of C and C++
    https://en.wikipedia.org/wi­ki/Compatibility_of_C_and_C%2B%2B
  24. C++23: compatibility with C
    https://www.sandordargo.com/blog/2023/08/23/cpp­23-c-compatibility
  25. Can C++ Run C Code? Understanding Language Compatibility
    https://www.codewithc.com/can-c-run-c-code-understanding-language-compatibility/
  26. C3: Comparisons With Other Languages
    https://c3-lang.org/faq/compare-languages/
  27. C3 Programming Language Gains Traction as Modern C Alternative
    https://biggo.com/news/202504040125_C3_Pro­gramming_Language_Alterna­tive_to_C
  28. The case against a C alternative
    https://c3.handmade.networ­k/blog/p/8486-the_case_against_a_c_alternative
  29. C (programming language) Alternatives
    https://alternativeto.net/software/c-programming-language-/
  30. Seriál Programovací jazyk Go
    https://www.root.cz/seria­ly/programovaci-jazyk-go/
  31. Is C3 the Underdog That Will Overtake Zig and Odin?
    https://bitshifters.cc/2025/05/22/c3-c-tradition.html
  32. „Hello, World!“ program
    https://en.wikipedia.org/wi­ki/%22Hello%2C_World!%22_pro­gram
  33. The C Programming Language
    https://en.wikipedia.org/wi­ki/The_C_Programming_Langu­age
  34. Kontejner (abstraktní datový typ)
    https://cs.wikipedia.org/wi­ki/Kontejner_(abstraktn%C3%AD_da­tov%C3%BD_typ)
  35. Are arrays not considered containers because they are not based off of a class?
    https://stackoverflow.com/qu­estions/37710975/are-arrays-not-considered-containers-because-they-are-not-based-off-of-a-class
  36. Array declaration (C, C++)
    https://en.cppreference.com/w/cpp/lan­guage/array.html
  37. Understanding the Apple ‘goto fail;’ vulnerability
    https://www.blackduck.com/blog/un­derstanding-apple-goto-fail-vulnerability-2.html
  38. Branch (computer science)
    https://en.wikipedia.org/wi­ki/Branch_(computer_scien­ce)
  39. Conditional (computer programming)
    https://en.wikipedia.org/wi­ki/Conditional_(computer_pro­gramming)
  40. Dangling else
    https://en.wikipedia.org/wi­ki/Dangling_else
  41. Switch statement
    https://en.wikipedia.org/wi­ki/Switch_statement
Neutrální ikona do widgetu na odběr článků ze seriálů

Zajímá vás toto téma? Chcete se o něm dozvědět víc?

Objednejte si upozornění na nově vydané články do vašeho mailu. Žádný článek vám tak neuteče.


Autor článku

Vystudoval VUT FIT a v současné době pracuje na projektech vytvářených v jazycích Python a Go.