Warning
This page is located in archive.

Lab 05 - Řídicí struktury, funkce a ladění programu

Procvičovaná témata

  • Funkce a vnořené cykly

Funkce

  • Vytvořte program, který načte 10 čísel a zavolá na každou dvojici součet, který vypíše na standardní výstup.

Kalendář

  • Naprogramujte zjednodušenou verzi programu cal.
  • Nejdříve zkuste vypsat:

 Mo Tu We Th Fr Sa Su
  1  2  3  4  5  6  7
  8  9 10 11 12 13 14
 15 16 17 18 19 20 21
 22 23 24 25 26 27 28
 29 30 31

  • Pak zkuste kalendář pro mesíc září:

 September
 Mo Tu We Th Fr Sa Su
           1  2  3  4
  5  6  7  8  9 10 11
 12 13 14 15 16 17 18
 19 20 21 22 23 24 25
 26 27 28 29 30

  • nebo rovnou kalendář pro tři po sobě jdoucí měsíce:

 September
 Mo Tu We Th Fr Sa Su
           1  2  3  4
  5  6  7  8  9 10 11
 12 13 14 15 16 17 18
 19 20 21 22 23 24 25
 26 27 28 29 30

 October
 Mo Tu We Th Fr Sa Su
                 1  2
  3  4  5  6  7  8  9
 10 11 12 13 14 15 16
 17 18 19 20 21 22 23
 24 25 26 27 28 29 30
 31

 November
 Mo Tu We Th Fr Sa Su
     1  2  3  4  5  6
  7  8  9 10 11 12 13
 14 15 16 17 18 19 20
 21 22 23 24 25 26 27
 28 29 30

  • Parametrizujte kód, pokud tak již nemáte a zkuste vypsat kalendář pro různý rozsah měsícu.
  • Následující vám může pomoci:

static char *day_of_week[] = {"Mo", "Tu", "We", "Th", "Fr", "Sa", "Su" };
static char *name_of_month[] = {
    "January",
    "February",
    "March",
    "April",
    "May",
    "June",
    "July",
    "August",
    "September",
    "October",
    "November",
    "December"
};
/* values for 2022 */
static int days_in_month[] = { 31, 28, 31, 30, 31, 30,
                               31, 31, 30, 31, 30, 31 };
static int first_day_in_september = 3; // 1. 9. 2022 is Thursday
static int first_day_in_year = 5; // 1. 1. 2022 is Saturday

Ladění programu - Debug

  • Všechny programy v této sekci kompilujte s přepínačem -g.
  • Spusťte následující program. Porovnejte výstup s ostatními ve třídě a vysvětlete, co se v programu děje.

#include <stdio.h>
 
int main(int argc, char *argv[])
{
    int arr[5] = { 1, 2, 3, 4, 5 };
 
    for (int i = 0; i < 30; ++i){
        printf("%d: %d\n", i, arr[i]);
    }
 
    return 0;
}

  • Zkuste zvýšit počet cyklů na 10000. Co se děje nyní. Jaký je návratový kód programu? (echo $?)
  • Nyní zkuste spustit
    valgrind ./prog 2>log
    a podívejte se do souboru log. Zkuste sami rozluštit co valgrind vypisuje.
  • Podobně si vyzkoušejte gdb s prikazy run a bt:

gdb ./prog
(gdb) run
(gdb) bt

  • Podobně zanalyzujte následující kód

#include <stdio.h>
 
static int arr[5] = { 1, 2, 3, 4, 5 };
static void endless(int size)
{
    for (int i = 0; i < size; ++i)
        printf(" %d", arr[i]);
    printf("\n");
    endless(size * 10);
}
 
int main(int argc, char *argv[])
{
    endless(1);
    return 0;
}

  • Zjistěte, co dělá funkce a(). Nejdříve si prohlídněte kód a zkuste rozluštit, co se v něm děje. Potom si rozmyslete, jak funkci otestovat a otestujte ji.

#include <limits.h>
 
static int a(int i);
static int b(int i);
static int c(int i);
static int d(int i);
 
static int a(int i)
{
    int shift = sizeof(int) * 8 - 1;
 
    if ((i & (0x1 << shift)) == INT_MIN){
        return i + a(0);
    }else if (i % 2 == 0){
        return a(i + 1) - 1;
    }else{
        return i + b(i) / 2;
    }
}
 
static int b(int i)
{
    if ((i & 0x1) == 0){
        return d(i);
    }else{
        return c(i - 1);
    }
}
 
static int c(int i)
{
    int j = i / 2;
 
    if (i == 0){
        return 2;
    }else{
        return b(j);
    }
}
 
static int d(int i)
{
    int ip = i + 1;
    int im = i - 1;
 
    if (i == 1)
        return ip;
    return b(im);
}
 
int main(int argc, char *argv[])
{
    ...
}

  • Zkuste teď svůj testovací program spustit pomocí gdb nebo cgdb. Vyzkoušejte si následující příkazy.

run  -- spustí běh
break [název funkce nebo číslo řádku]  -- nastaví breakpoint
tbreak [název funkce nebo číslo řádku]  -- nastaví jednorázový breakpoint
clear [název funkce nebo číslo řádku]  -- smaže breakpoint
info break  -- zobrazí seznam breakpointů
step  -- provede jeden krok program (zkratka s)
step [počet kroků]  -- provede uvedený počet kroků programu
display [výraz]  -- nastaví výraz, který se vypíše při každém zastavení
backtrace  -- vypíšte backtrace
frame  -- zobrazí rámec
up [počet rámců]  -- posune program o počet rámců zpět
down [počet rámců]  -- posune program o počet rámců dopředu
info locals  -- zobrazí lokální proměnné
info args  -- zobrazí argumenty rámce
info variables  -- zobrazí všechny statické a globální proměnné

courses/bab36prga/labs/lab05.txt · Last modified: 2024/02/14 00:19 by faiglj