ANSI C 9

ANSI C 9



5 WSKAŹNIKI I TABLICE______—--

alloc i afree jest stosem lub listą LIFO (ang. last-in, first-out: ostatni przychodzi, pierwszy wychodzi). Biblioteka standardowa oferuje analogiczne funkcje o nazwach malloc i free, które nie wprowadzają takich ograniczeń; w p. 8.7 pokażemy, jak można je zrealizować.

W najprostszej wersji funkcja alloc przydziela części dużej tablicy znakowej, którą nazwiemy allocbuf. Jest ona prywatną własnością funkcji alloc i afree. Funkcje te będą używać wskaźników, a nie indeksów, nazwa tablicy nie musi więc być znana innym podprogramom. Tablicę możemy zatem zadeklarować jako static w tym pliku źródłowym, w którym mieszczą się obie funkcje - w ten sposób stanie się niedostępna dla otoczenia. W praktyce tablica ta nawet nie musi w ogóle mieć nazwy: możemy ją otrzymać wywołując funkcję malloc lub żądając od systemu operacyjnego wskaźnika do pewnego nie nazwanego bloku pamięci.

Potrzebna jest również informacja o tym, jak duża część tablicy allocbuf jest już zajęta. W tym celu użyjemy wskaźnika allocp, który wskazuje na następny wolny element. Funkcja alloc przed przydzieleniem n znaków sprawcza, czy w tablicy allocbuf jest wystarczająco dużo wolnego miejsca. Jeżeli tak, to funkcja wraca z bieżącą wartością wskaźnika allocp (to znaczy adresem początku wolnego obszaru), jednocześnie zwiększając ten wskaźnik o n, aby wskazywał na kolejny wolny obszar. Jeśli w tablicy nie ma wolnego miejsca, to funkcja alloc zwraca zero. Funkcja afree(p) po prostu wstawia wartość wskaźnika p do allocp, jeżeli p wskazuje na wnętrze tablicy allocbuf.

Oto rysunek, na którym przedstawiono działanie dystrybutora pamięci: przed wywołaniem funkcji alloc:

allocp: ^

4 —

allocbuf:

*-zajęte-- wolne

po wywołaniu funkcji alloc:

allocbuf:

allocp: >

4 ——

zajęte-

-> <-

wolne

#define ALLOCSIZE 10000 /* rozmiar dostępnej pamięci */

static char allocbuf [ALLOCSIZE]; /* pamięć dla alloc */ static char *allocp = allocbuf; /* następna wolna pozycja */

5.4 ARYTMETYKA NA ADRESACH_____

powered by

Mi sio"!


char *alloc(int n) /* podaj wskaźnik do n znaków */

{

if (allocbuf + ALLOCSIZE - allocp >= n) { /* wystarczy miejsca */ allocp 4= n;

return allocp - n; /* zwróć starą wartość allocp */

} else I* za mało miejsca */ return 0;

}

void afree(char *p) /* zwolnij pamięć wskazaną przez p */

{

if (p >= allocbuf && p < allocbuf + ALLOCSIZE) allocp = p;

}

Ogólnie wskaźnikom można nadawać wartości początkowe tak samo, jak innym zmiennym. Jednak zwykle jedynymi znaczącymi wartościami są zero oraz wyrażenia zawierające adresy uprzednio zdefiniowanych danych właściwego typu. Deklaracja

static char *allocp = allocbuf;

definiuje allocp jako wskaźnik do znaków i inicjuje go tak, aby wskazywał na początek tablicy allocbuf, czyli na pierwszą wolną pozycję przy starcie programu. Można to również napisać inaczej:

static char *allocp = &allocbuf[0];

ponieważ nazwa tablicy jest adresem jej zerowego elementu.

Test

if (allocbuf + ALLOCSIZE - allocp >= n) {/* wystarczy miejsca */

sprawdza, czy w tablicy jest dostatecznie dużo wolnego miejsca, aby spełnić żądanie przydzielenia n znaków. Jeżeli tak, to nowa wartość allocp może wskazywać na miejsce przekraczające koniec obszaru allocbuf co najwyżej o jeden znak. Funkcja alloc zwraca wówczas wskaźnik do początku bloku znaków (zwróć uwagę na deklarację samej funkcji). Jeśli nie, to alloc musi zwrócić jakiś sygnał o braku pamięci. Język C gwarantuje, że zero nigdy nie jest poprawnym adresem danych, a więc może być sygnałem zajścia nienormalnego zdarzenia - w tym przypadku braku miejsca w pamięci.

Wskaźniki i liczby całkowite nie są wymienne. Zero jest jedynym wyjątkiem: stalą zero można przypisać wskaźnikowi, można też porównać wskaźnik ze stałą zero. Często zamiast zera używa się stałej symbolicznej NULL, by podkreślić, że chodzi

141


Wyszukiwarka

Podobne podstrony:
ANSI C 9 5 WSKAŹNIK! I TABLICE ________— A oto program: #include <stdio.h> #include
ALG9 5.3. Stos 129 angielskiego skrótu UFO: Last-In-First-Out, co w wolnym tłumaczeniu oznacza „ost
ANSI C 4 WSKAŹNIKI I TABLICE Wskaźnik jest zmienną, która zawiera adres innej zmiennej. W języku C
ANSI C 8 5 WSKAŹNIKI I TABLICE Między nazwą tablicy a wskaźnikiem jest jednak istotna różnica, o k
ANSI C 0 5 WSKAŹNIKI I TABLICE o specjalną wartość wskaźnikową. Stała NULL jest zdefiniowana w
ANSI C 5 5 WSKAŹNIKI I TABLICE Jeżeli wskaźnik ip wskazuje na zmienną całkowitą x, to *ip może wys
ANSI C 6 5 WSKAŹNIKI I TABLICE _ Obrazowo wygląda to tak: 5 2 WSKAŹNIKI I ARGUMENTY FUNKCJI w miej
ANSI C 7 5 WSKAŹNIKI I TABLICE Ćwiczenie 5.1. Tak jak została napisana, funkcja getint traktuje zn
ANSI C 1 5 WSKAŹNIKI I TABLICE Stałe napisowe chyba najczęściej występują jako argumenty funkcji,
ANSI C 2 5 WSKAŹNIKI I TABLICE _______^ operator przyrostkowy ++ nie zmieni t, dopóki nie zostanie
ANSI C 3 5 WSKAŹNIKI I TABLICE możliwości są zawarte w funkcjach: getline (rozdz. 1 i 4), atoi, it
ANSI C 4 5 WSKAŹNIKI I TABLICE #define MAXLEN 1000 /* maks. długość wiersza wejściowego */ int get
ANSI C 5 5 WSKAŹNIKI I TABLICE /* swap: zamień miejscami v[i] i v[j] */ void swap(char *v[], int i
ANSI C 6 5 WSKAŹNIKI I TABLICE_______—- Oprócz tej różnicy w zapisie tablicę dwuwymiarową traktuj
ANSI C 7 5 WSKAŹNIKI I TABLICE oba zapisy a[3][4] i b[31[4] są poprawnymi odwołaniami do pojedyncz
ANSI C 8 5 WSKAŹNIKI I TABLICE ____________— for (i = 1; i < argc; i-H-) printf(,,%s%s”, argv[i
ANSI C 0 5 WSKAŹNIKI I TABLICE -------- ten program tak, aby najlepiej wykorzystywał dostępną mu p
ANSI C 1 5 WSKAŹNIKI I TABLICE------- if (left >= right) /* nic nie rób, jeśli tablica zawiera
ANSI C 2 5 WSKAŹNIKI I TABLICE _______—— Ćwiczenie 5.16. Dodaj opcję -d (kolejność słownikowa) spr

więcej podobnych podstron