C - jak udelat CRC

Jan Kratochvil short
Středa Březen 17 14:31:19 CET 2004


On Fri, Jun 14, 2002 at 08:21:38PM +0200, Ing. Pavel Poucha wrote:
...
> Mam nadefinovanou strukturu, napr:
> struct
> {
>     int a,b;
>     float c;
>     char d;
> } Zaznam
> 
> K teto strukture potrebuji spocitat jednobytove CRC.

A dejte si pozor na aligning, tj. ze:

	sizeof(Zaznam) >= 2*sizeof(int)+sizeof(float)+sizeof(char)

tj. nemusi se ==, ale Ccko ma pravo si "mezi" polozky vkladat dorovnavaci
prostor. V tomto pripade to asi zrovna nenastane, ale pozor na struktury, kde
"vetsi" typy nasleduji za "mensimi" typy. Pak by napr. mohlo nastat:

void testcrc(void)
{
struct {
	char a;
	int b;
} Zaznam1, Zaznam2;

Zaznam1.a=10; Zaznam2.a=10;
Zaznam1.b=20; Zaznam2.b=20;

MakeCRC(&Zaznam1, sizeof(Zaznam1)) != MakeCRC(&Zaznam2, sizeof(Zaznam2)); /* !!! */
}

Samozreme protoze kompilator Zaznam1 i Zaznam2 naalokuje na zasobniku, kde
bude "balast", ktery bude samozrejme na zacatku jiny v pameti pridelene
pro Zaznam1 a Zaznam2:

	bajt Zaznam+0: a
	bajt Zaznam+1: balast
	bajt Zaznam+2: balast
	bajt Zaznam+3: balast
	bajt Zaznam+4: b
	bajt Zaznam+5: b
	bajt Zaznam+6: b
	bajt Zaznam+7: b


> char MakeCRC(char *p, Lenght)
> 
> Vsechno funguje spravne, akorat se prekladaci nelibi, ze na strukturu
> ukazuji ukazovatkem typu char a pri volani vypisuje warning - nespravny
> parametr.

Sice ono explicitni pretypovani na "chat *" pri volani funkce je OK, ale
pohodlnejsi by mohlo byt "void *" v deklaraci:

unsigned char MakeCRC(const void *p, size_t Length)

"unsigned char", aby ta 1-bytova hodnota "246" napr. pri pretypovani
na "unsigned int" nepretekla na "4294967286", ale zustala jako "246".

"void *" je kompatibilni se vsemi pointery. "const" tam je dobre, aby nas
kompilator ohlidal, ze ve funkci MakeCRC() nebudeme nijak modifikovat obsah
pameti, kterou mame zCRC-ckovat, spis tim ale "dokumentujeme" ctenari, ze
proste zadany argument nemodifikujeme.

"size_t" je obecne typ, ktery je vracen funkci sizeof(). Ne kazdy kompilator C
jej obsahuje, byva obcas jeho existenci kompilacnimi skripty autodetekovat
a pouzit napr. "unsigned long", neni-li k dispozici.



							Lace





Další informace o konferenci Hw-list