Posted in: Různé, Studijní materiály, Vývoj počítačů

Datové struktury v C

Příklad struktur

#include <stdio.h>
#include <stdlib.h>
#include <string.h>

//definice struktury
typedef struct //zahájení definice
{
    char jmeno[31]; //textový řetezec
    int vek; //celé čílo
}UZIVATEL; //pojmenování struktury


void main()
{
    UZIVATEL uzivatle[3]; //založení pole o 3 položkách typu uživatel
    for (int i = 0; i < 3; i++) //cyklus k naplnění pole
    {
        printf("Zadej jméno uživatele: "); //výzva uživateli
        scanf("%30s", &uzivatle[i].jmeno); //načtení textového řetězce do položky jméno ve struktuře uživatel
        printf("Zadej vek: "); //výzva užiovateli
        scanf("%d", &uzivatle[i].vek); //načtení celého čísla do položky věk ve struktuře uživatel
    }
    printf("\n\n"); //dvojité odřádkování
    for (int j = 0; j < 3; j++) //cyklus k vypsání strukutry
    {
        printf("Uživatel na indexu %d\n", j);
        printf("Jméno: %s\n", uzivatle[j].jmeno); //vypsání jména ze struktury uživatel
        printf("Věk: %d\n", uzivatle[j].vek); //vypsání věku ze struktury uživatel
    }
}

Kopírovaní struktur

#include <stdio.h>
#include <stdlib.h>
#include <string.h>

//definice struktury
typedef struct //zahájení definice
{
    char jmeno[31]; //textový řetezec
    int vek; //celé čílo
}UZIVATEL; //pojmenování struktury

void main()
{
    UZIVATEL Karel; //inicializace struktury
    Karel.vek = 20; //přiřazení hodnoty 
    strcpy(Karel.jmeno, "Karel"); //přiřazení stringu jako hodnoty
    UZIVATEL KarelKopie;
    KarelKopie = Karel; //Struktura Karel se zkopíruje do struktury KarelKopie
    //porovníní stuktur Karel a KarelKopie
    if (Karel.jmeno == KarelKopie.jmeno && Karel.vek == KarelKopie.vek){
        printf("Struktury jsou shodne");
    }else{
        printf("Struktuy jsou rozdilne");
    }
}

Porovnání struktur

#include <stdio.h>
#include <stdlib.h>
#include <string.h>

//definice struktury
typedef struct //zahájení definice
{
    char jmeno[31]; //textový řetezec
    int vek; //celé čílo
}UZIVATEL; //pojmenování struktury

void main()
{
    UZIVATEL Karel; //inicializace struktury
    Karel.vek = 20; //přiřazení hodnoty 
    strcpy(Karel.jmeno, "Karel"); //přiřazení stringu jako hodnoty
    UZIVATEL Martin;
    Martin.vek = 20;
    strcpy(Martin.jmeno, "Martin");
    //porovníní stuktur Karel a Martin
    if (Karel.jmeno == Martin.jmeno && Karel.vek == Martin.vek){
        printf("Struktury jsou shodne");
    }else{
        printf("Struktuy jsou rozdilne");
    }
}

Vnořené struktury

#include <stdio.h>
#include <stdlib.h>
#include <string.h>

//definice struktury
typedef struct //zahájení definice
{
    float sirka;
    float delka;
}POLOHA; //pojmenování struktury

//definice struktury
typedef struct //zahájení definice
{
    int id; //textový řetezec
    POLOHA poloha; //vnoření struktur
}VUZ; //pojmenování struktury

//funkce pro posunutí vozu
void VUZposun(VUZ* vuz, float sirka, float delka)
{
    vuz->poloha.delka += delka; //přidání zeměpisné délky do polohy vozu
    vuz->poloha.sirka += sirka; //přidání zeměpisné šířky do polohy vozu
}

void main()
{
    VUZ osobak; //vytvoření struktury jménem osobak
    osobak.id = 1; //uložení hodnoty do prvku struktury
    osobak.poloha.delka = 41.40338; //uložení hodnoty do prvku vnořené struktury
    osobak.poloha.sirka = 2.17403;
    printf("Osobni auto má id %d a začíná na poloze %fN, %fW", osobak.id, osobak.poloha.sirka, osobak.poloha.delka);
    VUZposun(&osobak, 10, 10); //volání funkce s předáním reference na strukturu
    printf("\nOsobni auto má id %d a polohu %fN, %fW", osobak.id, osobak.poloha.sirka, osobak.poloha.delka);
}

Dynamicky alokovaná struktura

#include <stdio.h>
#include <stdlib.h>
#include <string.h>

//definice struktury
typedef struct //zahájení definice
{
    char jmeno[31]; //textový řetezec
    int vek; //celé čílo
}UZIVATEL; //pojmenování struktury

void main()
{
    UZIVATEL *ukazatel; //ukazatel na stukturu Uzivatel
    //dynamická alokace struktury v paměti
    ukazatel = (UZIVATEL*) malloc(sizeof(UZIVATEL));
    //přítup ke členům struktury
    ukazatel->vek = 2; //přiřazení celého čísla pomocí ukazatele
    strcpy(ukazatel->jmeno, "Michal"); //přiřazení textu pomocí ukazatele
    //vypsání obsahu dynamicky alokované struktury
    printf("Malý %s chodí do školky už ve %d letech", ukazatel->jmeno, ukazatel->vek);
    free(ukazatel); //uvolnění dynamicky alokované struktury
}

Spojový seznam

#include <stdio.h>
#include <stdlib.h>
#include <string.h>

//definice prvku spojového seznamu
typedef struct  
{
  int cislo; //data
  //další datové položky různých typů
  struct data *nasl, *pred; //ukazatel na následující a předchozí prvek seznamu
}SEZNAM; //pojmenování prvku seznamu

void main()
{
  SEZNAM *prvni = NULL; //inicializace spojového seznamu
  //alokace paměti pro nový prvek
  SEZNAM *novy = (SEZNAM*) malloc(sizeof(SEZNAM)); 
  if(novy == NULL) //kontroloa alokování paměti  
  {                                  
    printf("Nedostatek pameti !\n");                                    
    system("pause");               
    exit(1);                        
  }     
  //inicializace ukazatelů
  novy->pred = NULL;                       
  novy->nasl = NULL; 
  //naplneni dat
  printf("Zadej cele cislo: ");
  scanf("%d", &novy->cislo);
  //zařazeni na začátek seznamu
  if (prvni == NULL) //pokud byl seznam prázdný, zařadí se na první místo                           
  {                                                     
    prvni = novy;                  
	}                                             
	else                   
  {
    prvni->pred = novy; //zařazení před první prvek                
    novy->nasl = prvni; //nastavení následujícího záznamu v aktuálně vkládaném prvku                       
    prvni = novy; //kopírování dat    
  }   
  //výpis seznamu
  for (SEZNAM *i = prvni; i != NULL; i = i ->nasl) //definice cyklu procházejícího seznam
  {
    printf("%d, ", i->cislo); //vypsání číslené datov hodnoty
    free(i->pred); //uvolnění alokované paměti předešlého prvku
  }  
}

Deklarace enum

#include <stdio.h>
#include <stdlib.h>
#include <string.h>

//definice enum
typedef enum //zahájení definice
{
    zelena, oranzova, cervena
}barva; //pojmenování enum

void main()
{
    barva semafor;
    semafor = zelena;
    switch (semafor)
    {
    case 0:
        printf("Můžeš jít");
        break;
    case 1:
        printf("Připrav se");
        break;
    case 2:
        printf("Stůj");
        break;
    default:
        printf("Nevalidní hodnota");
        break;
    }
}

Union

#include <stdio.h>
#include <stdlib.h>
#include <string.h>

//definice unie
typedef union
{
  int cislo;
  char znak;
} unie; //pojmenování struktury
// unie bude mít velikost rovnou sizeof(int)

void main()
{
  unie ZnakCislo; //inicializace unie
  ZnakCislo.cislo = 101; // v unii bude číslo 101
  if (ZnakCislo.znak == 'e')
  {
    printf("Do unie bylo ascii kódem vloženo písmeno e");
  }
}
Posted in: Různé, Studijní materiály, Vývoj počítačů

Dynamická alokace paměti v C

Aneb ďábel v podobě ukazatele

Globální proměnné

#include <stdlib.h>;
#include <stdio.h>;
//globalni promene udavajici hodnoty pro cely program
int x = 2;
const int y = 3; //y je konstantou
//hlavni funkce programu
void main()
{
	//lokalni promene
	int z = 5;
	//kontrolni vypis hodnot promennych
	printf("Hodnota promene x je %d, hodnota y je %d a hodnota z je %d \n", x, y, z);
	//zastinenni promenne y, jeji redefinice
	int y = 9;
	printf("Hodnota promene x je %d, hodnota y je %d a hodnota z je %d \n", x, y, z);
	printf("Press any key to continue...");
	getchar();
}

Definice ukazatele

#include <stdio.h>
#include <stdlib.h>
void main()
{
    int a; //alokace proměnné a
    int *p_a; //alokace ukazatele
    a = 56; //uožení hodnoty do proměnné a
    p_a = &a; //uložení adresy proměnné a do ukazatele p_a
    printf("Proměnná a s hodnotou %d je v paměti uložená na adrese %p", a, p_a);
    *p_a = 2; //zápis hodnoty 2 na adresu v ukazateli
    printf("\nUkazatel p_a má hodnotu %d a ukazuje na hodnotu %d", p_a, *p_a);
}

Dynamicky alokovaná paměť

#include <stdio.h>
#include <stdlib.h>

int main()
{
    int velikost; //určuje počet jednotek, pro které se bude alokovat paměť
    do //ošetření vstupu
    {
        printf("Zadej pocet cisel: "); //výzva uživateli k zadání početu
        if (scanf("%d", &velikost) == 1) //ošetření vstupu
        {
            getchar();
            break;
        }
        else
        {
            printf("Nebylo zadano cele cislo, opakuj zadani\n");
        }
    } while (1); //konec osetreni vstupu
    float *p_i;
    printf("Pokousim se alokovat prostor pro %d cisel...", velikost);
    //dynamická alokace paměti na haldě
    p_i = (float *) malloc(sizeof(float)*velikost);
    //kontrola úspěšnosti alokace paměti
    if (p_i == NULL) //výpis chyby alokace a ukončení programu
    {
        printf("Nedostatek paměti!");
        return (-1);
    }
    //uvolnění paměti
    printf("\nUvolnuji uspesne alokovanou pamet...");
    free(p_i); //samostné uvolnění paměti z haldy
    p_i = NULL; //vymazání ukazatele
    return 0;
}

Procházení bloku paměti

#include <stdio.h>
#include <stdlib.h>

void main()
{
    int *p_i, *p_paty;
    // Alokace 100 krát velikosti intu
    p_i = (int *) malloc(sizeof(int) * 100); //dynamická alokace paměti na haldě
    if (p_i == NULL)
    {
        printf("Nedostatek paměti.\n");
        exit(1);
    }
    printf("Alokovana pamet zacina na adrese %p", p_i);
    //vynulování paměti
    for(int i = 0; i < 100; i++)
    {
        p_i[i] = 0; //zápis nuly do daného bloku paměti
    }
    printf("\nNulovani pameti dokonceno");
    //zápis 1 pomocí pointrové aritmetiky - rychlejší postup
    int *p_pozice;
    for (p_pozice = p_i; p_pozice < p_i+100; p_pozice++) //výpočet jednotlivých adres v cyklu
    {
        *p_pozice = 1;
    }
    printf("\nNaplneni pameti jednickami dokonceno");
    free(p_i); // Uvolnění paměti
    p_i = NULL; // Vymazání ukazatele
}

Předávání hodnot referencí

#include <stdio.h>
#include <stdlib.h>

void prohod(int *p_a, int *p_b) //parametry jsou ukazatele
{
    int pomocna = *p_a; //ulozeni hodnoty referované ukazatelem p_a do pomocna
    *p_a = *p_b;  //zápis hodnoty z adresy p_b na adresu p_a
    *p_b = pomocna; //uložení původní hodnoty z adresy p_a na adresu p_b
}

void main() {
    int cislo1 = 15; //inicializace proměnné
    int cislo2 = 8; //inicializace proměnné
    prohod(&cislo1, &cislo2); //volání funkce s použitím referenčního operátoru
    printf("V cislo1 je číslo %d a v cislo2 je číslo %d.", cislo1, cislo2);
}

Předávání polí

#include <stdio.h>
#include <stdlib.h>
#define DELKA 10

void napln_pole(int pole[])
{
    for (int i = 0; i < DELKA; i++)
    {
        pole[i] = i + 1; //naplní pole hodnotami 1 až 10
    }
}

void main() {
    int cisla[DELKA]; //deklaruje datovou strukturu pole typu int o 10 prvcích
    napln_pole(cisla); //zavolá funkce napln_pole a předá refeneci na pole
    printf("%d", cisla[5]); // Vypíše číslo 6
}

Výpočet adresy N. prvku paměti

#include <stdio.h>
#include <stdlib.h>

void main()
{
    int *p_i, *p_paty;
    // Alokace 100 krát velikosti intu
    p_i = (int *) malloc(sizeof(int) * 100); //dynamická alokace paměti na haldě
    if (p_i == NULL)
    {
        printf("Nedostatek paměti.\n");
        exit(1);
    }
    printf("Alokovana pamet zacina na adrese %p", p_i);
    p_paty = p_i + 4; // Výpočet adresy pátého prvku
    printf("\n5. prvek alokovane pameti lezi na adrese %p", p_i);
    *p_paty = 56; // Uložení hodnoty na pátý prvek
    printf("\n5. prvek alokovane pameti obsahuje hodnotu %d", *p_paty);
    free(p_i); // Uvolnění paměti
    p_i = NULL; // Vymazání ukazatele
}

Callock

#include <stdlib.h>
#include <stdio.h>

int main()
{
       int *b; //ukazatel na int
       b = (int *)calloc(200, sizeof(int)); //vytvoří pole o 200 intech
       if (b == NULL)
       {
             printf("Nedostatek paměti");
             return (-1);
       }
       else
       {
             printf("Úspěšně alokováno");
       }
       free(b); //uvolnění alokované paměti
       return 0;
}

Reallock

#include <stdio.h>
#include <stdlib.h>

int main() 
{
  int *b; //uakzatel na int
  b = (int *)calloc(10, sizeof(int)); //vynulované dynamické pole pro 10 intů
  if (b == NULL)
  {
    printf("Nedostatek paměti");
    return (-1);
  }
  for (int i = 0; i < 10; i++)
  {
    b[i] = i * 10; //naplnění hodnotami 0 až 90 po desítkách
  }
  int *temp; //pomocný ukazatel
  //není vhodné ukládat o původního ukazatele, protože při neúspěchu
  //realokace bychom přišli o původní pole
  temp = (int *) realloc(b, sizeof(int) * 11); //realokace pole, které je o 1 položku větší
  if (temp == NULL)   //validace úspěčné realokace
  {
    printf("Nedostatek paměti");
    free(b);
    return (-1);
  }
  else
  {
    b = temp; //b ukazuje na nově realokovanou paměť
  }
  b[10] = 100; //zápis do nově aplokované části pole b
  for (int i = 0; i < 11; i++)
  {
    printf("%d", b[i]);   //výpis hodnot ze zvětšeného pole
  }
  free(b); //uvolnění pole b z paměti
  b = NULL; //zrušení ukazatele b
}

Dynamická paměť pro text

#include <stdio.h>
#include <stdlib.h>
#include <string.h>

void main()
{
    char buffer[101]; //pomocný statický řetězec
    printf("Zadej jméno: ");
    scanf(" %100s[^\n]", buffer); // Načtení jména do pomocné paměti
    // Vytvoření dynamického řetězce
    char* jmeno = (char *) malloc(strlen(buffer) + 1);
    strcpy(jmeno, buffer); // Nastavení hodnoty
    buffer[0] = '\0'; //vymazání vstupu   
    printf("Zadej prijmeni: ");
    scanf(" %100s[^\n]", buffer); //opakovane pouziti bufferu
    char* prijmeni = (char *) malloc(strlen(buffer) + 1); // Vytvoření dynamického řetězce
    strcpy(prijmeni, buffer); // Nastavení hodnoty
    printf("Jmenuješ se %s %s", jmeno, prijmeni);
    free(jmeno); // Uvolnění paměti
}

2D pole

#include <stdlib.h>
#include <stdio.h>

int main()
{
  //technika ukazatel na ukazatele
  //dynamické 2D pole pro celá čísla (3x5)
  int **matice; //definuje ukazatel na ukazatele na int
  matice = (int **)malloc(sizeof(int *) * 3); //alokuje paměť pro 3 ukazatele na typ int
  if (matice == NULL)
  {
    printf("Nedostatek pameti");
    return (-1);
  }
  for (int i = 0; i < 3; i++) //projde sadu ukazatelů
  {
    matice[i] = (int *)calloc(5, sizeof(int)); //dynamická paměti pro 5 intů
    if (matice[i] == NULL)
    {
      printf("Nedostatek pameti");
      return (-1);
    }
  }
  //nyní je hotová dynamická alokace paměti a s polem pracujeme jakoí se statickým
  //uložení číslených hodnot 1 - 15 do pole
  int t = 1;
  for (int i = 0; i < 3; i++) //prochází řádky
  {
    for (int j = 0; j < 5; j++) //prochází sloupce
    {
      matice[i][j] = t; //zápis hodnoty t do pole
      t++; //inkrementace proměnné t
    }
  }
  //výpis pole
  for (int i = 0; i < 3; i++) //prochází řádky
  {
    for (int j = 0; j < 5; j++) //prochází sloupce
    {
      printf("%d, ", matice[i][j]);
    }
  }
  //uvolnění paměti
  for (int i = 0; i < 3; i++)
  {
    free(matice[i]); //uvolnění jednotlivých řádků
  }
  free(matice); //uvolnění ukazatele na ukazatele 
  return(0); //ukončení s kódem 0
}

2D pole varianta 2

#include <stdlib.h>
#include <stdio.h>

int main()
{
       //dynamické 2D pole
       //technika ukazatel na ukazatele

       //dynamické 2D pole pro celá čísla (libovolná velikost)
       int rady = 0, sloupce = 0;
       //načtení rozměru matice ze vstupu
       do
       {
             printf("Zadej pocet radku a pocet sloupcu oddelene mezerou: ");
             if (scanf_s("%d %d", &rady, &sloupce) == 2)
             {
                    getchar();
                    break;
             }
             printf("Nevalidni vstup, opakuj zadani\n");
             getchar();
       } while (1);
       int **matice; //definuje ukazatel na ukazatele na int
       matice = (int **)malloc(sizeof(int *) * rady);  //alokuje paměť pro ukazatele na typ int
       if (matice == NULL)
       {
             printf("Nedostatek pameti");
             return (-1);
       }
       for (int i = 0; i < rady; i++)    //projde sadu ukazatelů
       {
             matice[i] = (int *)calloc(sloupce, sizeof(int)); //dynamická paměti pro samotné hodnoty
             if (matice[i] == NULL)
             {
                    printf("Nedostatek pameti");
                    return (-1);
             }
       }
       //nyní je hotová dynamická alokace paměti a s polem pracujeme jakoí se statickým
       //načtení čísel ze vstupu do pole
       printf("\n"); //odřádkování výpisu
       for (int i = 0; i < rady; i++)    //prochází řádky
       {
             for (int j = 0; j < sloupce; j++) //prochází sloupce
             {
                    do
                    {
                          printf("Zadej cele cislo: ");
                          if (scanf_s("%d", &matice[i][j]) == 1)   //načtení hodnoty do pole
                          {
                                 getchar();
                                 break;
                          }
                          printf("Nevalidni vstup, opakuj zadani\n");
                          getchar();
                    } while (1);
             }
       }
       //výpis pole
       printf("Obsah pole: \n");
       for (int i = 0; i < rady; i++)    //prochází řádky
       {
             for (int j = 0; j < sloupce; j++) //prochází sloupce
             {
                    printf("%d, ", matice[i][j]);
             }
             printf("\n");
       }
       //uvolnění paměti
       for (int i = 0; i < rady; i++)
       {
             free(matice[i]); //uvolnění jednotlivých řádků
       }
       free(matice); //uvolnění ukazatele na ukazatele 
       return(0); //ukončení s kódem 0
}

Simulace 2D pole 1D polem

#include <stdlib.h>
#include <stdio.h>

int main()
{
  //dynamické 2D pole
  //použitím jednoho ukazatele - souvyslý blok paměti

  //dynamické 2D pole pro celá čísla (libovolná velikost)
  int rady = 0, sloupce = 0;
  //načtení rozměru matice ze vstupu
  do
  {
    printf("Zadej pocet radku a pocet sloupcu oddelene mezerou: ");
    if (scanf_s("%d %d", &rady, &sloupce) == 2)
    {
      getchar();
      break;
    }
    printf("Nevalidni vstup, opakuj zadani\n");
    getchar();
  } while (1);
  int *matice; //definuje ukazatel
  matice = (int *)calloc((sloupce * rady), sizeof(int)); //alokuje pro celou matici jako souvislý blok
  if (matice == NULL)
  {
    printf("Nedostatek pameti");
    return (-1);
  }
  //nyní je hotová dynamická alokace paměti a s polem pracujeme jakoí se statickým
  //načtení čísel ze vstupu do pole
  printf("\n"); //odřádkování výpisu
  for (int i = 0; i < rady; i++)    //prochází řádky
  {
    for (int j = 0; j < sloupce; j++) //prochází sloupce
    {
      do
      {
        printf("Zadej cele cislo: ");
        if (scanf_s("%d", &matice[i * sloupce +j]) == 1)  //i * sloupce +j //výpočet reálného jednorozměrného indexu
        {
          getchar();
          break;
        }
        printf("Nevalidni vstup, opakuj zadani\n");
        getchar();
      } while (1);
    }
  }
  //výpis pole
  printf("Obsah pole: \n");
  for (int i = 0; i < rady; i++)    //prochází řádky
  {
    for (int j = 0; j < sloupce; j++) //prochází sloupce
    {
      printf("%d, ", matice[i * sloupce + j]);
    }
    printf("\n");
  }
  //uvolnění paměti
  free(matice); //uvolnění reálně jednorozměrného pole 
  return(0); //ukončení s kódem 0
}
Posted in: Různé, Studijní materiály, Vývoj počítačů

Textové řetězce

Jak na texty, na které se v C na první pohled zapomnělo…

ASCII ART, které s tématem nesouvisí 😉

#include <stdio.h>

int main() {
    char znak;

    printf("Zadejte prosím jeden znak: ");
    scanf_s(" %c", &znak,1);

    printf("\n");
    printf(" %c %c %c %c %c    %c    %c   %c%c%c%c      %c%c%c%c%c   %c%c%c%c    %c   %c     %c%c         %c%c%c%c%c%c    %c%c%c%c%c    %c      %c       %c%c\n", znak, znak, znak, znak, znak, znak, znak, znak, znak, znak, znak, znak, znak, znak, znak, znak, znak, znak, znak, znak, znak, znak, znak, znak, znak, znak, znak, znak, znak, znak, znak, znak, znak, znak, znak, znak, znak, znak, znak, znak);
    printf("     %c        %c%c   %c   %c         %c   %c   %c   %c   %c%c %c%c     %c%c           %c         %c      %c    %c         %c%c\n", znak, znak, znak, znak, znak, znak, znak, znak, znak, znak, znak, znak, znak, znak, znak, znak, znak, znak, znak, znak, znak, znak, znak, znak, znak, znak, znak, znak, znak, znak, znak);
    printf("     %c        %c %c  %c   %c         %c   %c   %c   %c   %c %c %c    %c  %c          %c         %c      %c  %c          %c  %c\n", znak, znak, znak, znak, znak, znak, znak, znak, znak, znak, znak, znak, znak, znak, znak, znak, znak, znak, znak, znak, znak, znak, znak, znak, znak, znak, znak, znak, znak, znak, znak);
    printf("     %c        %c  %c %c   %c%c%c%c      %c   %c   %c%c%c%c    %c   %c    %c%c%c%c          %c         %c       %c%c           %c%c%c%c\n", znak, znak, znak, znak, znak, znak, znak, znak, znak, znak, znak, znak, znak, znak, znak, znak, znak, znak, znak, znak, znak, znak, znak, znak, znak, znak, znak, znak, znak, znak, znak);
    printf("     %c        %c   %c%c   %c         %c   %c   %c  %c    %c   %c   %c    %c         %c         %c      %c  %c         %c    %c\n", znak, znak, znak, znak, znak, znak, znak, znak, znak, znak, znak, znak, znak, znak, znak, znak, znak, znak, znak, znak, znak, znak, znak, znak, znak, znak, znak, znak, znak, znak, znak);
    printf(" %c %c %c %c %c    %c    %c   %c         %c%c%c%c%c   %c   %c   %c   %c  %c      %c        %c       %c%c%c%c%c    %c    %c      %c      %c\n", znak, znak, znak, znak, znak, znak, znak, znak, znak, znak, znak, znak, znak, znak, znak, znak, znak, znak, znak, znak, znak, znak, znak, znak, znak, znak, znak, znak, znak, znak, znak);
}
;
Posted in: Různé, Studijní materiály, Vývoj počítačů

Statická pole v C

Není pole jako pole…

Příklady pole

//direktivy
#include <stdio.h>
#include <stdlib.h>
//konstanty formou makra
#define POCET 10

//globalni promenne a konstanty (hodnota konstanty v pameti aplikace)
int delka = 0;

//hlavnnei telo programu
void main()
{
	//pole zalozene inicializaci
	char text[] = { 'T', 'e', 'x', 't', ' ', 'p', 'o', 'l', 'e' };
	
	//zjisteni delky pole
	delka = sizeof(text) / sizeof(char); //sizeof urci delku datovaho typu, u poli se musi vydelit velikosti datoveho typu
	
	//vypsani celeho pole cyklem
	for (int i = 0; i < delka; i++) //i musi byt mensi nez delka, protoze pole se indexuje od 0
	{
		printf("%c", text[i]); //hodnota i udava, který index pole je vypsan
	}

	//pole zalozene bez inicializace
	int cisloA[10]; //zalozi pole pro 10 cisel, ktere je prazdne

	//naplneni pole cisli
	for (int j = 0; j < POCET; j++)
	{
		cisloA[j] = j + 1; //do první polozky pole se prida cislo 1
	}

	//vypsani male nasobilky
	printf("\n\n");
	printf("Mala nasobilka\n");
	for (int k = 0; k < POCET; k++)
	{
		for (int l = 0; l < POCET; l++)
		{
			printf("%d ", cisloA[k] * cisloA[l]);
		}
		printf("\n"); //odradkovani na konci radku
	}
	printf("\n"); //odradkovani za vypisem

	//pole zalozene pomoci konstanty
	int cisla[POCET];

	//naplneni pole 10 cisli
	printf("Bude potreba zadat 10 celych cisel\n");
	for (int i = 0; i < POCET; i++)
	{
		printf("Zadej cele cislo: ");
		scanf_s("%d",&cisla[i],1);
		getchar();
	}
	printf("\nDekuji za zadani\n");

	//serazeni pole algoritmem insertsort
	int pamet, j; //pomocné proměnné
	for (int i = 1; i < POCET; i++)
	{
		pamet = cisla[i];
		j = i - 1;
		while ((j >= 0) && (cisla[j] > pamet))
		{
			cisla[j + 1] = cisla[j];
			j--; //to same jako j = j -1;
		}
		cisla[j + 1] = pamet;
	}

	printf("\nCisla serazena od nejmensiho k nejvetsimu:\n\n");
	//vypsis setrizeneho pole
	for (int i = 0; i < POCET; i++)
	{
		printf("%d, ", cisla[i]);
	}
	printf("\n\n");
	printf("Press any key to continue...");
	getchar();
}
Posted in: Různé, Studijní materiály, Vývoj počítačů

Ošetření uživatelského vstupu v C

Jak v C realizovat rčení Margaret Hamilton, že uživatelé chybují a počítače s tím musí počítat.

Základní ošetření pomocí IF a masky příkazu scanf

#include <stdio.h>

#include <stdbool.h> //umozni poutivat logicke funkce



void main()

{

    int celeCislo;

    do

    {

        printf("Zadej cele cislo: ");

        if (scanf("%d", &celeCislo) == 1)

        {

            break; //ukonci nekonecny cyklus

        }

        else

        {

            printf("Na vstupu neni cislo, opakuj zadani\n");

            getchar(); //snaze potvrzovaci enter z bufferu vstupu

        }

    } while (true);

    getchar(); //snaze potvrzovaci enter z bufferu vstupu

    printf("Zadane cislo je %d.", celeCislo);

    float DesetinnneCislo;

    printf("Zadane cislo je %d.", celeCislo);

    do

    {

        printf("\nZadej desetinne cislo: ");

        if (scanf("%f", &DesetinnneCislo) == 1)

        {

            break;

        }

        else

        {

            printf("Na vstupu neni cislo, opakuj zadani\n");

            getchar();

        }

    } while (true);

    getchar(); //snaze potvrzovaci enter z bufferu vstupu

    printf("Zadane cislo je %f.", DesetinnneCislo);

}

Přetypování ze stringu pomocí knihovních funkcí

#include <stdio.h>
#include <ctype.h> //validace datovych typu
#include <stdlib.h>
#include <string.h> //textove retezce
#include <stdbool.h> //datovy typ bool
#define BUFFER_SIZE 4096 //velikost bufferu

bool parse_int(char* string, int* integer)
{
	//na vstupu prijme string a vrati true a hdonotu integeru, pokud je stringem cele cislo
	//odmaze pripadne mezery a taby kolem cisla
	int i = 0; //idex pocatku retezce
	while (isspace(string[i])) //dokud je pred prvkem mezera, novy radek nebo tab
	{
		i++; //nastavi index na zacatek nejake hodnoty
	}
	int length = strlen(string); //ulozi delku retezce
	if (length == i)
	{
		return false; //reteezec byl prazdny, jen bile znaky
	}
	char integet_buffer[BUFFER_SIZE];
	int integer_chars = 0;
	//detekce zaporne hodnoty
	if (string[i] == '-')
	{
		integet_buffer[integer_chars] = '-';
		integer_chars++;
		i++;
		if (!isdigit(string[i])) //validace, zda je dalsi zank cislo
		{
			return false; //kdyz neni dalsi znak cislo, vracime false
		}
	}
	//nacteni ciselnych hodnot z retezce
	while (i < length && !isspace(string[i])) //doku i je mensi nez delka a zaroven nejde o mezeru
	{
		if (!isdigit(string[i])) //pokud znak neni cislo vrat false
		{
			return false;
		}
		//pokud jde o cislo, pridame jej do bufferu
		integet_buffer[integer_chars] = string[i];
		integer_chars++;
		i++;
	}
	//korektni ukonceni textoveho retezce
	integet_buffer[integer_chars] = '\0';
	*integer = atoi(integet_buffer); //vlastni konverze z retezce na cislo
	return true;
}

bool parse_float(char* string, float* desetinne)
{
	//na vstupu prijme string a vrati true a hdonotu float, pokud je stringem cele cislo
	//odmaze pripadne mezery a taby kolem cisla
	int i = 0; //idex pocatku retezce
	while (isspace(string[i])) //dokud je pred prvkem mezera, novy radek nebo tab
	{
		i++; //nastavi index na zacatek nejake hodnoty
	}
	int length = strlen(string); //ulozi delku retezce
	if (length == i)
	{
		return false; //reteezec byl prazdny, jen bile znaky
	}
	char desetinne_buffer[BUFFER_SIZE];
	int desetinne_chars = 0;
	//detekce zaporne hodnoty
	if (string[i] == '-')
	{
		desetinne_buffer[desetinne_chars] = '-';
		desetinne_chars++;
		i++;
		if (!isdigit(string[i])) //validace, zda je dalsi zank cislo
		{
			return false; //kdyz neni dalsi znak cislo, vracime false
		}
	}
	//nacteni ciselnych hodnot z retezce
	bool carka = false;
	while (i < length && !isspace(string[i])) //doku i je mensi nez delka a zaroven nejde o mezeru
	{
		if((string[i]=='.' || string[i] == ',') && (!carka)) //detekce desetinne carky resp tecky
		{
			desetinne_buffer[desetinne_chars] = '.'; //pridani desetinne carky
			carka = true;
		}
		else if (!isdigit(string[i])) //pokud znak neni cislo vrat false
		{
			return false;
		}
		else
		{
			//pokud jde o cislo, pridame jej do bufferu
			desetinne_buffer[desetinne_chars] = string[i];
		}
		//posun k dalsimu znaku
		desetinne_chars++;
		i++;
	}
	//korektni ukonceni textoveho retezce
	desetinne_buffer[desetinne_chars] = '\0';
	*desetinne = atof(desetinne_buffer); //vlastni konverze z retezce na cislo
	return true;
}

int main()
{
	int cislo;
	float cislo2;
	char buffer[BUFFER_SIZE]; //textove pole pro ulozeni vstupu
	bool uspech = true;
	do
	{
		printf("Zadej cele cislo: ");
		scanf(" %4096[^\n]s", buffer);; //nacteni z konzole do bufferu
		uspech = parse_int(buffer, &cislo); //promenou cislo predavame jako ukazatel v pameti
		if (!uspech)
		{
			printf("Musi byt zadano cele cislo\n");
		}
	} while (!uspech); //dokud neni spravne nacteno
	printf("Zadane cele cislo je %d\n", cislo);
	uspech = true;
	do
	{
		printf("Zadej desetinne cislo: ");
		scanf(" %4096[^\n]s", buffer);; //nacteni z konzole do bufferu
		uspech = parse_float(buffer, &cislo2); //promenou cislo predavame jako ukazatel v pameti
		if (!uspech)
		{
			printf("Musi byt zadano cele cislo\n");
		}
	} while (!uspech); //dokud neni spravne nacteno
	printf("Zadane destinne cislo je %f\n", cislo2);
	return 0;
}

Vlastní konverzní funkce využívající dekadický zápis čísel

#include <stdlib.h>
#include <stdio.h>
#include <math.h>
#include <string.h>
#define DELKA 4096

//vyuzit dekatickeho zapisu pro konverzi string na int
void main()
{
	char text[DELKA]; //pro přímé zadání vstupu
	char cislice[DELKA]; //ocistene cislo
	int cislo = 0; //finalni cislice
	float desetine = 0.0;
	int i = 0, j = 0; //ridici promene
	int zaporne = 0; //detekce zaporne hodnoty
	printf("Zadej cele cislo: ");
	scanf_s("%4096[^\n]s", &text, 4096); //nacteni cisla v podobe textu
	getchar();
	//odmazani mezer a dalsich bilich znaku pred cislem
	for (i = 0; i < DELKA; i++)
	{
		if (!isspace(text[i]))
		{
			break;
		}
	}
	if (i < DELKA)
	{
		if (text[i] == '-') //detekce zaporne hodnoty
		{
			i++;
			zaporne = -1;
		}
		do
		{
			if (isdigit(text[i])) //prevedeni ciselnych hodnot do druheho pole (ciste cislo)
			{
				cislice[j] = text[i]; 
			}
			else if (isspace(text[i])) //mezera za cislem => ukonceni prevodu
			{
				break;
			}
			else if (text[i] == '\0') //znak konce retezce ukonci prevod
			{
				cislice[j] = text[i]; //ukonceni retezce cisteho sicla
				break;
			}else
			{
				printf("Nejde o ciso"); //vypis chyby
				break;
			}
			//povyseni ridicich promenych
			j++;
			i++;
		} while (i < DELKA);
		int mocnina = 0; //hodnota mocniny deseti
		//prevod pomoci dekadickeho zapisu disla (mantisa * deset na pozici)
		for (int d = strlen(cislice) -1; d >= 0; d--)
		{
			switch (cislice[d])
			{
			case '0':
				cislo = cislo + 0 * pow(10, mocnina);
				break;
			case '1':
				cislo = cislo + 1 * pow(10, mocnina);
				break;
			case '2':
				cislo = cislo + 2 * pow(10, mocnina);
				break;
			case '3':
				cislo = cislo + 3 * pow(10, mocnina);
				break;
			case '4':
				cislo = cislo + 4 * pow(10, mocnina);
				break;
			case '5':
				cislo = cislo + 5 * pow(10, mocnina);
				break;
			case '6':
				cislo = cislo + 6 * pow(10, mocnina);
				break;
			case '7':
				cislo = cislo + 7 * pow(10, mocnina);
				break;
			case '8':
				cislo = cislo + 8 * pow(10, mocnina);
				break;
			case '9':
				cislo = cislo + 9 * pow(10, mocnina);
				break;
			default:
				break;
			}
			mocnina++; //povyseni mocniny pro dalsi pozici
		}
		if (zaporne == -1) //realizace zaporne hodnoty
		{
			cislo = cislo * (-1);
		}
	}
	//kontolni vypis cisla
	printf("\n\nZadane cislo je %d", cislo);
	//desetinne cislo
	//nulovani ridicich promennych
	i = 0;
	j = 0; 
	zaporne = 0;
	//nulvani retezcu
	for (int i = 0; i < DELKA; i++)
	{
		text[i] = '\0';
		cislice[i] = '\0';
	}
	i = 0; //opetovne vynulovani
	printf("\n\nZadej desetinne cislo: ");
	scanf_s("%4096[^\n]s", &text, 4096); //nacteni cisla v podobe textu
	//odmazani mezer a dalsich bilich znaku pred cislem
	for (i = 0; i < DELKA; i++)
	{
		if (!isspace(text[i]))
		{
			break;
		}
	}
	if (i < DELKA) //pokud retezec obsahuje jiny nez bily znak
	{
		if (text[i] == '-') //detekce zaporne hodnoty
		{
			i++;
			zaporne = -1;
		}
		do
		{
			if (isdigit(text[i])) //prevedeni ciselnych hodnot do druheho pole (ciste cislo)
			{
				cislice[j] = text[i];
			}
			else if (isspace(text[i])) //mezera za cislem => ukonceni prevodu
			{
				break;
			}
			else if (text[i] == '\0') //znak konce retezce ukonci prevod
			{
				cislice[j] = text[i]; //ukonceni retezce cisteho sicla
				break;
			}
			else if (text[i] == '.' || text[i] == ',') //detekce a prevedeni desetinneho oddelovace
			{
				cislice[j] = text[i];
			}
			else
			{
				printf("Nejde o ciso"); //vypis chyby
				break;
			}
			//povyseni ridicich promenych
			j++;
			i++;
		} while (i < DELKA);
		int mocnina = 0; //hodnota mocniny deseti
		int tecka = -1; //pozice desetineho oddelovace
		for (int k = 0; k < strlen(cislice); k++) //nalezeni pozice desetinneho oddelovace
		{
			if (cislice[k] == '.' || cislice[k] == ',')
			{
				tecka = k;
				break;
			}
		}
		if (tecka > -1) //jestli je desetinna nalezena
		{
			//prevod desetinne casti
			mocnina = 1; //nastaveni na rad desetin
			for (int d = tecka+1; d <strlen(cislice); d++)
			{
				switch (cislice[d])
				{
				case '0':
					desetine = desetine + 0 * pow(10, (mocnina * (-1))); //hodnota cifry * 10 na -cifru
					break;
				case '1':
					desetine = desetine + 1 * pow(10, (mocnina * (-1)));
					break;
				case '2':
					desetine = desetine + 2 * pow(10, (mocnina * (-1)));
					break;
				case '3':
					desetine = desetine + 3 * pow(10, (mocnina * (-1)));
					break;
				case '4':
					desetine = desetine + 4 * pow(10, (mocnina * (-1)));
					break;
				case '5':
					desetine = desetine + 5 * pow(10, (mocnina * (-1)));
					break;
				case '6':
					desetine = desetine + 6 * pow(10, (mocnina * (-1)));
					break;
				case '7':
					desetine = desetine + 7 * pow(10, (mocnina * (-1)));
					break;
				case '8':
					desetine = desetine + 8 * pow(10, (mocnina * (-1)));
					break;
				case '9':
					desetine = desetine + 9 * pow(10, (mocnina * (-1)));
					break;
				default:
					break;
				}
				mocnina++; //povyseni mocniny pro dalsi pozici
			}
			mocnina = 0; //nastaveni mocniny pro rad jednotek
			//prevod cele casti
			for (int d = tecka - 1; d >=0 ; d--)
			{
				switch (cislice[d])
				{
				case '0':
					desetine = desetine + 0 * pow(10, mocnina); //hodnota cifry *10 na cifru
					break;
				case '1':
					desetine = desetine + 1 * pow(10, mocnina);
					break;
				case '2':
					desetine = desetine + 2 * pow(10, mocnina);
					break;
				case '3':
					desetine = desetine + 3 * pow(10, mocnina);
					break;
				case '4':
					desetine = desetine + 4 * pow(10, mocnina);
					break;
				case '5':
					desetine = desetine + 5 * pow(10, mocnina);
					break;
				case '6':
					desetine = desetine + 6 * pow(10, mocnina);
					break;
				case '7':
					desetine = desetine + 7 * pow(10, mocnina);
					break;
				case '8':
					desetine = desetine + 8 * pow(10, mocnina);
					break;
				case '9':
					desetine = desetine + 9 * pow(10, mocnina);
					break;
				default:
					break;
				}
				mocnina++; //povyseni mocniny pro dalsi pozici
			}
		}
		else
		{
			//prevod pomoci dekadickeho zapisu disla (mantisa * deset na pozici)
			for (int d = strlen(cislice) - 1; d >= 0; d--)
			{
				switch (cislice[d])
				{
				case '0':
					desetine = desetine + 0 * pow(10, mocnina);
					break;
				case '1':
					desetine = desetine + 1 * pow(10, mocnina);
					break;
				case '2':
					desetine = desetine + 2 * pow(10, mocnina);
					break;
				case '3':
					desetine = desetine + 3 * pow(10, mocnina);
					break;
				case '4':
					desetine = desetine + 4 * pow(10, mocnina);
					break;
				case '5':
					desetine = desetine + 5 * pow(10, mocnina);
					break;
				case '6':
					desetine = desetine + 6 * pow(10, mocnina);
					break;
				case '7':
					desetine = desetine + 7 * pow(10, mocnina);
					break;
				case '8':
					desetine = desetine + 8 * pow(10, mocnina);
					break;
				case '9':
					desetine = desetine + 9 * pow(10, mocnina);
					break;
				default:
					break;
				}
				mocnina++; //povyseni mocniny pro dalsi pozici
			}
		}
		if (zaporne == -1) //realizace zaporne hodnoty
		{
			desetine = desetine * (-1);
		}
	}
	//kontolni vypis cisla
	printf("\n\nZadane cislo je %f", desetine);
}
Posted in: Různé, Studijní materiály, Vývoj počítačů

Cykly v C

Něco málo o tom, jak udělat něco opakovaně.

Komentovaný příklad

#include <stdio.h>
#include <stdlib.h>

void main()
{
	printf("Ukazka cyklu\n\n");
	//deklarace proměnných nesmí být v cyklech
	float vstup;
	float vysledek = 0; //inicializace proměnné
	int i, j;
	char ukonci;
	//umístění výkoného kódu do cyklu
	do
	{
		printf("Mocneni pomoci nasobeni\n");
		printf("Zadej cislo k umocneni: ");
		scanf_s("%f", &vstup, 1); //bezpečné načtení jednoho čísla
		getchar(); //vyčištění vstupního bufferu
		printf("Zadej cele cislo odpvidajici mocnice: ");
		scanf_s("%d", &j, 1);
		getchar();
		//proces mocnění čísla pomocí cyklu for
		vysledek = vstup; //první krok, tey číslo na prvou
		for (i = j; i > 1; i--)
		{
			vysledek = vysledek * vstup; //proces mocnění
		}
		//vyspsání výsledku
		printf("%d mocnina cisla %f je %f \n", j, vstup, vysledek);
		printf("Prejete si pokracovat? (A/N) ");
		scanf_s("%c", &ukonci, 1);
		getchar();
	} while ((ukonci == 'A') || (ukonci == 'a')); //podmínka cyklu do while
}
Posted in: Různé, Studijní materiály, Vývoj počítačů

Větvení kódu v C

Něco málo o podmíněném zpracování kódu.

Komentovaný příklad

#include <stdio.h>
#include <stdlib.h>
#include <math.h>

void main()
{
	printf("Priklad jednoducheho vetveni\n");
	int c1, c2; //založení proměnných
	printf("Zadej prvni cele cislo: ");
	scanf_s("%d", &c1, 1); //načtení 1 čísla
	fflush(stdin); //vymazání enteru z bufferu
	printf("Zadej druhe cele cislo: ");
	scanf_s("%d", &c2, 1); //načtení 1 čísla
	fflush(stdin); //vymazání enteru z bufferu
	printf("\nOdmocnina z prvniho cisla\n");
	if (c1 > 0) //pokud je c1 kladné, pak...
	{
		float vysledek = sqrt(c1); //výpočet odmocniny
		printf("Odmocnina z %d je %f \n", c1, vysledek);
	}
	else //pokud c1 není kladné, pak...
	{
		printf("Odmocninu lze spocitat jen z kladneho cisla");
	}
	//pokračování kódu bez ohledu na to, kolik je c1
	printf("\nPorovnani cisel \n");
	if (c1 < c2) //pokud je c1 menší než c2, pak
	{
		printf("Druhe cislo je vetsi\n");
	}
	else if (c1 > c2 ) //pokud je c1 větší než c2, pak
	{
		printf("Prvni cislo je vetsi\n");
	}
	else //pokud neplatí ani jedna z předešlých dvou podmínek, pak...
	{
		printf("Cisla jsou stejna\n");
	}
	printf("\nJak si prejete pokracoavat?\n");
	printf("0 - ukonceni\n");
	printf("1 - podekovani\n");
	printf("\nZadej svou volbu: ");
	int volba;
	scanf_s("%d", &volba, 1); //načtení jednoho znaku
	fflush(stdin); //vymazání posledního enteru
	//obsloužení menu
	switch (volba)
	{
	case 0:
		break;
	case 1:
		printf("\nDekuji za pouziti, hezky den :)\n");
		printf("Press any key to continue...");
		getchar();
		getchar();
		break;
	default:
		printf("\nNevalidni zadani, koncim!\n");
		printf("Press any key to continue...");
		getchar();
		getchar();
		break;
	}
}

Press any key to continue…

#include <stdio.h>;
#include <stdlib.h>;
void main()
{
	//vykonny kod aplikace
	printf("Ahoj\n");
	//kod ukonceni programu
	printf("Press any key to continue..."); //vypis pokynu uzivateli
	getchar(); //cekani na zadani libovolneho znaku, znak zahozen
}
Posted in: Studijní materiály, Vývoj počítačů

Začátek s C

Dnes zpřístupňuji online prezentace na 4 úvodní hodiny do jazyka C. Zpřístupňuji pouze prezentaci se základními informacemi o jazyce, datových typech, operátorech a dalšími drobnosti, které jsou potřebné k napsání Hallow Word.

Demo kód k prezentaci

/*Jsem blokový komentář*/
//jsem řádkový komentář

//import sttandardních knihoven
#include <stdio.h> //práce s konzolí a soubory
#include <stdlib.h> //standardní knihovna funkcí
void main() //hlavní funkce programu, ta se provede při spuštění
{
	int vek = 16; //celočíselná proměnná
	double pi = 3.14; //desetinná čísla zapisujeme s tečkou
	char pismeno = 'A'; //znak zadáváme do apostrofů
	printf("%c", pismeno); //vypíše znak
	printf("\n"); //odřádkuje
	printf("%d \n", vek); //vypíše celé číslo a odřádkuje 
	printf("%f \n", pi); //vypíše desetinné číslo a odřádkuje
	
	//příklad vstupu
	int cislo;
	printf("Zadejte cele cislo: ");
	scanf("%d", &cislo);
	printf("Zadali jste cislo: %d", cislo);
	//return(EXIT_SUCCESS); //main je typu void, nemá co vracet
}

Překladač GCC

Back to Top