1. Tablice dynamiczne Początkowa zadeklarowana wielkość tablicy czasami może okazać niewystarczająca, lub nadmierna. Dynamiczna alokacja pamięci wykorzystywana jest w celu otrzymania bądź zwolnienia pamięci podczas pracy programu. Istnieją cztery funkcje w bibliotece stdlib.h odpowiedzialne za dynamiczną alokację pamięci. Malloc() alokuje żądaną ilość bajtów i zwraca do wskaźnika adres pierwszego bajtu alokowanej przestrzeni. Nazwa malloc odnosi się do zwrotu memory allocation. Funkcja malloc() rezerwuje blok pamięci o podanym rozmiarze i zwraca wskaźnik typu pustego, który może być przypisany do wskaźnika dowolnego typu. wsk=(typ_danych*)malloc(rozmiar_w_bajtach); Powyżej wsk jest wskaźnikiem typu typ_danych. Funkcja malloc() zwraca wskaźnik do przestrzeni pamięci o rozmiarze rozmiar_w_bajtach. Jeśli nie wystarcza pamięci, alokacja jest nieudana i zwracany jest wskaźnik NULL. wsk=(int*)malloc(100*sizeof(int)); Powyższe wyrażenie alokuje 200 lub 400 w zależności od rozmiaru int w danym systemie. Wskaźnik wskazuje na adres pierwszego bajtu pamięci. Calloc() Alokuje przestrzeń dla elementów tablicowych, inicjuje do zera i zwraca wskaźnik do pamięci. Nazwa calloc odnosi się do zwrotu contigous allocation. Jedyną różnicą pomiędzy funkcjami malloc() i calloc() jest taka, że malloc() alokuje pojedynczy blok pamięci, a calloc() wiele bloków o tych samych rozmiarach i ustala wszystkie do zera. wsk=(cast-type*)calloc(n,element-size); Powyższe wyrażenie alokuje przyległą przestrzeń w pamięci dla tablicy n elementowej. wsk=(float*)calloc(25,sizeof(double)); Powyższy przykład tworzy w pamięci 25 bloków typu float o rozmiarze double. Free() dealokuje uprzednio alokowaną przestrzeń. Pamięć alokowana dynamicznie nie zwraca się samoczynnie. Programista musi użyć funkcji free() aby uwolnić pamięć. free(wsk); Powyższy przykład dealokuje wskaźnik pamięci. Reallock() Zmień rozmiar uprzednio alokowanej pamięci. Przydatny, gdy alokowana wcześniej pamięć jest nie wystarczająca lub nadmierna. wsk=realloc(wsk, nowy_rozmiar); W powyższym wyrażeniu wsk jest relokowane do rozmiaru nowy_rozmiar). Przykłady:
int main(void) int n,i,*ptr,sum=0; printf("wprowadz liczbe elementow: "); scanf("%d",&n); ptr=(int*)malloc(n*sizeof(int)); //alokacja pamieci if(ptr==null) printf("blad! Alokacja nie powiodla sie."); exit(0); printf("podaj wartosci kolejnych elementow tablicy: "); for(i=0;i<n;++i) scanf("%d",ptr+i); sum+=*(ptr+i); printf("sum=%d",sum); free(ptr); int main(void) int n,i,*ptr,sum=0; printf("wprowadz liczbe elementow: "); scanf("%d",&n); ptr=(int*)calloc(n,sizeof(int)); if(ptr==null) printf("blad! Alokacja nie powiodla sie."); exit(0); printf("podaj wartosci kolejnych elementow tablicy: "); for(i=0;i<n;++i) scanf("%d",ptr+i); sum+=*(ptr+i); printf("sum=%d",sum); free(ptr); int main(void) int *ptr,i,n1,n2; printf("enter size of array: "); scanf("%d",&n1); ptr=(int*)malloc(n1*sizeof(int)); printf("address of previously allocated memory: "); for(i=0;i<n1;++i) printf("%u\t",ptr+i); printf("\nenter new size of array: "); scanf("%d",&n2);
ptr=realloc(ptr, n2); for(i=0;i<n2;++i) printf("%u\t\n",ptr+i); 2. Ciągi znaków (String) Operacje na ciągach znaków są bardzo ważne. Niestety język C nie posiada dedykowanego typu string. W języku C stringiem nazywamy jednowymiarową tablicę typu char którą kończy znal null (\0). Dzięki temu, w teorii string może mieć nieskończoną długość. Jedynym ograniczeniem jest pamięć komputera. Przykładowa deklaracja: char slowo[7]= s, t, r, i, n, g, \0 ; char slowo[]= string ; Poniżej przedstawiono jak wygląda ciąg znaków(string) zdefiniowany w pamięci: Programista nie musi pamiętać o wstawianiu na końcu znaku null. Kompilator automatycznie dodaje \0 na końcu stworzonego stringa po przeanalizowaniu tablicy. W celu odczytania stringu należy skorzystać z kwantyfikatora formatowego %s. Dla lepszej obsługi ciągów znaków możliwe jest skorzystanie z biblioteki string.h wyposażonej w funkcje ułatwiające pracę na stringach. int main (void) char word[8] = 's', 't', 'r', 'i', 'n', 'g', 's', '\0'; printf("the program works with %s\n", word); W języku C możliwe jest korzystanie z następujących funkcji: strcpy(s1,s2) kopiuje string s2 do stringu s1 strcat(s1,s2) dołącza string s2 na koniec stringu s1
strlen(s1) zwraca długość stringu s1 strcmp(s1,s2) zwraca 0 jeśli s1 i s2 są takie same, mniej niż 0 jeśli s1<s2, więcej niż 0 jeśli s1>s2 strchr(s1, ch) zwraca wskaźnik to pierwszego wystąpienia znaki ch w stringu s1 strstr(s1,s2) zwraca wskaźnik do pierwszego wystąpienia stringu s2 w stringu s1 int main (void) char name[]="john", surname[]="price", temp[256], *temp2; int i; /*String display*/ printf("name: %s, Surname: %s \n", name, surname); /*string copying*/ strcpy(temp, name); printf("temp after use of strcpy(): %s\n", /*concentrating strings*/ strcat(temp, ""); strcat(temp, surname); printf("temp after use of strcat(): %s\n", /*changing all letters of the string into small letters*/ temp2=temp; while (*temp2) if (*temp2 >= 65 && *temp2 <=90) *temp2 += 32; temp2++; printf("temp after \"manual\" letter size change: %s\n", /*searching subseries in a string*/ temp2=strstr(temp, "ice"); if (temp2) printf("temp from seached subseries 'ice': %s\n", temp2); else printf("no subseries found\n"); /*obtaining the length of the strings*/ printf("length of temp: %ld\n", strlen(temp)); /*comparison of of strings*/ strcpy(temp, "Paul"); i=strcmp(name, if(i==0) printf("compared strings are thesame\n"); else if(i<0) printf("string %s appears before %s.\n", name, else if(i>0) printf("string %s appears after %s.\n", name, /* use of sprintf() instruction*/ sprintf(temp, "Name: %s, i: %d", name, i); printf("buffer : '%s'\n", Wczytywanie ciągów znaków od użytkownika: char string[20]; scanf( %s, string);
Tablica znakowa może pobierać pojedyncze słowa. Jeśli wprowadzona zostaje spacja (lub inny biały znak), scanf zostaje przerwany. int main(void) char name[20]; printf("enter name: "); scanf("%s",name); printf("your name is %s.",name);