14. Pole II
  1. Následující funkce provádí hledání zadané hodnoty X v prvních N prvcích pole A.

  2. int vyskyt(int N, int A[], int X)
    {
      int i;
      for (i = 0; i < N; i++) if (A[i] == X) return i;
      return -1;
    }
    Funkce vrací index výskytu prvku, není-li hodnota v poli obsažena, je vráceno -1. Vytvořte obdobnou funkci, která bude zjišťovat, zda zadaný znak je obsažen v poli znaků. Funkci použijte v konzolové aplikaci, která přečte větu ukončenou tečkou a která zjistí celkový počet výskytů samohlásek v této větě (všechny samohlásky uložíme do pole prvků typu char a k určení zda znak je samohláska použijeme upravenou funkci).
  3. Následující funkce provádí řazení pole n hodnot typu int. Pole je řazeno vzestupně.

  4. void razeni(int n, int a[])
    {
      int i, priznak, pom;
      do {
        priznak = 0;
        for (i = 0; i < n-1; i++)
          if (a[i] > a[i+1]) {
            pom = a[i];
            a[i] = a[i+1];
            a[i+1] = pom;
            priznak = 1;
          }
      } while (priznak);
    }
    Změňte tuto funkci tak, aby prováděla řazení pole s prvky typu double a použijte ji v programu, kde takovéto pole přečtete, necháte je seřadit a opět je vypíšete.
  5. C++ nepodporuje řetězcové proměnné (proměnné, které obsahují text). Řetězce v programech C++ jsou reprezentovány poli datového typu char. Např. znakovému poli lze přiřadit řetězec takto:

  6. char text[] = "Toto je řetězec.";
    Tím alokujeme 17 slabik v paměti a uložíme řetězec na toto místo. Pokud spočítáme znaky našeho řetězce, zjistíme, že jich je pouze 16. Poslední 17 slabika je alokována pro uložení ukončujícího znaku řetězce  (tento znak je na konec řetězce vložen automaticky). Ukončující znak je speciální znak, který je reprezentován konstantou '\0', což je ekvivalentní s číslem 0.
  7. Když program nalezne ve znakovém poli znak s kódem 0, interpretuje jej jako konec řetězce. To nám ukáže následující konzolová aplikace.

  8. int main(int argc, char **argv)
    {
      char ret[] = "Toto je řetězec.";
      cout << ret << endl;
      ret[7] = '\0';
      cout << ret << endl;
      getch();
      return 0;
    }
    Původně znakové pole obsahovalo znaky Toto je řetězec. následované ukončujícím znakem. Tento řetězec je vypsán. Další příkaz vloží ukončující znak za sedmý prvek pole. Když znakové pole opět vypíšeme, pak je vypsáno pouze prvních sedm znaků pole (do ukončujícího znaku pole). Zbytek pole je již za ukončujícím znakem a není již součástí našeho řetězce.
    Namísto znaku '\0' můžeme jednoduše používat 0. Následující dva řádky kódu jsou ekvivalentní:
      ret[7] = '\0';
      ret[7] = 0;
    Nezapoměnte na rozdíl mezi apostrofy a uvozovkami. Když přižazujeme ukončující znak (nebo jinou znakovou konstantu), pak používáme apostrofy. Při práci se znakovými řetězci (více znaků), pak je nutno používat uvozovky.
  9. Pro práci s řetězci (porovnávání řetězců, kopírování apod.) používáme funkce z hlavičkového souboru string.h. Nejdůležitější funkce z tohoto hlavičkového souboru jsou: strcpy (kopírování znaků řetězce), strcat (připojuje řetězec k jinému řetězci), strchr (hledá znak v řetězci), strcmp (porovnávání řetězců), strcmpi (porovnávání řetězců bez rozlišení velikosti písmen), strlen (délka řetězce), strlwr (převádí velká písmena v řetězci na malá), strrev (obrací řetězec), strstr (hledání podřetězce v řetězci) a strupr (převádí malá písmena v řetězci na velká). Řetězec můžeme číst datovým proudem cin. Výstup řetězců provádíme datovým proudem cout.

  10. Tyto funkce byly zavedeny již v jazyku C. Při vytváření aplikací GUI budemo při práci s řetězci používat třídu AnsiString (viz dále).
    Následuje několik příkladů manipulace s řetězci. Funkce strcpy se používá ke kopírování jednoho řetězce do jiného. Zdrojový řetězec může být proměnná nebo řetězcová konstanta.
    // vytvoření proměnné pro uložení 29 znaků
    char buff[30];
    // kopírování řetězcové konstanty do buff
    strcpy(buff, "Toto je test.");
    // zobrazení buff
    cout << buff << endl;
    // inicializace druhého buferu
    char buff2[] = "Druhý řetězec.";
    // kopírování obsahu buff2 do buff
    strcpy(buff, buff2);
    cout << buff << endl;
    Stejně jako u číselných polí, i u znakových polí se nesmí překročit konec pole. Např.
    char buff[10] = "Řetězec";
    // a někdy později
    strcpy(buff, "Toto je test.");
    Způsobí chybu, neboť do buff je možno uložit pouze řetězec o devíti znacích (a ukončující znak). V tomto případě opět dojde k přepsání nějakých informací uložených za polem.
    Jinou často používanou funkcí je sprintf. Tato funkce umožňuje vytvářet formátované řetězce mícháním textu a hodnot. S touto funkcí jsme se již v našich programech setkali. Následuje příklad použití této funkce:
    char buff[30];
    int x = 20;
    int y = 5;
    sprintf(buff, "%d + %d = %d", x, y, x + y);
    cout << buff;
    Tato část programu nám na obrazovce zobrazí:
    20 + 5 = 25
    Jednoduché zpětné lomítko v řetězci indikuje Escape sekvenci. Např. '\n' pro odřádkování nebo '\t' reprezentuje znak tabulátoru. Pokud v řetězci potřebujeme použít zpětné lomítko musíme zapsat dvě zpětná lomítka. Např.
    strcpy(jmenoSouboru, "c:\\prac\\abc.txt");
    Nemusíme pracovat pouze se znakovými poli, ale můžeme mít také pole znakových polí (pole řetězců). Např.
    char retezec [][20] = {
      "Toto je řetězec 1.",
      "Toto je řetězec 2.",
      "Toto je řetězec 3.",
      "Toto je řetězec 4."
    };
    Tento kód vytváří pole čtyř řetězců, každý může obsahovat až 19 znaků.
  11. Vytvořte program, ve kterém přečtete několik jmen (nepoužívejte jména s diakritickými znaménky), abecedně je seřaďte a opět vypište.
  12. Napište funkci, která přečte jméno a příjmení (jako dva řetězce - používejte pouze písmena anglické abecedy), u příjmení změňte všechny znaky na velká písmena a u jména všechny znaky na malá písmena. Hodnota funkce bude text vytvořený spojením příjmení, mezera, jméno. Tuto funkci vyzkoušejte v nějakém programu.
  13. Vytvořte konzolovou aplikaci, která přečte přirozená čísla n a m a hodnoty matice typu n * m s prvky typu double (předpokládejte, že n < 10 a m < 5). V programu zjistěte průměrnou hodnotu ze všech prvků matice a prvky matice přehledně vypište.

Kontrolní otázky:

  1. Co C++ dělá k zajištění nepřepsání informací za koncem pole?
  2. Co je chybné na následujícím programu?

  3. #include <iostream.h>
    #include <conio.h>
    #pragma hdrstop
    void zobrazText();
    zobrazText()
    {
      cout << "Ahoj." << endl;
    }
  4. Kolik hodnot může vracet funkce?
  5. Co dělá funkce strcpy?
  6. Kolik funkcí může program obsahovat?
  7. Může funkce volat jinou funkci?
  8. Co je chybného na následujícím programu?

  9. #include <iostream.h>
    #include <conio.h>
    #pragma hdrstop
    int main(int argc, char **argv)
    {
      delejNeco();
      return 0;
    }
    void delejNeco()
    {
      cout << "Nyní nic nedělám." << endl;
    }
  10. Podívejte se na tento řádek kódu

  11. char buff[20];
    Kolik znaků může nejvýše obsahovat řetězec, který do proměnné buff uložíme?
  12. Je index prvního prvku pole 0 nebo 1?
Řešení


14. Pole II