Struktury - definicja
struct nazewnik struktury
{
zbiór składowych (elementów) struktury
} lista zmiennych;
nazewnik struktury i lista zmiennych mogą być opcjonalne
Przykład 1:
struct ksiazka
{
char tytul[40];
char autor[30];
float wartosc;
};
struct ksiazka bib1, bib2, tab[5], *wk;
struct ksiazka k={”W pustyni i w puszczy”, ”Henryk Sienkiewicz”, 100};
Przykład 2:
struct ksiazka
{
char tytul[40];
char autor[30];
float wartosc;
} bib1, bib2, tab[5], *wk;
Przykład 3:
typedef struct
{
char tytul[40];
char autor[30];
float wartosc;
} KSIAZKA;
KSIAZKA bib1, bib2, tab[5], *wk;
Dostęp do elementów struktury:
1. zmienna strukturą - operator składowej:
nazwa zmiennej.nazwa elementu struktury
np.
gets(bib1.tytul);
if (bib1.tytul[0]=='$') break;
Co oznacza zapis tab[1].autor[1] ?
2. zmienna wskaźnikiem do struktury - operator wskaźnikowy składowej:
nazwa zmiennej wskaźnikowej->nazwa elementu struktury
np.
y=bib1.wartosc; lub y=wk->wartosc; lub y=(*wk).wartosc;
c=bib1.tytul[5]; lub c=wk->tytul[5]; lub c=(*wk).tytul[5]; lub c=*(bib1.tytul+5); lub c=*(wk->tytul+5); lub c=*((*wk).tytul+5);
Funkcje a struktury
Struktura argumentem
#include <stdio.h>
struct fundusze
{
char bank[50];
double bankfund;
char oszcz[50];
double oszczfund;
};
double suma (struct fundusze mamona)
{
return (mamona.bankfund+mamona.oszczfund);
}
int main (void)
{
struct fundusze edek = {”Bank Czosnkowo-Melonowy”, 2024.72, ”Kasa Oszczednosciowo-Pozyczkowa \”Debet\””, 8237.11};
printf(”Edek posiada w sumie %.2f zl.\n”,suma(edek));
return 0;
}
Wynik:
Edek posiada w sumie 10261.83 zl.
Wskaźniki do struktur - parametry formalne funkcji
#include <stdio.h>
#include <string.h>
struct daneos
{
char imie[20];
char nazw[20];
int litery;
};
void pobierz(struct daneos *);
void oblicz(struct daneos *);
void pokaz(struct daneos *);
int main(void)
{
struct danos osoba;
pobierz (&osoba);
oblicz (&osoba);
pokaz (&osoba);
return 0;
}
void pobierz (struct daneos *wst)
{
printf(”Podaj swoje imie:”);
gets(wst->imie);
printf(”Podaj swoje nazwisko:”);
gets(wst->nazw);
}
void oblicz (struct daneos *wst)
{
wst->litery=strlen(wst->imie)+strlen(wst->nazw);
}
void pokaz (struct daneos *wst)
{
printf(”%s %s, Twoje imie i nazwisko skladaja sie z %d liter.”, wst->imie, wst->nazw, wst->litery);
}
Wynik:
Podaj swoje imie: Wiola
Podaj swoje nazwisko: Pumpernikiel
Wiola Pumpernikiel, Twoje imie i nazwisko skladaja się z 17 liter.
Funkcja zwraca strukturę:
#include <stdio.h>
#include <string.h>
struct daneos
{
char imie[20];
char nazw[20];
int litery;
};
struct daneos pobierz(void);
struct daneos oblicz(struct daneos);
void pokaz(struct daneos);
int main(void)
{
struct daneos osoba;
osoba=pobierz();
osoba=oblicz(osoba);
pokaz(osoba);
return 0;
}
struct daneos pobierz(void)
{
struct daneos temp;
printf(”Podaj swoje imie:”);
gets(temp.imie);
printf(”Podaj swoje nazwisko:”);
gets(temp.nazw);
return temp;
}
struct daneos oblicz(struct daneos info)
{
info.litery=strlen(info.imie)+strlen(info.nazw);
return info;
}
void pokaz (struct daneos info)
{
printf(”%s %s, Twoje imie i nazwisko skladaja sie z %d liter.”, info.imie, info.nazw, info.litery);
}
Wynik:
Podaj swoje imie: Wiola
Podaj swoje nazwisko: Pumpernikiel
Wiola Pumpernikiel, Twoje imie i nazwisko skladaja się z 17 liter.
Struktury samoodwołujące się:
deklaracja:
struct nazewnik struktury
{
zbiór składowych struktury
struct nazewnik struktury *wskaźnik;
...
}
Przykład struktury samoodwołującej się - lista dwukierunkowa:
#include <stdio.h>
#include <alloc.h>
#include <string.h>
#include <ctype.h>
#define M 80
main()
{
struct elem
{
char tekst[M];
struct elem *poprz;
struct elem *nast;
};
struct elem *pocz=NULL, *koniec=NULL, *p=NULL, *nowy;
char linia[M], kon='#', kryt='K';
printf (”\nWprowadzenie nazwisk (# kończy)”);
for(;;)
{
printf(”>”);
gets(linia);
if (*linia==kon)
break;
if (*linia=='')
continue;
/*alokacja pamięci*/
nowy=(struct elem*)malloc(sizeof(struct elem));
strcpy(nowy->tekst,linia);
if(pocz==NULL) /*utworzenie pierwszego elementu listy*/
{
nowy->poprz=NULL;
nowy->nast=NULL;
pocz=nowy;
koniec=nowy;
continue;
}
else /*wstawienie na poczatek listy*/
if (strcmp(linia,pocz->tekst)<=0)
{
nowy->poprz=NULL;
nowy->nast=pocz;
pocz->poprz=nowy;
pocz=nowy;
continue;
}
else /*wstawienie na koniec listy*/
if (strcmp(linia,koniec->tekst)>=0)
{
nowy->nast=NULL;
nowy->poprz=koniec;
koniec->nast=nowy;
koniec=nowy;
continue;
}
else /*wstawienie gdzies wewnatrz listy*/
if (toupper(*linia)<kryt)
{
/*szukanie miejsca od poczatku listy*/
p=pocz;
while(p!=NULL)
{
if(strcmp(linia,p->nast->tekst)<=0)
{
/*rozciecie listy i wstawienie elementu*/
nowy->poprz=p;
nowy->nast=p->nast;
p->nast->poprz=nowy;
p->nast=nowy;
break;
}
p=p->nast;
}
}
else /*szukanie miejsca od konca listy*/
{
p=koniec;
while(p!=NULL)
{
if(strcmp(linia,p->poprz->tekst)>=0)
{
/*rozciecie listy i wstawienie elementu*/
nowy->poprz=p->poprz;
nowy->nast=p;
p->poprz->nast=nowy;
p->poprz=nowy;
break;
}
p=p->poprz;
}
}
}
printf(”\nAlfabetyczna lista nazwisk”);
p=pocz;
while (p!=NULL)
{
puts(p->tekst);
p=p->nast;
}
}
Unie:
Unia jest strukturą, której wszystkie składowe umieszczane są w tym samym miejscu pamięci. Miejsce to jest tak zwymiarowane przez kompilator, aby mogło pomieścić największą składową. Umożliwia to oszczędne gospodarowanie pamięcią komputera i jednocześnie manipulowanie danymi różnego rodzaju w tym samym miejscu pamięci.
Deklaracja:
union nazewnik unii
{
zbiór składowych (elementów) unii
}
lista zmiennych;
Dostęp do elementów unii przy pomocy operatora składowej (.) i operatora wskaźnikowego składowej (->)
Przykład:
union blok1 { int numer; int ident; char nazwa[20]; char text[50]; };
union blok1 b1;
|
struct blok2 { int numer; int ident; char nazwa[20]; char text[50]; };
struct blok2 b2;
|
zmienna b1 zajmuje pamięć 50 bajtów, a zmienna b2 74
Pola bitowe:
Pola bitowe są strukturami upakowanymi w jednym słowie maszynowym. Każda część słowa (1 lub kilka bitów) posiada zwykle swój identyfikator. Deklaracja pola bitowego jest podobna do deklaracji struktury, zawiera tylko dodatkowo dwukropki, po których podawana jest liczba bitów. Składowe pól bitowych mogą być wyłącznie typu signed lub unsigned.
struct pole_1
{
unsigned a:2;
unsigned b:3;
unsigned c:4;
unsigned d:1;
};
struct pole_1 q1,q2;
Przyjmując słowo maszynowe 16 bitowe oraz rozmieszczenie pól od prawej do lewej (co nie zawsze jest regułą) poszczególne bity będą przyporządkowane następującym polom struktury pole_1:
0-1 - pole a,
2-4 - pole b,
5-8 - pole c,
9 - pole d,
10-15 - bity niewykorzystane
Przykład
struct data
{
unsigned dzien:5;
unsigned miesiac:4;
unsigned rok:7;
} dzien={26,11,01};
dzien.dzien=26
dzien.miesiac=11
dzien.rok=01
struct pole_2
{
unsigned a:2;
unsigned :3; /*nie okreslono identyfikatora pole utworzone dostep nie jest mozliwy */
unsigned b:4;
unsigned c:1;
};
struct pole_2 q1,q2;
struct pole_3
{
unsigned a:5; /*slowo pierwsze*/
unsigned b:5;
unsigned c:5;
unsigned d:5; /*slowo drugie*/
};
struct pole_3 q1,q2;
struct pole_4
{
unsigned a:5; /*slowo pierwsze*/
unsigned b:5;
unsigned :0;
unsigned c:5; /*slowo drugie*/
unsigned d:5;
};
struct pole_4 q1,q2;
struct pole_5
{
unsigned a:5; /*slowo pierwsze*/
unsigned b:5;
unsigned :6;
unsigned c:5; /*slowo drugie*/
unsigned d:5;
};
struct pole_4 q1,q2;
Funkcje peek (odczyt danej słowowej) oraz poke (ustawienie danej słowowej)
#include <stdio.h>
#include <dos.h>
#define USTAW_SLOWO(_zmienna, _wartosc) \
poke (FP_SEG(&_zmienna),FP_OFF(&_zmienna),_wartosc);
#define CZYTAJ_SLOWO(_zmienna, _format) \
printf(#_format, peek(FP_SEG(&_zmienna), FP_OFF(&_zmienna)));
main()
{
struct pole_bitowe
{
unsigned b0:1;
unsigned b1:1;
unsigned b2:1;
unsigned b3:1;
unsigned b4:1;
unsigned b5:1;
unsigned b6:1;
unsigned b7:1;
unsigned b8:1;
unsigned b9:1;
unsigned b10:1;
unsigned b11:1;
unsigned b12:1;
unsigned b13:1;
unsigned b14:1;
unsigned b15:1;
};
struct pole_bitowe b;
int a=0x40ff;
USTAW_SLOWO(b,a);
printf(”\n Ustawiono 0x40ff”);
printf(”\n bit 2=%d”,b.b2);
printf(”\n bit 10=%d”,b.b10);
if(b.b5==1)
printf(”\n bit 5 jest 1”);
printf(”\n slowo ustawione=”);
CZYTAJ_SLOWO(b,%X);
b.b0=0;
b.b1=0;
b.b15=1;
printf(”\n slowo zmodyfikowane=”);
CZYTAJ_SLOWO(b,%X);
USTAW_SLOWO(b,a+4);
printf(”\n slowo ponownie ustawione=”);
CZYTAJ_SLOWO(b,%X);
printf(”\n bit 2=%d”,b.b2);
}
Deklaracja typedef
typedef nazwa_typu nowa_nazwa_typu;
Np. typedef char BYTE;
BYTE x, y[10], *z;
Zasięg definicji typedef:
definicja wewnątrz funkcji - zasięg lokalny
definicja poza funkcją - zasięg globalny
Definicja typu strukturalnego przy pomocy typedef:
typedef struct
{
lista elementów (składowych);
} NAZWA_TYPU;
NAZWA_TYPU lista zmiennych;
typedef struct NAZWA_TYPU
{
lista elementów (składowych);
};
struct NAZWA_TYPU lista_zmiennych;