Wstęp do Programowania, laboratorium 09 Zadanie 1. Zrobić
Transkrypt
Wstęp do Programowania, laboratorium 09 Zadanie 1. Zrobić
Wstęp do Programowania, laboratorium 09 Zadanie 1. Zrobić program liczący wartość funkcji sin(x) przy pomocy rozwinięcia w szereg. Zakres wartości x (od, do) oraz liczba przedziałów podawane będą jako argumenty programu, wyniki wpisywane będą do plików – dokładny do pliku „sin_dokladny.txt”, obliczony z szeregu „sin_szereg.txt”. Przykładowe wywołanie programu: ./a.out -2 4 60 ^ Policzy dla x od -2 do 5, 60 podprzedziałów Przykładowa zawartość plików: sin_dokladny.txt sin_szereg.txt x sin(x) -2 0.2 -1.9 0.31 -1.8 0.47 ... x szereg(x) -2 0.2 -1.9 0.3 -1.8 0.45 ... Zadanie 2. Zrobić dwie funkcje: • zamieniającą małe znaki na duże, • zamieniającą spacje na podkreślenia i cyfry na inne, losowe. Obie funkcje powinny jako argument przyjmować wskaźnik na char. Wczytać dowolny plik tekstowy (całość, do tablicy). Do jednego pliku wpisać jego zawartość po użyciu na nim pierwszej funkcji, do drugiego zawartość po użyciu drugiej funkcji. Zadanie 3. Zrobić funkcję która dla podanego argumentu x zwraca wartość funkcji sin i cos oraz x przeliczone z radianów na stopnie. Instrukcja http://pl.wikibooks.org/wiki/C/Wska%C5%BAniki Wskaźnik jest zmienną przechowującą adres z pamięci. int *a; Wskaźnik na zmienną typu int char *tekst; Wskaźnik na zmienną typu char int **b; Wskaźnik na zmienną typu int* (wskaźnik na wskaźnik) double ******c; Wskaźnik na wskaźnik na wskaźnik na wskaźnik... int* (*wskaznik)(char*, int); Wskaźnik na funkcję zwracającą wskaźnik na int, przyjmującą argumenty typu char* oraz int Nazwa tablicy jest wskaźnikiem na jej pierwszy element. Nazwa funkcji jest wskaźnikiem na nią. int *a; Deklaracja zmiennej a będącej wskaźnikiem na int a=&zmienna; Przypisanie adresu zmiennej zmienna do wskaźnika a *a; Odczytanie wartości na którą wskazuje a. a++; Przestawienie a na następną zmienną w pamięci a+=4; Przeskoczenie 4 elementy wprzód. #include <stdio.h> int main(int argc, char *argv[]) { int tablica[]={10, 11, 12}; int *wskaznik=tablica; // ^ to samo co v // int *wskaznik=&tablica[0]; int i; // Zwieksz i o jeden, przesun wskaznik na następny element for(i=0; i<3; i++, wskaznik++) printf("%d\n", *wskaznik); return 0; } Alokacja pamięci Wskaźniki można wykorzystać do tworzenia tablic o różnych wartościach w trakcie działania programu. #include <stdio.h> #include <stdlib.h> int main(int argc, char *argv[]) { double *wskaznik; int i; int liczba_elementow=50; wskaznik=(double *) malloc(liczba_elementow * sizeof(double)); for(i=0; i<liczba_elementow; ++i) wskaznik[i]=1.0/i; // *(wskaznik+i)=1.0/i; // To samo co ^ for(i=0; i<liczba_elementow; ++i) printf("%d: %f %f\n", i, wskaznik[i], *(wskaznik+i)); // Zajeta pamiec nalezy oddac przed koncem programu // Tylko zli programisci tego nie robia free(wskaznik); return 0; } Funkcja malloc jako argument przyjmuje wielkość pamięci jaką potrzebujemy. Jeśli chcemy zrobić tablicę na 50 elementów, każdy o wielkości 8 bajtów, potrzebujemy 50*8 bajtów. sizeof(double) zwraca wielkość zmiennej typu double. sizeof(int), sizeof(char) zwrócą odpowiednio wielkość zmiennej int i char. Podpowiedzi Ad. 2 Zrobić dwie funkcje: void zamianaLiterki(char *tekst); void zamianaCyferki(char *tekst); Na początku każdej sprawdzić jakiej długości przesłany został tekst, przy pomocy funkcji strlen lub wyliczając ręcznie: int dlugosc=0; while(tekst[dlugosc++]); // ^ Kto zgadnie jak to dziala i czemu dziala? printf("Dlugosc tekstu: %d\n", dlugosc); Uruchomić pętlę zamieniającą znaki: int i; for(i=0; i<dlugosc; ++i) { if(literka jest mala) zamien na duza } Aby cały plik wczytać za jednym razem, należy zrobić tablicę która go całego zmieści – potrzebna jest więc wiedza o wielkości pliku. Przy pomocy fseek można przeskoczyć na koniec pliku, a przy pomocy ftell można zobaczyć gdzie aktualnie jesteśmy. Będąc na końcu pliku, ftell zwróci jego wielkość w bajtach. Mając wielkość pliku, można zrobić tablicę i przy pomocy fread wczytać do niej cały plik. int wielkosc; char *dane; FILE plik=fopen(...); // Otworz plik fseek(...); wielkosc=ftell(...); fseek(...); // Przeskocz na koniec // Sprawdz wielkosc pliku // Wroc na poczatek dane=(char *)malloc(...); // Zajmij pamiec fread(...) // Wczytaj caly plik do tablicy Proponuję pamiętać o tym, że każdy tekst musi kończyć się znakiem '0'. Po wczytaniu pliku, zrobić drugą tablicę tej samej wielkości i przekopiować do niej zawartość pierwszej. Wywołać obie funkcji zmieniające znaki (do pierwszej przesłać wskaźnik na pierwszą tablicę, do drugiej – na drugą). Na koniec otworzyć dwa pliki i przy pomocy funkcji fwrite wpisać do nich zawartość każdej z tablic. Warto też przed końcem programu zwolnić zajętą pamięć. Ad. 3 Chcemy zrobić funkcję, która zwraca trzy wartości wyliczone na podstawie jednego argumentu. W C można zwrócić tylko jedną wartość, dlatego trzeba zrobić to inaczej: jako argumenty funkcji przesłać wskaźniki na trzy dodatkowe zmienne, do których zostaną wpisane obliczone wartości: void sincosrad(float x, float *vsin, float *vcos, float *xdeg); Przesłanie zmiennej 'normalnie' (float x) powoduje wysłanie do funkcji nowej zmiennej o tej samej wartości (tzw. przesłanie argumentu przez wartość). Przesyłając wskaźnik podajemy funkcji adres miejsca w pamięci do którego ma wpisać obliczone wartości.