cw3b.pdf

(140 KB) Pobierz
wskazniki
WSKA NIKI I ADRESY
Wska nik – zmienna, która zawiera adres (wskazanie) pocz tku dowolnego obszaru w pami ci
komputera
Ogólna posta wska nika : typ_danych *identyfikator ;
Najcz ciej u ywane s wska niki „ zdefiniowane” zawieraj ce adres innej zmiennej. Taki
wska nik zawiera informacj o:
· adresie zmiennej
· typie danych przechowywanych przez t zmienn
np.: int *wska nik ; //wska nik na zmienn całkowit
Wska nik „niezdefiniowany” zawiera tylko informacj o adresie obszaru pami ci:
void *identyfikator ; //wska nik na dowolny ci g bajtów
Ze wska nikami i adresami zwi zane s dwa operatory:
· operator & zwracaj cy adres zmiennej podanej po prawej stronie operatora,
· operator * identyfikuj cy obszar wskazywany przez wska nik podany po prawej stronie
operatora.
Inicjowanie zmiennych wska nikowych
eby zainicjowa zmienn wska nikow i przypisa jej adres zmiennej automatycznej nale y u y
operatora & :
char znak=’a’; //zmiena automatyczna
char *wska nik_do_znaku; //zmienna wska nikowa
wskaznik_do_znaku=&znak; //przypisuje zmiennej wska nikowej wskaznik_do_znaku adres
zmiennej znak
W przypadu tablic:
int tablica_liczb[100];
int *wskaznik_do_tablicy_liczb;
poniewa zmienna (np. tablica_liczb ) jest wska nikiem wskazuj cym adres pierwszego elementu
tablicy!!! Tak wi c jej warto ci jest adres. Prawidłowe jest wi c przypisanie:
wskaznik_do_tablicy_liczb=tablica_liczb;
1
Operacje na zmiennych wska nikowych:
Je li chcemy zmieni warto elementu wskazywanego przez wska nik u ywamy
operatora * :
int *wska nik_do_liczby=&liczba;
*wska nik_do_liczby=20 ; //takie przypisanie spowoduje, e zmienna liczba b dzie miała
warto 20 (jest to równoznaczne z zapisem liczba=20 ;)
int liczba2=*wska nik_do_liczby; // spowoduje to przypisanie warto ci zmiennej liczba do
zmiennej liczba2 (jest to równoznaczne z zapisem liczba2=liczba ;)
je li napiszemy:
(*wskaznik_do_liczby)++; //to spowoduje to zwi kszenie zmiennej liczba o 1;
Operacje na adresach:
Je li natomiast zapiszemy
wska nik_do_liczby++; //spowoduje to przesuni cie adresu wska nika o jeden element.
wska nik_do_liczby + i ; //spowoduje to przesuni cie adresu wska nika o i elementów.
czyli np.:
*wskaznik_do_liczby++; //spowoduje przesuni cie adresu wska nika o jeden element i
pobranie warto ci zmiennej pod tym adresem
Wska niki do wska ników
Wska niki s zmiennymi, których warto ci jest adres s one równie reprezentowane w
pewnym obszarze pami ci, mo na wi c okre li ich adres i stworzy wska nik. Poprawny
jest nast puj cy zapis:
char c1=’a’;
char *pc=&c1; //wska nik do zmiennej typu char
char **ppc=&pc; //wska nik do wska nika typu char
zapisy *pc=’b’ oraz **ppc=’b’ s równowa ne.
Wska niki do wska ników stosuje si np. do przechowywania tablic wielowymiarowych lub
tablic napisów. Np.: char *argv[] //tablica wska ników do napisów, równowa ne char
**argv;
2
Wykorzystanie typów wska nikowych
Lista argumentów funkcji: gdy chcemy, by funkcja zwracała wi cej ni jedn warto , miała
mo liwo zmiany warto ci podanych argumentów.
Przykład:
void swap(int* pZmienna1, int* pZmienna2)
{
int temp=*pZmienna1;
*pZmienna1=*pZmienna2;
*pZmienna2=temp;
}
wywołanie tej funkcji ma posta :
void main()
{
int zmienna1;
int zmienna2;
swap(&zmienna1,&zmienna2); //jako argumenty wywołania nale y poda adresy zmiennej 1 i 2
}
Dynamiczny przydział pami ci
Zmienn wska nikow inicjowa mo na nie tylko przez przydzielenie jej adresu zmiennej automatycznej,
lecz równie przez dynamiczne przydzielenie pami ci .
Zmienn wska nikow inicjuje si za pomoc funkcji przydziału pami ci .
void *calloc(size_t n, size_t size);
void *malloc(size_t size);
calloc() przydziela pami dla tablicy zawieraj cej n elementów, ka dy o rozmiarze size bajtów i
zwraca wska nik do przydzielonej pami ci lub NULL je li alokacja si nie powiodła. Pami jest
zerowana.
malloc() przydziela size bajtów i zwraca wska nik do przydzielonej pami ci lub NULL je li
alokacja si nie powiodła. Pami nie jest czyszczona.
Np.:. int * pliczba=(int*)malloc(sizeof(int));
int * pliczba=(int*)calloc(1,sizeof(int));
Zalet dynamicznego przydziału pami ci, jest to e mo emy zarezerwowa obszar pami ci, który
aktualnie potrzebujemy.
int* ptab_liczb=(int*)malloc(n*sizeof(int)); //gdzie n mo e by ustalony dopiero w trakcie działania
ptab_liczba jest tablic liczb o wielko ci n , a wi c mo na si do nie odwoływa przy pomocy
operatora indeksowania ptab_liczb[i].
Zwalnianie pami ci przydzielonej automatycznie:
free(void *ptr);
free() zwalnia obszar pami ci wskazywany przez ptr , który został wcze niej przydzielony za
pomoc wywołania malloc() lub calloc().
3
Przykład:
Przydział pami ci dla tablicy jednowymiarowej (wektora) liczb całkowitych o rozmiarze n:
int* tab1=(int*)malloc(n*sizeof(int));
int *tab1
Przydział pami ci dla tablicy dwuwymiarowej (macierzy) liczb całkowitych o rozmiarze m x n:
int **tab2;
1) tab2=(int**)malloc(m*sizeof(int*));
2) for( i = 0 ;i<m ; i++)
tab2[i]= (int*)malloc(n*sizeof(int));
Zwolnienie przydzielonej pami ci dla tablicy jednowymiarowej:
free(tab1);
dwuwymiarowej:
for( i = 0 ;i<m ; i++)
free(tab2[i]);
free(tab2);
4
957831.001.png 957831.002.png
Dost p do tablic za pomoc indeksow i wska ników
Tablica jednowymiarowa
int tab1[N];
//lub int *tab1; //dynamiczny przydzial pamieci
for (i=0; i<N;i++) //dost p za pomoc indeksu
{
scanf("%d",&tab1[i]);
tab1[i]= 2*tab1[i];
printf("Tab[%d]=%d \n",i+1,tab1[i]);
}
for (i=0; i<N;i++) //dost p za pomoc wska ników
{
scanf("%d", tab1+i ); // tab1+i = = &*(tab1+i)
tab1[i]= 2* *(tab1+i);
printf("Tab[%d]=%d \n",i+1, *(tab1+i ));
}
Tablica dwuwymiarowa
int tab2[N][N];
//lub int **tab2; //dynamiczny przydzial pamieci
for (i=0; i<N;i++) //dost p za pomoc indeksu
{
for (j=0; j<N;j++)
{
scanf("%d",&tab2[i][j]);
tab2[i][j]= 2*tab2[i][j];
printf("Tab[%d][%d]=%d",i+1,j+1,tab2[i][j]);
}
printf("\n");
}
for (i=0; i<N;i++) //dost p za pomoc wska ników
{
for (j=0; j<N;j++)
{
scanf("%d", *(tab2+i)+j );
*(*(tab2+i)+j) =2* *(*(tab2+i)+j) ;
printf("Tab[%d][%d]=%d",i+1,j+1, *(*(tab2+i)+j) );
}
printf("\n");
}
5
 
Zgłoś jeśli naruszono regulamin