Na dzisiejszych zajęciach poćwiczymy operacje na wskaźnikach i alokacji pamięci. Na początek takie zadanie - należy zadeklarować tablicę tab pięcioelementową od 0 do 4, oraz zmienną tab2 wskaźnikową, która zamieni się w drugą tablicę o takiej samej liczbie komórek (5), co w tablicy tab. Zobaczmy, jak wygląda taki psudokod:
main (){
int tab [5]; < Deklaracja tablicy tab o pieciu elementach
int* tab2; < Deklaracja zmiennej wskaźnikowej tab2
tab2=(int*)malloc (sizeof(int)*5); < Zamiana zmiennej tab2 w zmienną tablicową o liczbie komórek 5
if (tab2 !=NULL){ < Warunek: Jeśli zawartośc komórek tablicy tab2 są puste, to …
tab2 [4]=8; < Tymczasowe przypisanie ostatniej komórce w tablicy tab2 wart. 2
free (tab2); < Wyczyszczenie zawartości komórek w tablicy tab2
}
Kolejne zadanie - bardzo proste bardziej skupiające się na wskaźnikach. Należy napisać funkcję zeruj zerującą jedną zmienną z uzyciem wskaźników i funkcję główną z przypisaną zmienną równą 5. Funkcja zeruj ma zamienić tą zmienną 5 na 0. Oto, jak to się robi. Po lewej stronie obydwie funkcje, a po prawej komórki pamięci i ich zawartości:
void zeruj (int *k)
{
*k=0;
}
main (){
int a=5;
zeruj (&a);
printf ("%d", a);
}
Następne zadanie z użyciem wskaźników bedzie polegało na tym, żeby napisać dwie funkcje - główną i zamien. W funkcji głównej mają być zadeklarowane dwie zmienne, a funkcja zamien ma zamienić te zmienne miejscami. Po lewej stronie pseudokod funkcji, a po prawej - komórki pamięci:
main (){
int a=5, b=3
zamien (a,b);
printf ("%d",a);
}
void zamien (int k, int j)
{
int p;
p=*k;
*k=*j;
*j=p;
}
Zrobiliśmy wskaźniki, tablice, to teraz zajmiemy się listami. Lista jest strukturą, gdzie nasz dostęp do elementów jest nieograniczony, czyli możemy dotrzeć do każdego elementu i wykonać na nim jakąś operację. W przypadku listy jednokierunkowej możemy poruszać się, jak sama nazwa wskazuje, tylko w jednym kierunku. W naszej liście każdy jej element zna swojego następnika. Aby stworzyć listę potrzebujemy paru elementów. Przede wszystkim strukturę, która będzie reprezentować elementy naszej listy. Kolejne zadanie polega na zaimplementowaniu takiej listy dwuelementowej. Pierwszy element listy ma być o nazwie val, a drugi element ma być wskaźnikiem do następnego elementu listy. Oto, jak wygląda pseudokod takiego zadania:
struct node {
int val;
struct node *next;
};
main (){
struct node k;
struct node *l=&k;
k.val=5;
k.next=NULL;
(*l).val=5; |
(*l).next=NULL; |
l->val=5;
l->next=NULL;
}
A teraz kolejne zadanie. Należy napisać funkcje dodaj, która doda na początek listy liczby 5 i 8. A zatem:
struct node{
int val;
struct node *next;
};
main (){
struct node *lista=NULL;
lista=dodaj (lista,5);
lista=dodaj (lista,8);
struct node * dodaj (struct node * l, int k)
{
struct node *.e;
e=(struct node*)malloc (sizeof(struct node));
if (e !=NULL){
e-> val=k;
e -> next=l;
} else printf ("brak pamieci");
return e;
}
}
I na zakończenie należy napisać funkcję dodaj, która doda na początek listy liczbę 5 i na koniec listy liczbę 8, oraz wypisze zawartośc listy. A więc:
struct node {
int val;
struct node *next;
};
main (){
struct node *lista=NULL;
lista=dodaj(lista,5);
lista=dodaj(lista,8);
wypisz (lista);
void wypisz (struct node *l){
while (l !=NULL){
printf ("%d",l->val);
l=l->next;
}
}
}
a 8000 |
5 |
k 8004 |
[8000] |
8008 |
|
Zmienne Adresy komórek Zawartość komórek
p = k | [8000]
p = &k | [8008]
p = *k | 5
a 8000 |
5 > 3 |
b 8004 |
3 > 5 |
k 8008 |
[8000] |
j 8012 |
[8004] |
p 8016 |
5 |
val next
val 8000 |
|
next 8004 |
|
8008 |
|
8012 |
|
8016 |
|
k
b > val *