{{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