Přednáška http://efis.tul.cz/~dana.nejedlova/ Základy programování, Programování I a II Přednáška z jazyka C na téma "Pole a řetězce v jazyce C" neproběhla naživo kvůli výpadku služeb Google. Přednáška byla nahrána na server https://elearning.tul.cz/ - předmět "KIN/ZP - Základy programování (2020)". https://elearning.tul.cz/course/view.php?id=7803 v části "Téma 12". Přednáška z jazyka C - Snímek "Pointerová aritmetika" - kód, který je komentován na začátku videa s přednáškou. #include int main(void) { int i; double f, *p = &f; for (i = 0; i < sizeof(double); i++) printf("%d. byte = %p\n", i, /*(char *)*/ p + i); return 0; } Ke zkoušce je třeba znát: http://efis.tul.cz/~dana.nejedlova/multiedu/Prednask.pdf Kapitola 2.2.5.2 Využití údajů o složitosti algoritmu Jsou zde 4 vzorové úlohy. V zápočtovém testu bude jedna z těchto úloh s jinými hodnotami. Cvičení Načtení čísel do pole z textového souboru. Pointerová aritmetika - různé způsoby procházení polem. Předání řetězce jako parametru do funkce. Program načte čísla z textového souboru do statického pole. #include #define SOUBOR "vstup.txt" #define MAX_POCET_CISEL 10 int zjisti_pocet_cisel_v_souboru(FILE *fr) { int c, pocet_nactenych_cisel = 0; do { if (fscanf(fr, "%d", &c) == 1) { pocet_nactenych_cisel++; } else { putchar(getc(fr)); putchar('\n'); } } while (!feof(fr)); return pocet_nactenych_cisel; } void nacti_cisla_ze_souboru_do_pole(FILE *fr, int pole_cisel[]) { int i = 0; do { if (fscanf(fr, "%d", &pole_cisel[i]) == 1) { i++; } else { putchar(getc(fr)); putchar('\n'); } } while (!feof(fr)); } void vypis_pole(int pole_cisel[], int pocet_cisel) { int i; for (i = 0; i < pocet_cisel; i++) { printf("%d ", pole_cisel[i]); } } int main(void) { FILE *fr; int pocet_cisel, pole_cisel[MAX_POCET_CISEL]; if ((fr = fopen(SOUBOR, "r")) == NULL) { printf("Soubor %s se nepodarilo otevrit.\n", SOUBOR); return 1; } pocet_cisel = zjisti_pocet_cisel_v_souboru(fr); printf("Ze souboru %s bylo nacteno %d cisel.\n", SOUBOR, pocet_cisel); if (fclose(fr) == EOF) { printf("Soubor %s se nepodarilo uzavrit.\n", SOUBOR); return 1; } if (pocet_cisel > MAX_POCET_CISEL) { printf("V souboru %s je vice cisel, nez je velikost %d pole.\n", SOUBOR, MAX_POCET_CISEL); } else { if ((fr = fopen(SOUBOR, "r")) == NULL) { printf("Soubor %s se nepodarilo otevrit.\n", SOUBOR); return 1; } nacti_cisla_ze_souboru_do_pole(fr, pole_cisel); if (fclose(fr) == EOF) { printf("Soubor %s se nepodarilo uzavrit.\n", SOUBOR); return 1; } vypis_pole(pole_cisel, pocet_cisel); } return 0; } Program načte čísla z textového souboru do statického pole. Větev else se závěrem funkce main() je nahrazena předčasným ukončením příkazem return, jako je to v testech na správnost otevření nebo uzavření souboru. #include #define SOUBOR "vstup.txt" #define MAX_POCET_CISEL 10 int zjisti_pocet_cisel_v_souboru(FILE *fr) { int c, pocet_nactenych_cisel = 0; do { if (fscanf(fr, "%d", &c) == 1) { pocet_nactenych_cisel++; } else { putchar(getc(fr)); putchar('\n'); } } while (!feof(fr)); return pocet_nactenych_cisel; } void nacti_cisla_ze_souboru_do_pole(FILE *fr, int pole_cisel[]) { int i = 0; do { if (fscanf(fr, "%d", &pole_cisel[i]) == 1) { i++; } else { putchar(getc(fr)); putchar('\n'); } } while (!feof(fr)); } void vypis_pole(int pole_cisel[], int pocet_cisel) { int i; for (i = 0; i < pocet_cisel; i++) { printf("%d ", pole_cisel[i]); } } int main(void) { FILE *fr; int pocet_cisel, pole_cisel[MAX_POCET_CISEL]; if ((fr = fopen(SOUBOR, "r")) == NULL) { printf("Soubor %s se nepodarilo otevrit.\n", SOUBOR); return 1; } pocet_cisel = zjisti_pocet_cisel_v_souboru(fr); printf("Ze souboru %s bylo nacteno %d cisel.\n", SOUBOR, pocet_cisel); if (fclose(fr) == EOF) { printf("Soubor %s se nepodarilo uzavrit.\n", SOUBOR); return 1; } if (pocet_cisel > MAX_POCET_CISEL) { printf("V souboru %s je vice cisel, nez je velikost %d pole.\n", SOUBOR, MAX_POCET_CISEL); return 1; } if ((fr = fopen(SOUBOR, "r")) == NULL) { printf("Soubor %s se nepodarilo otevrit.\n", SOUBOR); return 1; } nacti_cisla_ze_souboru_do_pole(fr, pole_cisel); if (fclose(fr) == EOF) { printf("Soubor %s se nepodarilo uzavrit.\n", SOUBOR); return 1; } vypis_pole(pole_cisel, pocet_cisel); return 0; } Program načte čísla ze souboru do statického pole. Funkce nacti_cisla_ze_souboru_do_pole() si sama otevře a uzavře soubor, vrací počet čísel v souboru a ukončí čtení, když počet načtených čísel přesáhne konstantu MAX_POCET_CISEL. #include #define SOUBOR "vstup.txt" #define MAX_POCET_CISEL 10 int nacti_cisla_ze_souboru_do_pole(char *nazev_souboru, int pole_cisel[]) { FILE *fr; int pocet_nactenych_cisel = 0; if ((fr = fopen(nazev_souboru, "r")) == NULL) { printf("Soubor %s se nepodarilo otevrit.\n", nazev_souboru); return -1; } while (!feof(fr) && pocet_nactenych_cisel < MAX_POCET_CISEL) { if (fscanf(fr, "%d", &pole_cisel[pocet_nactenych_cisel]) == 1) { pocet_nactenych_cisel++; } else { putchar(getc(fr)); putchar('\n'); } } if (fclose(fr) == EOF) { printf("Soubor %s se nepodarilo uzavrit.\n", nazev_souboru); return -1; } return pocet_nactenych_cisel; } void vypis_pole(int *pole_cisel, int pocet_cisel) { int i; for (i = 0; i < pocet_cisel; i++) { printf("%d ", pole_cisel[i]); } } int main(void) { int pocet_cisel, pole_cisel[MAX_POCET_CISEL]; pocet_cisel = nacti_cisla_ze_souboru_do_pole(SOUBOR, pole_cisel); if (pocet_cisel == 0) { printf("V souboru %s neni ani jedno cislo.\n", SOUBOR); } else if (pocet_cisel > 0) { vypis_pole(pole_cisel, pocet_cisel); } return 0; } Program načte čísla ze souboru do dynamického pole. #include #include #define SOUBOR "vstup.txt" int zjisti_pocet_cisel_v_souboru(FILE *fr) { int c, pocet_nactenych_cisel = 0; do { if (fscanf(fr, "%d", &c) == 1) { pocet_nactenych_cisel++; } else { putchar(getc(fr)); putchar('\n'); } } while (!feof(fr)); return pocet_nactenych_cisel; } void nacti_cisla_ze_souboru_do_pole(FILE *fr, int *pole_cisel) { int i = 0; do { if (fscanf(fr, "%d", pole_cisel + i) == 1) { /* Mozno i fscanf(fr, "%d", &pole_cisel[i]) */ i++; } else { putchar(getc(fr)); putchar('\n'); } } while (!feof(fr)); } void vypis_pole(int *pole_cisel, int pocet_cisel) { int i; for (i = 0; i < pocet_cisel; i++) { printf("%d ", *(pole_cisel + i)); /* Mozno i printf("%d ", pole_cisel[i]); */ } } int main(void) { FILE *fr; int pocet_cisel, *pole_cisel; if ((fr = fopen(SOUBOR, "r")) == NULL) { printf("Soubor %s se nepodarilo otevrit.\n", SOUBOR); return 1; } pocet_cisel = zjisti_pocet_cisel_v_souboru(fr); printf("Ze souboru %s bylo nacteno %d cisel.\n", SOUBOR, pocet_cisel); if (fclose(fr) == EOF) { printf("Soubor %s se nepodarilo uzavrit.\n", SOUBOR); return 1; } if ((pole_cisel = (int *) malloc(pocet_cisel * sizeof(int))) == NULL) { printf("Malo pameti!\n"); return 1; } if ((fr = fopen(SOUBOR, "r")) == NULL) { printf("Soubor %s se nepodarilo otevrit.\n", SOUBOR); return 1; } nacti_cisla_ze_souboru_do_pole(fr, pole_cisel); if (fclose(fr) == EOF) { printf("Soubor %s se nepodarilo uzavrit.\n", SOUBOR); return 1; } vypis_pole(pole_cisel, pocet_cisel); free((void *) pole_cisel); return 0; } Program s funkcemi pro načítání čísel z klávesnice s výzvou pro uživatele jako parametrem. #include int zadej_cele_cislo(char *prompt) { int cislo; printf(prompt); while (scanf("%d", &cislo) != 1) { printf("Zadali jste cislo spatne.\n"); printf("Zadejte cislo znovu: "); while (getchar() != '\n') ; } while (getchar() != '\n') ; return cislo; } void nacti_cele_cislo(char *prompt, int *cislo) { printf(prompt); while (scanf("%d", cislo) != 1) { printf("Zadali jste cislo spatne.\n"); printf("Zadejte cislo znovu: "); while (getchar() != '\n') ; } while (getchar() != '\n') ; } int zadej_cislo_v_intervalu(char *prompt, int min, int max) { int cislo; printf(prompt, min, max); while ((cislo = zadej_cele_cislo("")) < min || cislo > max) { printf("Zadali jste cislo mimo interval.\n"); printf(prompt, min, max); } return cislo; } int main(void) { int volba; volba = zadej_cele_cislo("Zadejte cele cislo: "); printf("%d\n", volba); nacti_cele_cislo("Zadejte cele cislo: ", &volba); printf("%d\n", volba); volba = zadej_cislo_v_intervalu("Zadejte cele cislo od %d do %d: ", 1, 3); printf("%d\n", volba); return 0; }