typ *nazwa;np.
int z; int *wsk=&z; *wsk=1; // zmienna z będzie miała wartość 1
Jeśli
W języku C++ jak i w C istnieje ścisła zależność pomiędzy tablicami a
wskaźnikami. Można powiedzieć, że tablica jest wskaźnikiem stałym (nie
prawidłowa jest na przykład instrukcja
int T[3]={1,2,3};
int *wsk=T;
*wsk=3; // równoważnie T[0]=3
wsk++;
*wsk=2; // T[1]=2
wsk++;
*wsk=1; // T[2]=1
Wskaźników można używać jako tak zwanych iteratorów, co może zwiększać efektywność operacji tablicowych. Przykładowo funkcja kopiująca łańcuchy może wyglądać tak:
char *strcpy(char *dst, const char *src)
{
char *cp = dst;
while (*cp++ = *src++);
return dst;
}
Wskaźnikowi można także dynamicznie (tzn. w trakcie działania programu)
przydzielić pamięć. Wykorzystujemy w tym celu operator
int *wsk=new int; // alokacja nowej zmiennej typu int double *wd=new double[10]; // alokacja tablicyAby zwolnić wcześniej przydzieloną pamięć wykorzystujemy operator
delete wsk; delete []wd;
int T1[10][10]; int (*W1)[10]; int **W2; int *T2[10];
Po takich deklaracjach
W2=T2; // T2 jest tablicą wskaźników, a więc wskaźnikiem na wskaźnik W1=T1; // T1 jest tablicą tablic, a więc wskaźnikiem na tablicęAle nie możliwe są przypisania
Porównaj dwa programy:
int T[12][5];Od tablic tablic, czyli tablic wskaźników (ang. jagged arrays) np:
int *T2[10];Tablica T z pierwszego przykładu zajmuje w pamięci zwarty obszar. W drugim przypadku zwarty obszar w pamięci zajmuje jedynie tablica wskaźników do tablic jednowymiarowych (które po tej deklaracji jeszcze nie istnieją). Proszę zwrócić uwagę, że tablice wskazywane przez T2 nie muszą mieć tego samego rozmiaru.
Pewną trudność może sprawiać elastyczne przekazywanie tablic wielowymiarowych do funkcji, gdyż albo, stosując rzutowanie typów, rezygnujemy z określania typów przekazywanych parametrów, albo jesteśmy skazani na wpisanie na stałe wszystkich rozmiarów tablicy z wyjątkiem ostatniego. Ilustrację dla tego problemu może stanowić przykładowe rozwiązanie zadania 2Dfun: frame rotate.
Napisz własną funkcję int my_strcat(char cel[], const char *s), która dopisuje łańcuch znaków s na koniec łańcucha cel. Użyj wskaźników jak iteratorów.
Napisz funkcję char* strcpy(const char* source), która tworzy kopię łańcucha source, o rozmiarze dokładnie takim, jak potrzeba i zwraca wskaźnik do utworzonej kopii.
Napisz funkcję int* realloc(int* source, int n), która tworzy kopię n elementowej tablicy source, o rozmiarze 2 razy większym niż oryginał, zwraca wskaźnik do utworzonej kopii oraz zwalnia pamięć zajmowaną przez source.
Użyj poprzedniej funkcji do zapamiętywania dowolnie długich ciągów liczb wczytywanych ze standardowego wejścia.
Napisz funkcję int* glue(int **T1, int l1, int k), która sklei wszystkie elementy T1, zawierającej l1 tablic k1 liczbowych w jedną tablicę l1k1 liczbową.
Wróć