to get the file
Transkrypt
to get the file
Politechnika Świętokrzyska Wydział Elektrotechniki, Automatyki i Informatyki Podstawy Programowania 2 Instrukcja laboratoryjna numer 1 do wykładu numer 1 Kielce, 28.02.2016 Zadanie 1: Odczytaj: 1.1 const int *a 1.2 int a; int *b=&a; 1.3 void (*a)(); 1.4 void *a(); 1.5 int (*a)(double); 1.6 void (*a)(char *) 1.7 double* (*a)(int, int) 1.8 int *a(); 1.9 int (*a)(); 1.10 int* (*a)(); 1.11 int a[5]; Zadanie 2: Zadeklaruj wskaźnik wskazujący na int. Zaalokuj ilość pamięci przy użyciu funkcji malloc wystarczającą do zapisania obiektu typu int stosując operator sizeof. Przypisz liczbę 5 do alokowanej pamięci. Wypisz na co wskazuje ten wskaźnik, a następnie zwolnij pamięć funkcją free(). Zadanie 3: Wyjaśnij problemy z poniższym przykładem: #include <stdio.h> int main(void) { int *pi; *pi = (int*)malloc(sizeof(int)); free(pi); return 0; } Zadanie 4: Zaalokuj pamięć dla łańcucha znaków (6 znaków), a następnie zapisz do tego łańcucha dowolne znaki. (Pamiętaj o zwolnieniu pamięci po wykonaniu programu). Zadanie 5: Wyjaśnij problemy z poniższym przykładem: #include <stdio.h> int main(void) { char *chunk; while(1) { chunk = (char *)malloc(sizeof(char)); printf("Alokowanie\n"); } return 0; } Zadanie 6: Wyjaśnij problemy z poniższym przykładem: #include <stdio.h> int main(void) { int *pi = (int*)malloc(sizeof(int)); *pi = 5; /* ... */ pi = (int*) malloc(sizeof(int)); free(pi); return 0; } Zadanie 7: Wyjaśnij problemy z poniższym przykładem: #include <stdio.h> int main(void) { char *greeting = (char *) malloc(strlen("Witaj")+1); strcpy(greeting,"Witaj"); while (*greeting !=0) { printf("%c",*greeting); greeting++; } return 0; } Zadanie 8: Przeanalizuj przykład: Gdy funkcja malloc nie jest w stanie wykonać alokacji pamięci, zwraca wartość NULL. Dobrą praktyką przy stosowaniu wskaźników jest sprawdzenie, czy funkcja malloc nie zwróciła przypadkiem wartości NULL. Ilustruje to poniższy przykład. #include <stdio.h> int main(void) { int *pi = (int*)malloc(sizeof(int)); if(pi != NULL) { /*wskaźnik powinien być poprawny */ }else{ /* niepoprawny wskaźnik */ } return 0; } Zadanie 9: Wyjaśnij problemy z poniższym przykładem: #include <stdio.h> int main(void) { char *name; printf("Podaj nazwisko:"); scanf("%s",name); printf("\n%s",name); return 0; } Zadanie 10: Wskaźnikowi pi zaalokuj pamięć na 5 elementów typu integer, jednocześnie wypełniając tę pamięć zerami. Zadanie 11: Przeanalizuj przykład: wiszący wskaźnik (1). Dwa wskaźniki p1 i p2 odnoszą się do tej samej przestrzeni pamięci, następnie wskaźnik p1 został uwolniony. #include <stdio.h> int main(void) { int *p1 = (int*) malloc(sizeof(int)); *p1 = 5; /* ... */ int *p2; p2 = p1; /* ... */ free(p1); /* ... */ *p2 = 10; /* wiszący wskaźnik */ return 0; } Zadanie 12: Przeanalizuj przykład: wiszący wskaźnik (2). Do zmiennej pi przypisano adres tmp. Blok zawierający zmienną tmp zostaje ściągnięty ze stosu programu, a jego adres staje się nieważny. #include <stdio.h> int main(void) { int *pi; /* ... */ { int tmp = 5; pi = &tmp; } /* pi jest teraz wiszącym wskaźnikiem */ return 0; } Zadanie 13: Napisz funkcję podnoszącą do kwadratu liczbę całkowitą (przekazaną jako parametr) i zwracającą wynik tego działania. Uruchom tą funkcję przez zastosowanie wskaźnika na funkcję. Zadanie 14: Przeanalizuj przykład: Przechowywanie przez wskaźnik adresu funkcji pozwala na dynamiczną kontrolę toku wykonania programu, co demonstruje zamieszczony przykład. #include <stdio.h> int add(int num1, int num2) { return num1+num2; } int substract(int num1, int num2) { return num1-num2; } int compute(int (*operation) (int,int),int num1,int num2) { return operation(num1,num2); } int main(void) { printf("%d\n",compute(add,5,6)); printf("%d\n",compute(substract,5,6)); return 0; } Zadanie 15: Stosowanie funkcji realloc() do zmiany rozmiaru buforu: napisz funkcję służącą do wczytywania znaków ze standardowego wejścia i przypisywania ich buforowi tak długo, aż użytkownik nie wciśnie ENTER. Przyjmij, że bufor mieści tylko 10 znaków. W przypadku braku miejsca w buforze, program powinien zwiększyć rozmiar buforu o kolejnych 10 znaków. Bufor ma zawierać wszystkie wczytane znaki razem ze znakiem zamykającym. Wskazówki (opcjonalne, nie trzeba z nich korzystać podczas realizacji zadania): bufor ma założony rozmiar początkowy oraz wielkość, o jaką będzie w razie potrzeby zwiększany (np: const size_t sizeIncrement = 10, gdzie size_t to nazwa typu danych całkowitych bez znaku, używany do określania rozmiaru, długości itp.). Potrzebny będzie wskaźnik na wczytywane znaki (np. char* buffer = malloc(sizeIncrement)), wskaźnik na następną wolną pozycję w buforze (np. char* currentPosition = buffer;), maksymalna liczba znaków, którą można bezpiecznie przechowywać w buforze (np. size_t maximumLength = sizeIncrement;), licznik wczytanych znaków (np. size_t length = 0;), zapamiętany ostatni wczytany znak (np. int character;). Znaki można wczytywać (np. character = fgetc(stdin);) w pętli while, która po wprowadzeniu znaku nowego wiersza powinna być zakończona (if (character == '\n') {break;}). Sprawdzić, czy nie dochodzi do przekroczenia bufora, jeżeli nie, to wczytany znak dodać do aktualnej pozycji wewnątrz buforu (np. *currentPosition++= character;). Jeżeli nastąpiło przekroczenie rozmiaru buforu, funkcją realloc utworzyć nowy blok pamięci (np. char *newBuffer = realloc(buffer, maximumLength += sizeIncrement);) oraz zmodyfikować wskaźnik na następną wolną pozycję w buforze tak, aby wskazywał na świeżo alokowany bufor (np. currentPosition = newBuffer + (currentPosition – buffer); buffer = newBuffer;). W celu zakończenia łańcucha dodać znak '\0' (np. *currentPosition = '\0';). Zadanie 16: Dodaj zabezpieczenia do poprzedniego programu, chroniące przed sytuacją, kiedy funkcja malloc nie jest w stanie dokonać alokacji pamięci (wówczas funkcja powinna zwrócić NULL). Zadanie 17: Zastosowanie funkcji realloc do zmniejszenia ilości pamięci zajmowanej przez wskaźnik: W poniższym przykładzie funkcja trim() usuwa znaki spacji znajdujące się na początku łańcucha buffer. Funkcja realloc ma za zadanie dokonać relokacji pamięci na podstawie nowej długości łańcucha. #include <stdio.h> char* trim(char* phrase) { char* oldString = phrase; char* newString = phrase; while(*oldString == ' ') { oldString++; } while(*oldString) { *(newString++) = *(oldString++); } *newString = 0; return (char*)realloc(phrase,strlen(phrase)+1); } int main(void) { char* buffer = (char*) malloc(strlen(" ciąg znaków ze spacjami na początku")+1); strcpy(buffer," ciąg znaków ze spacjami na początku"); printf("%s\n",buffer); printf("%s\n",trim(buffer)); return 0; } Zadanie 18: Zmodyfikuj program z przykładu poprzedniego tak, aby z ciągu znaków były usuwane wszystkie spacje. Zadania obowiązkowe, wpływające na ocenę z PP2: Rozwiązać zadnia z „Listy zadań na pierwsze zajęcia” umieszczonej na achilles.tu.kielce.pl.