Strukturované datové typy

Proměnné typu struktura (struct) jsou v jazyce C v paměti uloženy jednoduše jako její prvky za sebou, tzn. adresa struktury je stejná jako adresa jejího prvního prvku. Např. struct { long a; short b; } s; je uložena jako 6 bytů - 4 byty pro a, 2 pro b, přes proměnnou s se v assembleru dostaneme k prvnímu prvku s.a.

Při práci se strukturami je potřeba brát v potaz, že pro větší efektivnost dochází ješte k tzv. zarovnání velikosti struktury (padding) na vhodný násobek 4 nebo 8. To znamená, že i když výše uvedená struktura potřebuje k uchování dat pouze 6 bytů, ve skutečnosti zabere v paměti 8 bytů. Ověřte si to vhodným použitím operátoru sizeof.

Vedle zarovnání velikosti objektů je potřeba dbát i na zarovnání jednotlivých členů struktury. Hodnoty velikosti jeden byte jsou zarovnávany na 1B, dvoubytové hodnoty na 2B, čtyřbytové hodnoty na 4B, atd. V praxi to znamená, že jednotlivé členy daného typu začínají vždy na násobku svého zarovnání, např. hodnoty typu int jsou ve struktuře uložené vždy na pozici, která je násobkem čtyř. Toto chování je nutné mít na paměti při návrhu datových struktur, protože může vést k nevhodné spotřebě paměti. Pozici, na které je daný člen uložen, je možné v jazyce C zjistit pomocí makra offsetof(struktura, clen) ze stddef.h.

#include <stdio.h>
#include <stddef.h>

struct foo {
	char a;
	short b;
	int c;
};

struct foo bar;

int main()
{
	bar.a = 0;
	bar.b = 100;
	bar.c = 200;
	printf("%i\n", offsetof(struct foo, b));
	_asm {
		mov ebx, offset bar;
		mov byte ptr [ebx], 'd';     // ulozi do bar.a = 'd'
		mov cx, [ebx + 2];           // ulozi do cx hodnotu bar.b 
		mov eax, [ebx + 4];          // ulozi do eax hodnotu bar.c
		mov dword ptr [ebx + 3], eax // !!! provede nesmyslnou operaci
	}
	return 0;
}

Úkol

  1. Zjistěte pozice jednotlivých členů ve struktuře struct foo. Prohozením členů ověřte, že se překladač chová, jak je výše popsáno. Ověřte, že pořadí členů ovlivňuje velikost struktury.
  2. Naprogramujte databázi osob.
    1. Navrhněte vhodnou strukturu, která pojme následující informace -- jméno (char *), datum narození (zvolte vhodnou reprezentaci), výška (unsigned char), váha (unsigned short).
    2. Naprogramujte funkci db_add s parametry jméno, datum narození, výška a váha -- která přidá položku do databáze.
    3. Naprogramujte funkci db_print, která vypíše obsah databáze.
    4. Naprogramujte funkci db_avg_height, která vrací průměrnou výšku osob v databázi.
    5. Naprogramujte funkci db_avg_weight, která vrací průměrnou váhu osob v databázi.
    Úlohu naprogramujte nejdříve v C a pak v Assembleru. K ukládání hodnot použijte globální pole pevně dané velikosti.

Last update on 27. 3. 2019 12:46
Powered by Schemik.

© Petr Krajča, 2010, 2012
petr.krajca (at) upol.cz