Warning
This page is located in archive. Go to the latest version of this course pages. Go the latest version of this page.

7 - Dynamicky alokovaná pole

  • pro vyučující: 07

Procvičovaná témata

  • malloc, calloc, free,
  • pointer,
  • 2D pole
  • příprava na násobení matic

Teoretická příprava

Úkoly na cvičení

  1. Napište funkci, která formátovaně vypíše obecné pole reálných čísel.
  2. Napište funkci, která vypočte směrodatnou odchylku z prvků zadaného pole.
  3. 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.
  4. Společně s cvičícím si předveďte použití Valgrindu pro diagnostiku přístupů do paměti a správné alokace.
  5. 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!
  6. 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.
  7. 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!
  8. Vždy kontrolujte program pomocí Valgrindu

Ukázkové příklady

Deklarace pole

#include <stdio.h>
 
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 <stdlib.h>
 
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 <stdlib.h>
#include <stdio.h>
 
int main()
{
	int n, m = 0;
	float b;
 
	scanf("%d", &n);
 
	float *p = (float *)malloc(n*sizeof(float));
 
 
 	for (int cnt=0;cnt<n;cnt++){
 	scanf("%f", &b);
		p[cnt]= b;
		cnt++;
		printf("%2.2f\n", b);
	}
 
	printf("pole: ");	
	for (int i = 0; i < n; i++)
	{
		printf("%2.2f ", p[i]);		
	}
 
	printf("\n");
 
	free(p);
 
	return 0;
}

courses/b0b99prpa/labs/lab07.txt · Last modified: 2018/11/08 17:43 by mudromar