{{indexmenu_n>7}}
====== 7 - Dynamicky alokovaná pole ======
* pro vyučující: [[courses:b0b99prp:internal:tutorialinstruction:07|]]
==== Procvičovaná témata ====
* malloc, calloc, free,
* pointer,
* 2D pole
* příprava na násobení matic
==== Teoretická příprava ====
* [[courses:b0b36prp:tutorials:alokace_pameti_v_c]]
* [[https://en.wikipedia.org/wiki/Standard_deviation|Smerodatna odchylka]]
==== Úkoly na cvičení ====
- Napište funkci, která formátovaně vypíše obecné pole reálných čísel.
- Napište funkci, která vypočte směrodatnou odchylku z prvků zadaného pole.
- Napište funkci, která zajistí načtení n prvků z klávesnice do pole a toto pole předá do volající funkce. Počet prvků bude zadán jako parametr funkce.
- Společně s cvičícím si předveďte použití Valgrindu pro diagnostiku přístupů do paměti a správné alokace.
- Aplikujte funkce pro výpis a výpočet směrodatné odchylky na pole získané načítací funkcí. Nezapomeňte na dealokaci pole při ukončení programu!
- Upravte předchozí funkci tak, aby byla schopna načíst libovolnou posloupnost reálných čísel do pole ukončenou vhodnou zarážkou nebo lépe pomocí EOF, umí-li to vaše konzole.
- Upravte předchozí kód tak, aby bylo možné načíst od uživatele více datových řad a pro každou zvlášť spočítat směrodatnou odchylku. Jednoduše to zařídíte tak, že vytvoříte dvourozměrné pole, které ale může mít různé délky řádků. Nezapomeňte zajistit i dealoakaci celého pole!
- Vždy kontrolujte program pomocí Valgrindu
===== Ukázkové příklady =====
==== Deklarace pole ====
#include
void f1(int a[], int n, char nazev);
void f2(int *a, int n, char nazev);
int main()
{
int a[2]; // deklarace pole, prvky neinicializovany
// a[i], i = <0,1>
printf("neinicializovane pole\n");
for (int i = 0; i < 2; i++)
{
printf("a[%d]=%d\n", i, a[i]);
}
a[0] = 10;
a[1] = 20;
printf("inicializovane pole\n");
for (int i = 0; i < 2; i++)
{
printf("a[%d]=%d\n", i, a[i]);
}
int b[] = {3, 5, 8}; // triprvkove pole, velikost je urcena automaticky
int c[5] = {6, 3}; // petiprvkove, 6, 3, 0, 0, 0 - automaticky 0 u neinit.
// init. prvnich N z M, N <= M
int d[5] = {[3] = 9}; // 0 0 0 9 0
// prvek s indexem inicializovan, zbytek 0
int e[] = {[3] = 9}; // 0, 0, 0, 9
int f[10] = {0}; // 10x 0
printf("velikost pole e: %lu\n", sizeof(e)/sizeof(int));
f1(c, sizeof(c)/sizeof(int), 'c');
f1(d, sizeof(d)/sizeof(int), 'd');
f1(e, sizeof(e)/sizeof(int), 'e');
f1(f, sizeof(f)/sizeof(int), 'f');
int *A;
A = d; // ukazatel A odkazuje na pamet, kde zacina pole d
f1(A, sizeof(d)/sizeof(int), 'A');
for (int i = 0; i < 5; i++)
{
printf("A[%d]=%d\n", i, A[i]);
}
f2(e, sizeof(e)/sizeof(int), 'e');
// int h[10000000]; pozadavek na prilis mnoho pameti v zasobniku
return 0;
}
void f1(int a[], int n, char nazev) // ~ void f1(int *a, int n, char nazev)
{
// printf("test velikosti pole a: %lu\n", sizeof(a)/sizeof(int));
// neni moc pouzitelne, vraci velikost ukazatele, tj. sizeof(int *)
printf("%c: ", nazev);
for (int i = 0; i < n; i++)
printf("%d ", a[i]);
printf("\n");
}
void f2(int *a, int n, char nazev)
{
printf("%c: ", nazev);
for (int i = 0; i < n; i++)
printf("%d ", *(a+i)); // pozor na smysl dereference: *a+i je spatne
printf("\n");
}
==== Pole v dynamické paměti ====
#include
int main()
{
// volani malloc(pocet bytu) vrati adresu v dynamicke pameti, pokud to bylo uspesne volani
// adresa je datoveho typu void*, je vhodné ji přetypovat
int *a, *b;
const int n = 4;
a = (int *)malloc(n*sizeof(int));
b = (int *)calloc(n, sizeof(int));
if (a == NULL)
{
// kontrola, zda se podařilo alokovat potřebnou pamět, měla by být vždy
// zde chybí kontrola pole b
printf("nedarilo ze alokovat!\n");
return 100;
}
else
{
printf("adresa alokovaneho prostoru: %p\n", a);
for (int i = 0; i < n; i++)
*(a+i) = i;
for (int i = 0; i < n; i++)
printf("a[%d]=%d\n", i, a[i]);
for (int i = 0; i < n; i++)
printf("b[%d]=%d\n", i, b[i]);
free(a);
free(b);
}
return 0;
}
==== Načtení dat ze standardního vstupu ====
* mějte v textovém souboru in.txt následující data: ''3 3.14 5.34 8.33''
* první číslo reprezentuje počet následujících čísel typu float
* pak voláme ''$ ./a.out < in.txt''
#include
#include
int main()
{
int n, m = 0;
float b;
scanf("%d", &n);
float *p = (float *)malloc(n*sizeof(float));
for (int cnt=0;cnt